[Pkg-cli-apps-commits] [SCM] smuxi branch, master, updated. debian/0.8.10.2-1-8-gf658a59

Mirco Bauer meebey at meebey.net
Sat May 25 20:19:45 UTC 2013


The following commit has been merged in the master branch:
commit 22d13d55d28b9023300470aab9f929f9189d85a0
Author: Mirco Bauer <meebey at meebey.net>
Date:   Sat May 25 21:33:18 2013 +0200

    Imported Upstream version 0.8.11

diff --git a/Makefile.am b/Makefile.am
index f40ba98..be1d1f8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,8 @@
 # Engines
+if ENABLE_ENGINE_CAMPFIRE
+PO_ENGINE_CAMPFIRE = po-Engine-Campfire
+endif
+
 if ENABLE_ENGINE_IRC
 PO_ENGINE_IRC = po-Engine-IRC
 endif
@@ -32,6 +36,7 @@ EXTRA_DIST =	install-sh \
 
 PODIRS =	po \
 		po-Engine \
+		$(PO_ENGINE_CAMPFIRE) \
 		$(PO_ENGINE_IRC) \
 		$(PO_ENGINE_TWITTER) \
 		po-Server \
@@ -60,7 +65,7 @@ update-pot:
 	done
 
 update-transifex:
-	tx pull -l ca,da,de,en_GB,es,fi,fr,hr,nb_NO,pl,ru,sk,sv,tr,ur,zh_CN
+	tx pull -l ca,da,de,en_GB,es,fi,hr,nb_NO,pl,ru,sk,sv,tr,ur,zh_CN
 
 mail-po: update-po
 	for PODIR in $(PODIRS); do \
@@ -94,7 +99,9 @@ LIB_DIR = $(top_builddir)/lib
 BUILD_DIR = $(top_builddir)/bin/$(PROFILE)
 WIN32_LIB_DIR = $(LIB_DIR)/win32
 WIN32_BUILD_DIR = $(top_builddir)/bin-win32
+WIN32_ICON_THEME_DIR = $(top_srcdir)/images/Faenza-Smuxi
 OSX_LIB_DIR = $(LIB_DIR)/osx
+OSX_ICON_THEME_DIR = $(top_srcdir)/images/Faenza-Smuxi
 OSX_BUILD_DIR = $(top_builddir)/bin-osx
 OSX_APP_DIR = $(OSX_BUILD_DIR)/Smuxi.app
 OSX_CONTENTS_DIR = $(OSX_APP_DIR)/Contents
@@ -115,6 +122,7 @@ WIN32_FILES = \
 	$(WIN32_LIB_DIR)/fixedsys500c/Fixedsys500c.ttf \
 	$(BUILD_DIR)/smuxi-common.dll \
 	$(BUILD_DIR)/smuxi-engine.dll \
+	$(BUILD_DIR)/smuxi-engine-campfire.dll \
 	$(BUILD_DIR)/smuxi-engine-irc.dll \
 	$(BUILD_DIR)/smuxi-engine-twitter.dll \
 	$(BUILD_DIR)/smuxi-engine-xmpp.dll \
@@ -125,6 +133,9 @@ WIN32_FILES = \
 	$(BUILD_DIR)/Newtonsoft.Json.dll \
 	$(BUILD_DIR)/jabber-net.dll \
 	$(BUILD_DIR)/Db4objects.Db4o.dll \
+	$(BUILD_DIR)/ServiceStack.Text.dll \
+	$(BUILD_DIR)/ServiceStack.Interfaces.dll \
+	$(BUILD_DIR)/ServiceStack.Common.dll \
 	$(WIN32_LIB_DIR)/smuxi-frontend-gnome.exe.config \
 	$(WIN32_LIB_DIR)/smuxi-server.exe.config
 
@@ -132,10 +143,12 @@ OSX_FILES = \
 	$(LIB_DIR)/Nini.dll \
 	$(LIB_DIR)/log4net.dll \
 	$(BUILD_DIR)/smuxi-frontend-gnome.exe \
+	$(BUILD_DIR)/smuxi-frontend-gnome.exe.config \
 	$(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-campfire.dll \
 	$(BUILD_DIR)/smuxi-engine-irc.dll \
 	$(BUILD_DIR)/smuxi-engine-twitter.dll \
 	$(BUILD_DIR)/smuxi-engine-xmpp.dll \
@@ -144,7 +157,10 @@ OSX_FILES = \
 	$(BUILD_DIR)/Twitterizer2.dll \
 	$(BUILD_DIR)/Newtonsoft.Json.dll \
 	$(BUILD_DIR)/jabber-net.dll \
-	$(BUILD_DIR)/Db4objects.Db4o.dll
+	$(BUILD_DIR)/Db4objects.Db4o.dll \
+	$(BUILD_DIR)/ServiceStack.Text.dll \
+	$(BUILD_DIR)/ServiceStack.Interfaces.dll \
+	$(BUILD_DIR)/ServiceStack.Common.dll
 
 LINUX_STATIC_FILES = \
 	$(LIB_DIR)/Mono.Posix.dll \
@@ -159,7 +175,11 @@ LINUX_STATIC_FILES = \
 	$(BUILD_DIR)/Newtonsoft.Json.dll
 		
 dist-win32:
-	./autogen.sh --without-indicate --without-notify --without-dbus \
+	if [ -x /usr/bin/dmcs ]; then \
+		COMPILER_OVERRIDE="MCS=/usr/bin/dmcs"; \
+		echo COMPILER_OVERRIDE="$$COMPILER_OVERRIDE"; \
+	fi; \
+	./autogen.sh $$COMPILER_OVERRIDE --without-indicate --without-messaging-menu --without-notify --without-dbus \
 	  --with-db4o=included \
 	  --with-vendor-package-version="dist-win32"
 	$(MAKE)
@@ -170,20 +190,29 @@ dist-win32:
 	for PODIR in $(PODIRS); do \
 		$(MAKE) -C $$PODIR install itlocaledir=$(abs_top_builddir)/$(WIN32_BUILD_DIR)/locale; \
 	done
+	mkdir -p $(WIN32_BUILD_DIR)/icons
+	cp -r $(WIN32_ICON_THEME_DIR) $(WIN32_BUILD_DIR)/icons
 	makensis $(top_srcdir)/src/smuxi-win32.nsis
 
 dist-osx:
-	./autogen.sh --without-indicate --without-notify --without-dbus \
+	if [ -x /usr/bin/dmcs ]; then \
+		COMPILER_OVERRIDE="MCS=/usr/bin/dmcs"; \
+		echo COMPILER_OVERRIDE="$$COMPILER_OVERRIDE"; \
+	fi; \
+	./autogen.sh $$COMPILER_OVERRIDE --without-indicate --without-messaging-menu --without-notify --without-dbus \
 	  --with-db4o=included \
 	  --with-vendor-package-version="dist-osx"
 	$(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-server $(OSX_BINARIES_DIR)
 	cp $(OSX_LIB_DIR)/smuxi.icns $(OSX_RESOURCES_DIR)
 	for FILE in $(OSX_FILES); do \
 		cp $$FILE $(OSX_BINARIES_DIR); \
 	done
+	mkdir -p $(OSX_BINARIES_DIR)/icons
+	cp -r $(OSX_ICON_THEME_DIR) $(OSX_BINARIES_DIR)/icons
 	-rm smuxi-osx.zip
 	cd $(OSX_BUILD_DIR) && zip -r ../smuxi-osx.zip Smuxi.app
 
diff --git a/Makefile.in b/Makefile.in
index 36567ac..32ab82b 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -57,8 +57,11 @@ DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
 	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 \
@@ -87,8 +90,9 @@ AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
 	distdir dist dist-all distcheck
 ETAGS = etags
 CTAGS = ctags
-DIST_SUBDIRS = lib src po po-Engine po-Engine-IRC po-Engine-Twitter \
-	po-Server po-Frontend po-Frontend-GNOME po-Frontend-GNOME-IRC
+DIST_SUBDIRS = lib src po po-Engine po-Engine-Campfire po-Engine-IRC \
+	po-Engine-Twitter po-Server po-Frontend po-Frontend-GNOME \
+	po-Frontend-GNOME-IRC
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 distdir = $(PACKAGE)-$(VERSION)
 top_distdir = $(distdir)
@@ -171,9 +175,8 @@ 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_CAMPFIRE = @GETTEXT_PACKAGE_ENGINE_CAMPFIRE@
 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@
@@ -185,6 +188,9 @@ 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@
+GIO_SHARP_CFLAGS = @GIO_SHARP_CFLAGS@
+GIO_SHARP_FILES = @GIO_SHARP_FILES@
+GIO_SHARP_LIBS = @GIO_SHARP_LIBS@
 GLADE_SHARP_20_CFLAGS = @GLADE_SHARP_20_CFLAGS@
 GLADE_SHARP_20_LIBS = @GLADE_SHARP_20_LIBS@
 GLIB_SHARP_20_CFLAGS = @GLIB_SHARP_20_CFLAGS@
@@ -231,6 +237,11 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
+MESSAGINGMENU_SHARP_CFLAGS = @MESSAGINGMENU_SHARP_CFLAGS@
+MESSAGINGMENU_SHARP_FILES = @MESSAGINGMENU_SHARP_FILES@
+MESSAGINGMENU_SHARP_LIBS = @MESSAGINGMENU_SHARP_LIBS@
+MESSAGING_MENU_CFLAGS = @MESSAGING_MENU_CFLAGS@
+MESSAGING_MENU_LIBS = @MESSAGING_MENU_LIBS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
 MONO_MODULE_CFLAGS = @MONO_MODULE_CFLAGS@
@@ -238,8 +249,6 @@ 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@
@@ -252,8 +261,6 @@ 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@
@@ -347,6 +354,7 @@ top_srcdir = @top_srcdir@
 twitter_api_key = @twitter_api_key@
 
 # Engines
+ at ENABLE_ENGINE_CAMPFIRE_TRUE@PO_ENGINE_CAMPFIRE = po-Engine-Campfire
 @ENABLE_ENGINE_IRC_TRUE at PO_ENGINE_IRC = po-Engine-IRC
 @ENABLE_ENGINE_TWITTER_TRUE at PO_ENGINE_TWITTER = po-Engine-Twitter
 
@@ -368,6 +376,7 @@ EXTRA_DIST = install-sh \
 
 PODIRS = po \
 		po-Engine \
+		$(PO_ENGINE_CAMPFIRE) \
 		$(PO_ENGINE_IRC) \
 		$(PO_ENGINE_TWITTER) \
 		po-Server \
@@ -383,7 +392,9 @@ LIB_DIR = $(top_builddir)/lib
 BUILD_DIR = $(top_builddir)/bin/$(PROFILE)
 WIN32_LIB_DIR = $(LIB_DIR)/win32
 WIN32_BUILD_DIR = $(top_builddir)/bin-win32
+WIN32_ICON_THEME_DIR = $(top_srcdir)/images/Faenza-Smuxi
 OSX_LIB_DIR = $(LIB_DIR)/osx
+OSX_ICON_THEME_DIR = $(top_srcdir)/images/Faenza-Smuxi
 OSX_BUILD_DIR = $(top_builddir)/bin-osx
 OSX_APP_DIR = $(OSX_BUILD_DIR)/Smuxi.app
 OSX_CONTENTS_DIR = $(OSX_APP_DIR)/Contents
@@ -403,6 +414,7 @@ WIN32_FILES = \
 	$(WIN32_LIB_DIR)/fixedsys500c/Fixedsys500c.ttf \
 	$(BUILD_DIR)/smuxi-common.dll \
 	$(BUILD_DIR)/smuxi-engine.dll \
+	$(BUILD_DIR)/smuxi-engine-campfire.dll \
 	$(BUILD_DIR)/smuxi-engine-irc.dll \
 	$(BUILD_DIR)/smuxi-engine-twitter.dll \
 	$(BUILD_DIR)/smuxi-engine-xmpp.dll \
@@ -413,6 +425,9 @@ WIN32_FILES = \
 	$(BUILD_DIR)/Newtonsoft.Json.dll \
 	$(BUILD_DIR)/jabber-net.dll \
 	$(BUILD_DIR)/Db4objects.Db4o.dll \
+	$(BUILD_DIR)/ServiceStack.Text.dll \
+	$(BUILD_DIR)/ServiceStack.Interfaces.dll \
+	$(BUILD_DIR)/ServiceStack.Common.dll \
 	$(WIN32_LIB_DIR)/smuxi-frontend-gnome.exe.config \
 	$(WIN32_LIB_DIR)/smuxi-server.exe.config
 
@@ -420,10 +435,12 @@ OSX_FILES = \
 	$(LIB_DIR)/Nini.dll \
 	$(LIB_DIR)/log4net.dll \
 	$(BUILD_DIR)/smuxi-frontend-gnome.exe \
+	$(BUILD_DIR)/smuxi-frontend-gnome.exe.config \
 	$(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-campfire.dll \
 	$(BUILD_DIR)/smuxi-engine-irc.dll \
 	$(BUILD_DIR)/smuxi-engine-twitter.dll \
 	$(BUILD_DIR)/smuxi-engine-xmpp.dll \
@@ -432,7 +449,10 @@ OSX_FILES = \
 	$(BUILD_DIR)/Twitterizer2.dll \
 	$(BUILD_DIR)/Newtonsoft.Json.dll \
 	$(BUILD_DIR)/jabber-net.dll \
-	$(BUILD_DIR)/Db4objects.Db4o.dll
+	$(BUILD_DIR)/Db4objects.Db4o.dll \
+	$(BUILD_DIR)/ServiceStack.Text.dll \
+	$(BUILD_DIR)/ServiceStack.Interfaces.dll \
+	$(BUILD_DIR)/ServiceStack.Common.dll
 
 LINUX_STATIC_FILES = \
 	$(LIB_DIR)/Mono.Posix.dll \
@@ -959,7 +979,7 @@ update-pot:
 	done
 
 update-transifex:
-	tx pull -l ca,da,de,en_GB,es,fi,fr,hr,nb_NO,pl,ru,sk,sv,tr,ur,zh_CN
+	tx pull -l ca,da,de,en_GB,es,fi,hr,nb_NO,pl,ru,sk,sv,tr,ur,zh_CN
 
 mail-po: update-po
 	for PODIR in $(PODIRS); do \
@@ -990,7 +1010,11 @@ call-po: update-po
 	done
 
 dist-win32:
-	./autogen.sh --without-indicate --without-notify --without-dbus \
+	if [ -x /usr/bin/dmcs ]; then \
+		COMPILER_OVERRIDE="MCS=/usr/bin/dmcs"; \
+		echo COMPILER_OVERRIDE="$$COMPILER_OVERRIDE"; \
+	fi; \
+	./autogen.sh $$COMPILER_OVERRIDE --without-indicate --without-messaging-menu --without-notify --without-dbus \
 	  --with-db4o=included \
 	  --with-vendor-package-version="dist-win32"
 	$(MAKE)
@@ -1001,20 +1025,29 @@ dist-win32:
 	for PODIR in $(PODIRS); do \
 		$(MAKE) -C $$PODIR install itlocaledir=$(abs_top_builddir)/$(WIN32_BUILD_DIR)/locale; \
 	done
+	mkdir -p $(WIN32_BUILD_DIR)/icons
+	cp -r $(WIN32_ICON_THEME_DIR) $(WIN32_BUILD_DIR)/icons
 	makensis $(top_srcdir)/src/smuxi-win32.nsis
 
 dist-osx:
-	./autogen.sh --without-indicate --without-notify --without-dbus \
+	if [ -x /usr/bin/dmcs ]; then \
+		COMPILER_OVERRIDE="MCS=/usr/bin/dmcs"; \
+		echo COMPILER_OVERRIDE="$$COMPILER_OVERRIDE"; \
+	fi; \
+	./autogen.sh $$COMPILER_OVERRIDE --without-indicate --without-messaging-menu --without-notify --without-dbus \
 	  --with-db4o=included \
 	  --with-vendor-package-version="dist-osx"
 	$(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-server $(OSX_BINARIES_DIR)
 	cp $(OSX_LIB_DIR)/smuxi.icns $(OSX_RESOURCES_DIR)
 	for FILE in $(OSX_FILES); do \
 		cp $$FILE $(OSX_BINARIES_DIR); \
 	done
+	mkdir -p $(OSX_BINARIES_DIR)/icons
+	cp -r $(OSX_ICON_THEME_DIR) $(OSX_BINARIES_DIR)/icons
 	-rm smuxi-osx.zip
 	cd $(OSX_BUILD_DIR) && zip -r ../smuxi-osx.zip Smuxi.app
 
diff --git a/aclocal.m4 b/aclocal.m4
index 543fdbc..edf5b0a 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1782,8602 +1782,6 @@ sixtyfour bits
   test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem"
 ])
 
-# 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
-
-
-
-# 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], [[!?.]$], [], [.])
-)])
-
-
-
-
-
-# _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*)
-	    case `/usr/bin/file conftest.o` in
-	      *x86-64*)
-		LD="${LD-ld} -m elf32_x86_64"
-		;;
-	      *)
-		LD="${LD-ld} -m elf_i386"
-		;;
-	    esac
-	    ;;
-	  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" && \
-	test undefined != "$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
-  ;;
-
-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 | 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
-  ;;
-
-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 | 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 | 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 | 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
-
-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
-        ;;
-
-      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 | 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
-
-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
-
-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
-
-# 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
-
-
-
-# _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], [])
-
-
-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])])
-
-# 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
-])
-
-# 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)
-])
-
-# 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])])
-
 # nls.m4 serial 5 (gettext-0.18)
 dnl Copyright (C) 1995-2003, 2005-2006, 2008-2010 Free Software Foundation,
 dnl Inc.
@@ -12124,5 +3528,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/configure b/configure
index dc2621d..d2117b7 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for smuxi 0.8.10.2.
+# Generated by GNU Autoconf 2.69 for smuxi 0.8.11.
 #
 # Report bugs to <http://www.smuxi.org/issues/new>.
 #
@@ -590,8 +590,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='smuxi'
 PACKAGE_TARNAME='smuxi'
-PACKAGE_VERSION='0.8.10.2'
-PACKAGE_STRING='smuxi 0.8.10.2'
+PACKAGE_VERSION='0.8.11'
+PACKAGE_STRING='smuxi 0.8.11'
 PACKAGE_BUGREPORT='http://www.smuxi.org/issues/new'
 PACKAGE_URL=''
 
@@ -668,20 +668,13 @@ SERVER_COMPILER_FLAGS
 twitter_api_key
 ENABLE_ENGINE_TWITTER_FALSE
 ENABLE_ENGINE_TWITTER_TRUE
-ENABLE_ENGINE_MSNP_FALSE
-ENABLE_ENGINE_MSNP_TRUE
-MSNPSHARP_LIBS
-MSNPSHARP_CFLAGS
 ENABLE_ENGINE_XMPP_FALSE
 ENABLE_ENGINE_XMPP_TRUE
-ENABLE_ENGINE_OSCAR_FALSE
-ENABLE_ENGINE_OSCAR_TRUE
-OSCARLIB_LIBS
-OSCARLIB_CFLAGS
+ENABLE_ENGINE_CAMPFIRE_FALSE
+ENABLE_ENGINE_CAMPFIRE_TRUE
 ENABLE_ENGINE_IRC_FALSE
 ENABLE_ENGINE_IRC_TRUE
 SMARTIRC4NET_FILES
-subdirs
 GTKSPELL_LIBS
 GTKSPELL_CFLAGS
 NDESK_DBUS_GLIB_LIBS
@@ -697,6 +690,17 @@ NOTIFY_SHARP_LIBS
 NOTIFY_SHARP_CFLAGS
 INDICATE_SHARP_LIBS
 INDICATE_SHARP_CFLAGS
+WITH_MESSAGINGMENU_SHARP_INCLUDED_FALSE
+WITH_MESSAGINGMENU_SHARP_INCLUDED_TRUE
+MESSAGINGMENU_SHARP_FILES
+subdirs
+GIO_SHARP_FILES
+GIO_SHARP_LIBS
+GIO_SHARP_CFLAGS
+MESSAGING_MENU_LIBS
+MESSAGING_MENU_CFLAGS
+MESSAGINGMENU_SHARP_LIBS
+MESSAGINGMENU_SHARP_CFLAGS
 DB4O_FILES
 XBUILD
 BUNDLE_DB4O_FALSE
@@ -748,9 +752,8 @@ GETTEXT_PACKAGE_FRONTEND_GNOME_IRC
 GETTEXT_PACKAGE_FRONTEND_GNOME
 GETTEXT_PACKAGE_FRONTEND
 GETTEXT_PACKAGE_SERVER
+GETTEXT_PACKAGE_ENGINE_CAMPFIRE
 GETTEXT_PACKAGE_ENGINE_TWITTER
-GETTEXT_PACKAGE_ENGINE_MNSP
-GETTEXT_PACKAGE_ENGINE_OSCAR
 GETTEXT_PACKAGE_ENGINE_XMPP
 GETTEXT_PACKAGE_ENGINE_IRC
 GETTEXT_PACKAGE_ENGINE
@@ -925,14 +928,14 @@ with_vendor_package_version
 enable_release
 enable_debug
 with_db4o
+with_messaging_menu
 with_indicate
 with_notify
 with_dbus
 with_gtkspell
 enable_engine_irc
-enable_engine_oscar
+enable_engine_campfire
 enable_engine_xmpp
-enable_engine_msnp
 enable_engine_twitter
 with_twitter_api_key
 enable_frontend_gnome
@@ -962,6 +965,12 @@ NINI_CFLAGS
 NINI_LIBS
 DB4O_CFLAGS
 DB4O_LIBS
+MESSAGINGMENU_SHARP_CFLAGS
+MESSAGINGMENU_SHARP_LIBS
+MESSAGING_MENU_CFLAGS
+MESSAGING_MENU_LIBS
+GIO_SHARP_CFLAGS
+GIO_SHARP_LIBS
 INDICATE_SHARP_CFLAGS
 INDICATE_SHARP_LIBS
 NOTIFY_SHARP_CFLAGS
@@ -976,10 +985,6 @@ NDESK_DBUS_GLIB_CFLAGS
 NDESK_DBUS_GLIB_LIBS
 GTKSPELL_CFLAGS
 GTKSPELL_LIBS
-OSCARLIB_CFLAGS
-OSCARLIB_LIBS
-MSNPSHARP_CFLAGS
-MSNPSHARP_LIBS
 GLIB_SHARP_20_CFLAGS
 GLIB_SHARP_20_LIBS
 GTK_SHARP_20_CFLAGS
@@ -988,7 +993,8 @@ GLADE_SHARP_20_CFLAGS
 GLADE_SHARP_20_LIBS
 STFL_CFLAGS
 STFL_LIBS'
-ac_subdirs_all='lib/SmartIrc4net'
+ac_subdirs_all='lib/messagingmenu-sharp
+lib/SmartIrc4net'
 
 # Initialize some variables set by options.
 ac_init_help=
@@ -1528,7 +1534,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.10.2 to adapt to many kinds of systems.
+\`configure' configures smuxi 0.8.11 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1598,7 +1604,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of smuxi 0.8.10.2:";;
+     short | recursive ) echo "Configuration of smuxi 0.8.11:";;
    esac
   cat <<\_ACEOF
 
@@ -1620,9 +1626,9 @@ Optional Features:
   --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-campfire
+                          Enable Campfire protocol support (default yes)
   --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)
   --enable-frontend-stfl  Enable STFL frontend (default no)
@@ -1651,7 +1657,11 @@ Optional Packages:
                           "Debian 0.8-1"
   --with-db4o=auto|system|included
                           Use system or included db4o [default=auto]
-  --with-indicate         Support Messaging Menu [default=auto]
+  --with-messaging-menu=auto|system|included|no
+                          Support Messaging Menu (Ubuntu >= 12.10)
+                          [default=auto]
+  --with-indicate         Support Messaging Menu (Ubuntu <= 12.04)
+                          [default=auto]
   --with-notify           Support Desktop Notifications [default=auto]
   --with-dbus             Support D-Bus [default=auto]
   --with-gtkspell         Support GTK+ spell checking [default=auto]
@@ -1683,6 +1693,18 @@ Some influential environment variables:
   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
+  MESSAGINGMENU_SHARP_CFLAGS
+              C compiler flags for MESSAGINGMENU_SHARP, overriding pkg-config
+  MESSAGINGMENU_SHARP_LIBS
+              linker flags for MESSAGINGMENU_SHARP, overriding pkg-config
+  MESSAGING_MENU_CFLAGS
+              C compiler flags for MESSAGING_MENU, overriding pkg-config
+  MESSAGING_MENU_LIBS
+              linker flags for MESSAGING_MENU, overriding pkg-config
+  GIO_SHARP_CFLAGS
+              C compiler flags for GIO_SHARP, overriding pkg-config
+  GIO_SHARP_LIBS
+              linker flags for GIO_SHARP, overriding pkg-config
   INDICATE_SHARP_CFLAGS
               C compiler flags for INDICATE_SHARP, overriding pkg-config
   INDICATE_SHARP_LIBS
@@ -1711,14 +1733,6 @@ Some influential environment variables:
               C compiler flags for GTKSPELL, overriding pkg-config
   GTKSPELL_LIBS
               linker flags for GTKSPELL, overriding pkg-config
-  OSCARLIB_CFLAGS
-              C compiler flags for OSCARLIB, overriding pkg-config
-  OSCARLIB_LIBS
-              linker flags for OSCARLIB, overriding pkg-config
-  MSNPSHARP_CFLAGS
-              C compiler flags for MSNPSHARP, overriding pkg-config
-  MSNPSHARP_LIBS
-              linker flags for MSNPSHARP, overriding pkg-config
   GLIB_SHARP_20_CFLAGS
               C compiler flags for GLIB_SHARP_20, overriding pkg-config
   GLIB_SHARP_20_LIBS
@@ -1800,7 +1814,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-smuxi configure 0.8.10.2
+smuxi configure 0.8.11
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2078,7 +2092,7 @@ 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.10.2, which was
+It was created by smuxi $as_me 0.8.11, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2896,7 +2910,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='smuxi'
- VERSION='0.8.10.2'
+ VERSION='0.8.11'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -8112,6 +8126,10 @@ _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=
@@ -12242,10 +12260,9 @@ fi
 POSUB="
 	po
 	po-Engine
+	po-Engine-Campfire
 	po-Engine-IRC
 	po-Engine-XMPP
-	po-Engine-OSCAR
-	po-Engine-MSNP
 	po-Server
 	po-Frontend
 	po-Frontend-GNOME
@@ -12281,27 +12298,19 @@ cat >>confdefs.h <<_ACEOF
 _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
+GETTEXT_PACKAGE_ENGINE_TWITTER=smuxi-engine-twitter
 
 
 cat >>confdefs.h <<_ACEOF
-#define GETTEXT_PACKAGE_ENGINE_MSNP "$GETTEXT_PACKAGE_ENGINE_MSNP"
+#define GETTEXT_PACKAGE_ENGINE_TWITTER "$GETTEXT_PACKAGE_ENGINE_TWITTER"
 _ACEOF
 
 
-GETTEXT_PACKAGE_ENGINE_TWITTER=smuxi-engine-twitter
+GETTEXT_PACKAGE_ENGINE_CAMPFIRE=smuxi-engine-campfire
 
 
 cat >>confdefs.h <<_ACEOF
-#define GETTEXT_PACKAGE_ENGINE_TWITTER "$GETTEXT_PACKAGE_ENGINE_TWITTER"
+#define GETTEXT_PACKAGE_ENGINE_CAMPFIRE "$GETTEXT_PACKAGE_ENGINE_CAMPFIRE"
 _ACEOF
 
 
@@ -15357,6 +15366,349 @@ fi
 
 # Optional Libraries
 
+# Check whether --with-messaging-menu was given.
+if test "${with_messaging_menu+set}" = set; then :
+  withval=$with_messaging_menu;
+else
+  with_messagingmenu=auto
+
+fi
+
+WITH_MESSAGINGMENU=$with_messagingmenu
+if test "x$WITH_MESSAGINGMENU" = "xauto"; then
+	if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"messagingmenu-sharp-0.1\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "messagingmenu-sharp-0.1") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  FOUND_MESSAGINGMENU_SHARP=yes
+else
+  FOUND_MESSAGINGMENU_SHARP=no
+fi
+	if test "x$FOUND_MESSAGINGMENU_SHARP" = "xyes"; then
+		WITH_MESSAGINGMENU=system
+	else
+		if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"messaging-menu\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "messaging-menu") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  FOUND_MESSAGING_MENU=yes
+else
+  FOUND_MESSAGING_MENU=no
+fi
+		if test "x$FOUND_MESSAGING_MENU" = "xyes"; then
+			WITH_MESSAGINGMENU=included
+		else
+			WITH_MESSAGINGMENU=no
+		fi
+	fi
+fi
+if test "x$WITH_MESSAGINGMENU" = "xsystem"; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for MESSAGINGMENU_SHARP" >&5
+$as_echo_n "checking for MESSAGINGMENU_SHARP... " >&6; }
+
+if test -n "$MESSAGINGMENU_SHARP_CFLAGS"; then
+    pkg_cv_MESSAGINGMENU_SHARP_CFLAGS="$MESSAGINGMENU_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 \"messagingmenu-sharp-0.1\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "messagingmenu-sharp-0.1") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_MESSAGINGMENU_SHARP_CFLAGS=`$PKG_CONFIG --cflags "messagingmenu-sharp-0.1" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$MESSAGINGMENU_SHARP_LIBS"; then
+    pkg_cv_MESSAGINGMENU_SHARP_LIBS="$MESSAGINGMENU_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 \"messagingmenu-sharp-0.1\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "messagingmenu-sharp-0.1") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_MESSAGINGMENU_SHARP_LIBS=`$PKG_CONFIG --libs "messagingmenu-sharp-0.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
+	        MESSAGINGMENU_SHARP_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "messagingmenu-sharp-0.1" 2>&1`
+        else
+	        MESSAGINGMENU_SHARP_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "messagingmenu-sharp-0.1" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$MESSAGINGMENU_SHARP_PKG_ERRORS" >&5
+
+	as_fn_error $? "Package requirements (messagingmenu-sharp-0.1) were not met:
+
+$MESSAGINGMENU_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 MESSAGINGMENU_SHARP_CFLAGS
+and MESSAGINGMENU_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 MESSAGINGMENU_SHARP_CFLAGS
+and MESSAGINGMENU_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
+	MESSAGINGMENU_SHARP_CFLAGS=$pkg_cv_MESSAGINGMENU_SHARP_CFLAGS
+	MESSAGINGMENU_SHARP_LIBS=$pkg_cv_MESSAGINGMENU_SHARP_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+fi
+if test "x$WITH_MESSAGINGMENU" = "xincluded"; then
+	if test ! -f "$srcdir/lib/messagingmenu-sharp/configure.ac"; then
+		as_fn_error $? "lib/messagingmenu-sharp is empty!" "$LINENO" 5
+	fi
+
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for MESSAGING_MENU" >&5
+$as_echo_n "checking for MESSAGING_MENU... " >&6; }
+
+if test -n "$MESSAGING_MENU_CFLAGS"; then
+    pkg_cv_MESSAGING_MENU_CFLAGS="$MESSAGING_MENU_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"messaging-menu\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "messaging-menu") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_MESSAGING_MENU_CFLAGS=`$PKG_CONFIG --cflags "messaging-menu" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$MESSAGING_MENU_LIBS"; then
+    pkg_cv_MESSAGING_MENU_LIBS="$MESSAGING_MENU_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"messaging-menu\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "messaging-menu") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_MESSAGING_MENU_LIBS=`$PKG_CONFIG --libs "messaging-menu" 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
+	        MESSAGING_MENU_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "messaging-menu" 2>&1`
+        else
+	        MESSAGING_MENU_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "messaging-menu" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$MESSAGING_MENU_PKG_ERRORS" >&5
+
+	as_fn_error $? "Package requirements (messaging-menu) were not met:
+
+$MESSAGING_MENU_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 MESSAGING_MENU_CFLAGS
+and MESSAGING_MENU_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 MESSAGING_MENU_CFLAGS
+and MESSAGING_MENU_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
+	MESSAGING_MENU_CFLAGS=$pkg_cv_MESSAGING_MENU_CFLAGS
+	MESSAGING_MENU_LIBS=$pkg_cv_MESSAGING_MENU_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GIO_SHARP" >&5
+$as_echo_n "checking for GIO_SHARP... " >&6; }
+
+if test -n "$GIO_SHARP_CFLAGS"; then
+    pkg_cv_GIO_SHARP_CFLAGS="$GIO_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 \"gio-sharp-2.0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "gio-sharp-2.0") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_GIO_SHARP_CFLAGS=`$PKG_CONFIG --cflags "gio-sharp-2.0" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$GIO_SHARP_LIBS"; then
+    pkg_cv_GIO_SHARP_LIBS="$GIO_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 \"gio-sharp-2.0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "gio-sharp-2.0") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_GIO_SHARP_LIBS=`$PKG_CONFIG --libs "gio-sharp-2.0" 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
+	        GIO_SHARP_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gio-sharp-2.0" 2>&1`
+        else
+	        GIO_SHARP_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gio-sharp-2.0" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$GIO_SHARP_PKG_ERRORS" >&5
+
+	as_fn_error $? "Package requirements (gio-sharp-2.0) were not met:
+
+$GIO_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 GIO_SHARP_CFLAGS
+and GIO_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 GIO_SHARP_CFLAGS
+and GIO_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
+	GIO_SHARP_CFLAGS=$pkg_cv_GIO_SHARP_CFLAGS
+	GIO_SHARP_LIBS=$pkg_cv_GIO_SHARP_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+	GIO_SHARP_LIBS=`$PKG_CONFIG --variable=Libraries gio-sharp-2.0`
+
+	GIO_SHARP_FILES="gio-sharp.dll"
+
+
+	ac_configure_args="$ac_configure_args CSC=$MCS"
+
+
+subdirs="$subdirs lib/messagingmenu-sharp"
+
+	MESSAGINGMENU_SHARP_FILES="messagingmenu-sharp.dll"
+
+fi
+ if test "x$WITH_MESSAGINGMENU" = "xincluded"; then
+  WITH_MESSAGINGMENU_SHARP_INCLUDED_TRUE=
+  WITH_MESSAGINGMENU_SHARP_INCLUDED_FALSE='#'
+else
+  WITH_MESSAGINGMENU_SHARP_INCLUDED_TRUE='#'
+  WITH_MESSAGINGMENU_SHARP_INCLUDED_FALSE=
+fi
+
+
+
 # Check whether --with-indicate was given.
 if test "${with_indicate+set}" = set; then :
   withval=$with_indicate;
@@ -15376,6 +15728,9 @@ if test -n "$PKG_CONFIG" && \
 else
   INDICATE_SHARP_SUPPORT=no
 fi
+if test "x$WITH_INDICATE" = "xauto" -a "x$WITH_MESSAGINGMENU" != "xno"; then
+	WITH_INDICATE=no
+fi
 if test "x$WITH_INDICATE" = "xauto"; then
 	WITH_INDICATE=$INDICATE_SHARP_SUPPORT
 fi
@@ -16135,9 +16490,7 @@ if test "x$ENABLE_ENGINE_IRC" != "xno"; then
 		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"
-
-
-subdirs="$subdirs lib/SmartIrc4net"
+	subdirs="$subdirs lib/SmartIrc4net"
 
 	SMARTIRC4NET_FILES="lib/SmartIrc4net/bin/Meebey.SmartIrc4net.dll"
 
@@ -16151,99 +16504,20 @@ else
 fi
 
 
-# Check whether --enable-engine-oscar was given.
-if test "${enable_engine_oscar+set}" = set; then :
-  enableval=$enable_engine_oscar; ENABLE_ENGINE_OSCAR=$enableval
+# Check whether --enable-engine-campfire was given.
+if test "${enable_engine_campfire+set}" = set; then :
+  enableval=$enable_engine_campfire; ENABLE_ENGINE_CAMPFIRE=$enableval
 else
-  ENABLE_ENGINE_OSCAR=no
+  ENABLE_ENGINE_CAMPFIRE=yes
 
 fi
 
-if test "x$ENABLE_ENGINE_OSCAR" != "xno"; then
-
-pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for OSCARLIB" >&5
-$as_echo_n "checking for OSCARLIB... " >&6; }
-
-if test -n "$OSCARLIB_CFLAGS"; then
-    pkg_cv_OSCARLIB_CFLAGS="$OSCARLIB_CFLAGS"
- elif test -n "$PKG_CONFIG"; then
-    if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"oscarlib\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "oscarlib") 2>&5
-  ac_status=$?
-  $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
+ if test "x$ENABLE_ENGINE_CAMPFIRE" = "xyes"; then
+  ENABLE_ENGINE_CAMPFIRE_TRUE=
+  ENABLE_ENGINE_CAMPFIRE_FALSE='#'
 else
-  pkg_failed=yes
-fi
- else
-    pkg_failed=untried
-fi
-if test -n "$OSCARLIB_LIBS"; then
-    pkg_cv_OSCARLIB_LIBS="$OSCARLIB_LIBS"
- elif test -n "$PKG_CONFIG"; then
-    if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"oscarlib\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "oscarlib") 2>&5
-  ac_status=$?
-  $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
- 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
-	        OSCARLIB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "oscarlib" 2>&1`
-        else
-	        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
-
-	OSCAR_SUPPORT=no
-elif test $pkg_failed = untried; then
-     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-	OSCAR_SUPPORT=no
-else
-	OSCARLIB_CFLAGS=$pkg_cv_OSCARLIB_CFLAGS
-	OSCARLIB_LIBS=$pkg_cv_OSCARLIB_LIBS
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-	OSCAR_SUPPORT=yes
-fi
-
-	if test "x$ENABLE_ENGINE_OSCAR" = "xyes" -a "x$OSCAR_ENGINE_SUPPORT" != "xyes"; then
-		as_fn_error $? "OscarLib not found" "$LINENO" 5
-	else
-		ENABLE_ENGINE_OSCARC=$OSCAR_SUPPORT
-	fi
-fi
- if test "x$ENABLE_ENGINE_OSCAR" = "xyes"; then
-  ENABLE_ENGINE_OSCAR_TRUE=
-  ENABLE_ENGINE_OSCAR_FALSE='#'
-else
-  ENABLE_ENGINE_OSCAR_TRUE='#'
-  ENABLE_ENGINE_OSCAR_FALSE=
+  ENABLE_ENGINE_CAMPFIRE_TRUE='#'
+  ENABLE_ENGINE_CAMPFIRE_FALSE=
 fi
 
 
@@ -16337,102 +16611,6 @@ else
 fi
 
 
-# Check whether --enable-engine-msnp was given.
-if test "${enable_engine_msnp+set}" = set; then :
-  enableval=$enable_engine_msnp; ENABLE_ENGINE_MSNP=$enableval
-else
-  ENABLE_ENGINE_MSNP=no
-
-fi
-
-if test "x$ENABLE_ENGINE_MSNP" != "xno"; then
-
-pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for MSNPSHARP" >&5
-$as_echo_n "checking for MSNPSHARP... " >&6; }
-
-if test -n "$MSNPSHARP_CFLAGS"; then
-    pkg_cv_MSNPSHARP_CFLAGS="$MSNPSHARP_CFLAGS"
- elif test -n "$PKG_CONFIG"; then
-    if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"msnp-sharp\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "msnp-sharp") 2>&5
-  ac_status=$?
-  $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
- else
-    pkg_failed=untried
-fi
-if test -n "$MSNPSHARP_LIBS"; then
-    pkg_cv_MSNPSHARP_LIBS="$MSNPSHARP_LIBS"
- elif test -n "$PKG_CONFIG"; then
-    if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"msnp-sharp\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "msnp-sharp") 2>&5
-  ac_status=$?
-  $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
- 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
-	        MSNPSHARP_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "msnp-sharp" 2>&1`
-        else
-	        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
-
-	MSNP_SUPPORT=no
-elif test $pkg_failed = untried; then
-     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-	MSNP_SUPPORT=no
-else
-	MSNPSHARP_CFLAGS=$pkg_cv_MSNPSHARP_CFLAGS
-	MSNPSHARP_LIBS=$pkg_cv_MSNPSHARP_LIBS
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-	MSNP_SUPPORT=yes
-fi
-
-	if test "x$ENABLE_ENGINE_MSNP" = "xyes" -a "x$MSNP_SUPPORT" != "xyes"; then
-		as_fn_error $? "MSNPSharp not found" "$LINENO" 5
-	else
-		ENABLE_ENGINE_MSNP=$MSNP_SUPPORT
-	fi
-fi
- if test "x$ENABLE_ENGINE_MSNP" = "xyes"; then
-  ENABLE_ENGINE_MSNP_TRUE=
-  ENABLE_ENGINE_MSNP_FALSE='#'
-else
-  ENABLE_ENGINE_MSNP_TRUE='#'
-  ENABLE_ENGINE_MSNP_FALSE=
-fi
-
-
 # Check whether --enable-engine-twitter was given.
 if test "${enable_engine_twitter+set}" = set; then :
   enableval=$enable_engine_twitter; ENABLE_ENGINE_TWITTER=$enableval
@@ -16910,6 +17088,12 @@ $as_echo "not found" >&6; }
 
 
 
+	if test "x$WITH_MESSAGINGMENU" = "xsystem"; then
+		FRONTEND_GNOME_COMPILER_FLAGS+=" -define:MESSAGING_MENU_SHARP"
+	fi
+	if test "x$WITH_MESSAGINGMENU" = "xincluded"; then
+		FRONTEND_GNOME_COMPILER_FLAGS+=" -define:MESSAGING_MENU_SHARP"
+	fi
 	if test "x$WITH_INDICATE" = "xyes"; then
 		FRONTEND_GNOME_COMPILER_FLAGS+=" -define:INDICATE_SHARP"
 	fi
@@ -17169,7 +17353,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-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"
+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-Twitter/Makefile src/Engine-XMPP/Makefile src/Engine-XMPP/smuxi-engine-xmpp.pc src/Engine-Campfire/Makefile 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-Campfire/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
@@ -17369,22 +17553,22 @@ 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 "${WITH_MESSAGINGMENU_SHARP_INCLUDED_TRUE}" && test -z "${WITH_MESSAGINGMENU_SHARP_INCLUDED_FALSE}"; then
+  as_fn_error $? "conditional \"WITH_MESSAGINGMENU_SHARP_INCLUDED\" 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.
 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.
+if test -z "${ENABLE_ENGINE_CAMPFIRE_TRUE}" && test -z "${ENABLE_ENGINE_CAMPFIRE_FALSE}"; then
+  as_fn_error $? "conditional \"ENABLE_ENGINE_CAMPFIRE\" 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.
 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.
-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.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -17822,7 +18006,7 @@ 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.10.2, which was
+This file was extended by smuxi $as_me 0.8.11, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -17879,7 +18063,7 @@ _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.10.2
+smuxi config.status 0.8.11
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
@@ -18295,13 +18479,10 @@ do
     "src/Engine/smuxi-engine.pc") CONFIG_FILES="$CONFIG_FILES src/Engine/smuxi-engine.pc" ;;
     "src/Engine-IRC/Makefile") CONFIG_FILES="$CONFIG_FILES src/Engine-IRC/Makefile" ;;
     "src/Engine-IRC/smuxi-engine-irc.pc") CONFIG_FILES="$CONFIG_FILES src/Engine-IRC/smuxi-engine-irc.pc" ;;
-    "src/Engine-MSNP/Makefile") CONFIG_FILES="$CONFIG_FILES src/Engine-MSNP/Makefile" ;;
-    "src/Engine-MSNP/smuxi-engine-msnp.pc") CONFIG_FILES="$CONFIG_FILES src/Engine-MSNP/smuxi-engine-msnp.pc" ;;
-    "src/Engine-OSCAR/Makefile") CONFIG_FILES="$CONFIG_FILES src/Engine-OSCAR/Makefile" ;;
-    "src/Engine-OSCAR/smuxi-engine-oscar.pc") CONFIG_FILES="$CONFIG_FILES src/Engine-OSCAR/smuxi-engine-oscar.pc" ;;
     "src/Engine-Twitter/Makefile") CONFIG_FILES="$CONFIG_FILES src/Engine-Twitter/Makefile" ;;
     "src/Engine-XMPP/Makefile") CONFIG_FILES="$CONFIG_FILES src/Engine-XMPP/Makefile" ;;
     "src/Engine-XMPP/smuxi-engine-xmpp.pc") CONFIG_FILES="$CONFIG_FILES src/Engine-XMPP/smuxi-engine-xmpp.pc" ;;
+    "src/Engine-Campfire/Makefile") CONFIG_FILES="$CONFIG_FILES src/Engine-Campfire/Makefile" ;;
     "src/Server/Makefile") CONFIG_FILES="$CONFIG_FILES src/Server/Makefile" ;;
     "src/Server/smuxi-server") CONFIG_FILES="$CONFIG_FILES src/Server/smuxi-server" ;;
     "src/Frontend/Makefile") CONFIG_FILES="$CONFIG_FILES src/Frontend/Makefile" ;;
@@ -18323,6 +18504,7 @@ do
     "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-Campfire/Makefile.in") CONFIG_FILES="$CONFIG_FILES po-Engine-Campfire/Makefile.in" ;;
     "po-Engine-IRC/Makefile.in") CONFIG_FILES="$CONFIG_FILES po-Engine-IRC/Makefile.in" ;;
     "po-Engine-Twitter/Makefile.in") CONFIG_FILES="$CONFIG_FILES po-Engine-Twitter/Makefile.in" ;;
     "po-Server/Makefile.in") CONFIG_FILES="$CONFIG_FILES po-Server/Makefile.in" ;;
@@ -19818,14 +20000,15 @@ fi
 	  Core:                (db4o: $WITH_DB4O)
 	  IRC:                 $ENABLE_ENGINE_IRC
 	  XMPP:                $ENABLE_ENGINE_XMPP
-	  OSCAR:               $ENABLE_ENGINE_OSCAR
-	  MSNP:                $ENABLE_ENGINE_MSNP
 	  Twitter:             $ENABLE_ENGINE_TWITTER
+	  Campfire:            $ENABLE_ENGINE_CAMPFIRE
 
 	* Frontends
 	  ---------
 	  GNOME:               $ENABLE_FRONTEND_GNOME (IRC: $ENABLE_FRONTEND_GNOME_IRC XMPP: $ENABLE_FRONTEND_GNOME_XMPP)
-	  + Messaging Menu:    $WITH_INDICATE
+	  + Messaging Menu     (indicate: Ubuntu <= 12.04, messaging-menu: Ubuntu >= 12.04)
+	    - indicate:        $WITH_INDICATE
+	    - messaging-menu:  $WITH_MESSAGINGMENU
 	  + Notifications:     $WITH_NOTIFY
 	  + Spell Checking:    $WITH_GTKSPELL
 	  + D-Bus:             $WITH_DBUS
@@ -19848,14 +20031,15 @@ $as_echo "
 	  Core:                (db4o: $WITH_DB4O)
 	  IRC:                 $ENABLE_ENGINE_IRC
 	  XMPP:                $ENABLE_ENGINE_XMPP
-	  OSCAR:               $ENABLE_ENGINE_OSCAR
-	  MSNP:                $ENABLE_ENGINE_MSNP
 	  Twitter:             $ENABLE_ENGINE_TWITTER
+	  Campfire:            $ENABLE_ENGINE_CAMPFIRE
 
 	* Frontends
 	  ---------
 	  GNOME:               $ENABLE_FRONTEND_GNOME (IRC: $ENABLE_FRONTEND_GNOME_IRC XMPP: $ENABLE_FRONTEND_GNOME_XMPP)
-	  + Messaging Menu:    $WITH_INDICATE
+	  + Messaging Menu     (indicate: Ubuntu <= 12.04, messaging-menu: Ubuntu >= 12.04)
+	    - indicate:        $WITH_INDICATE
+	    - messaging-menu:  $WITH_MESSAGINGMENU
 	  + Notifications:     $WITH_NOTIFY
 	  + Spell Checking:    $WITH_GTKSPELL
 	  + D-Bus:             $WITH_DBUS
diff --git a/configure.ac b/configure.ac
index 3c05033..73a270d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,5 +1,5 @@
 AC_PREREQ([2.54])
-AC_INIT([smuxi], [0.8.10.2], [http://www.smuxi.org/issues/new])
+AC_INIT([smuxi], [0.8.11], [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])
@@ -22,10 +22,9 @@ IT_PROG_INTLTOOL([0.25])
 POSUB="
 	po
 	po-Engine
+	po-Engine-Campfire
 	po-Engine-IRC
 	po-Engine-XMPP
-	po-Engine-OSCAR
-	po-Engine-MSNP
 	po-Server
 	po-Frontend
 	po-Frontend-GNOME
@@ -49,18 +48,14 @@ GETTEXT_PACKAGE_ENGINE_XMPP=smuxi-engine-xmpp
 AC_SUBST(GETTEXT_PACKAGE_ENGINE_XMPP)
 AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE_ENGINE_XMPP, "$GETTEXT_PACKAGE_ENGINE_XMPP", [Gettext package])
 
-GETTEXT_PACKAGE_ENGINE_OSCAR=smuxi-engine-oscar
-AC_SUBST(GETTEXT_PACKAGE_ENGINE_OSCAR)
-AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE_ENGINE_OSCAR, "$GETTEXT_PACKAGE_ENGINE_OSCAR", [Gettext package])
-
-GETTEXT_PACKAGE_ENGINE_MSNP=smuxi-engine-msnp
-AC_SUBST(GETTEXT_PACKAGE_ENGINE_MNSP)
-AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE_ENGINE_MSNP, "$GETTEXT_PACKAGE_ENGINE_MSNP", [Gettext package])
-
 GETTEXT_PACKAGE_ENGINE_TWITTER=smuxi-engine-twitter
 AC_SUBST(GETTEXT_PACKAGE_ENGINE_TWITTER)
 AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE_ENGINE_TWITTER, "$GETTEXT_PACKAGE_ENGINE_TWITTER", [Gettext package])
 
+GETTEXT_PACKAGE_ENGINE_CAMPFIRE=smuxi-engine-campfire
+AC_SUBST(GETTEXT_PACKAGE_ENGINE_CAMPFIRE)
+AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE_ENGINE_CAMPFIRE, "$GETTEXT_PACKAGE_ENGINE_CAMPFIRE", [Gettext package])
+
 GETTEXT_PACKAGE_SERVER=smuxi-server
 AC_SUBST(GETTEXT_PACKAGE_SERVER)
 AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE_SERVER, "$GETTEXT_PACKAGE_SERVER", [Gettext package])
@@ -240,13 +235,56 @@ if test "x$WITH_DB4O" = "xincluded"; then
 fi
 
 # Optional Libraries
+AC_ARG_WITH([messaging-menu],
+	AC_HELP_STRING([--with-messaging-menu=auto|system|included|no], [Support Messaging Menu (Ubuntu >= 12.10) @<:@default=auto@:>@]),
+	[],
+	with_messagingmenu=auto
+)
+WITH_MESSAGINGMENU=$with_messagingmenu
+if test "x$WITH_MESSAGINGMENU" = "xauto"; then
+	PKG_CHECK_EXISTS([messagingmenu-sharp-0.1], FOUND_MESSAGINGMENU_SHARP=yes, FOUND_MESSAGINGMENU_SHARP=no)
+	if test "x$FOUND_MESSAGINGMENU_SHARP" = "xyes"; then
+		WITH_MESSAGINGMENU=system
+	else
+		PKG_CHECK_EXISTS([messaging-menu], FOUND_MESSAGING_MENU=yes, FOUND_MESSAGING_MENU=no)
+		if test "x$FOUND_MESSAGING_MENU" = "xyes"; then
+			WITH_MESSAGINGMENU=included
+		else
+			WITH_MESSAGINGMENU=no
+		fi
+	fi
+fi
+if test "x$WITH_MESSAGINGMENU" = "xsystem"; then
+	PKG_CHECK_MODULES([MESSAGINGMENU_SHARP], [messagingmenu-sharp-0.1])
+fi
+if test "x$WITH_MESSAGINGMENU" = "xincluded"; then
+	if test ! -f "$srcdir/lib/messagingmenu-sharp/configure.ac"; then
+		AC_MSG_ERROR([lib/messagingmenu-sharp is empty!])
+	fi
+
+	PKG_CHECK_MODULES([MESSAGING_MENU], [messaging-menu])
+	PKG_CHECK_MODULES([GIO_SHARP], [gio-sharp-2.0])
+	GIO_SHARP_LIBS=`$PKG_CONFIG --variable=Libraries gio-sharp-2.0`
+	AC_SUBST([GIO_SHARP_LIBS])
+	GIO_SHARP_FILES="gio-sharp.dll"
+	AC_SUBST([GIO_SHARP_FILES])
+
+	ac_configure_args="$ac_configure_args CSC=$MCS"
+	AC_CONFIG_SUBDIRS([lib/messagingmenu-sharp])
+	AC_SUBST([MESSAGINGMENU_SHARP_FILES], "messagingmenu-sharp.dll")
+fi
+AM_CONDITIONAL([WITH_MESSAGINGMENU_SHARP_INCLUDED], test "x$WITH_MESSAGINGMENU" = "xincluded")
+
 AC_ARG_WITH([indicate],
-	AC_HELP_STRING([--with-indicate], [Support Messaging Menu @<:@default=auto@:>@]),
+	AC_HELP_STRING([--with-indicate], [Support Messaging Menu (Ubuntu <= 12.04) @<:@default=auto@:>@]),
 	[],
 	with_indicate=auto
 )
 WITH_INDICATE=$with_indicate
 PKG_CHECK_EXISTS([indicate-sharp-0.1], INDICATE_SHARP_SUPPORT=yes, INDICATE_SHARP_SUPPORT=no)
+if test "x$WITH_INDICATE" = "xauto" -a "x$WITH_MESSAGINGMENU" != "xno"; then
+	WITH_INDICATE=no
+fi
 if test "x$WITH_INDICATE" = "xauto"; then
 	WITH_INDICATE=$INDICATE_SHARP_SUPPORT
 fi
@@ -328,21 +366,12 @@ if test "x$ENABLE_ENGINE_IRC" != "xno"; then
 fi
 AM_CONDITIONAL(ENABLE_ENGINE_IRC, test "x$ENABLE_ENGINE_IRC" = "xyes")
 
-AC_ARG_ENABLE([engine-oscar],
-	AC_HELP_STRING([--enable-engine-oscar], [Enable OSCAR (AIM/ICQ) protocol support (default no)]),
-	ENABLE_ENGINE_OSCAR=$enableval,
-	ENABLE_ENGINE_OSCAR=no
+AC_ARG_ENABLE([engine-campfire],
+	AC_HELP_STRING([--enable-engine-campfire], [Enable Campfire protocol support (default yes)]),
+	ENABLE_ENGINE_CAMPFIRE=$enableval,
+	ENABLE_ENGINE_CAMPFIRE=yes
 )
-if test "x$ENABLE_ENGINE_OSCAR" != "xno"; then
-	PKG_CHECK_MODULES([OSCARLIB], [oscarlib], OSCAR_SUPPORT=yes, OSCAR_SUPPORT=no)
-	AC_SUBST(OSCARLIB_LIBS)
-	if test "x$ENABLE_ENGINE_OSCAR" = "xyes" -a "x$OSCAR_ENGINE_SUPPORT" != "xyes"; then
-		AC_MSG_ERROR([OscarLib not found])
-	else
-		ENABLE_ENGINE_OSCARC=$OSCAR_SUPPORT
-	fi
-fi
-AM_CONDITIONAL(ENABLE_ENGINE_OSCAR, test "x$ENABLE_ENGINE_OSCAR" = "xyes")
+AM_CONDITIONAL(ENABLE_ENGINE_CAMPFIRE, test "x$ENABLE_ENGINE_CAMPFIRE" = "xyes")
 
 AC_ARG_ENABLE([engine-xmpp],
 	AC_HELP_STRING([--enable-engine-xmpp], [Enable XMPP (Jabber) protocol support (default yes)]),
@@ -366,22 +395,6 @@ if test "x$ENABLE_ENGINE_XMPP" != "xno"; then
 fi
 AM_CONDITIONAL(ENABLE_ENGINE_XMPP, test "x$ENABLE_ENGINE_XMPP" = "xyes")
 
-AC_ARG_ENABLE([engine-msnp],
-	AC_HELP_STRING([--enable-engine-msnp], [Enable MSNP protocol support (default no)]),
-	ENABLE_ENGINE_MSNP=$enableval,
-	ENABLE_ENGINE_MSNP=no
-)
-if test "x$ENABLE_ENGINE_MSNP" != "xno"; then
-	PKG_CHECK_MODULES([MSNPSHARP], [msnp-sharp], MSNP_SUPPORT=yes, MSNP_SUPPORT=no)
-	AC_SUBST(MSNPSHARP_LIBS)
-	if test "x$ENABLE_ENGINE_MSNP" = "xyes" -a "x$MSNP_SUPPORT" != "xyes"; then
-		AC_MSG_ERROR([MSNPSharp not found])
-	else
-		ENABLE_ENGINE_MSNP=$MSNP_SUPPORT
-	fi
-fi
-AM_CONDITIONAL(ENABLE_ENGINE_MSNP, test "x$ENABLE_ENGINE_MSNP" = "xyes")
-
 AC_ARG_ENABLE([engine-twitter],
 	AC_HELP_STRING([--enable-engine-twitter], [Enable Twitter support (default yes)]),
 	ENABLE_ENGINE_TWITTER=$enableval,
@@ -469,6 +482,12 @@ if test "x$ENABLE_FRONTEND_GNOME" != "xno"; then
 		System.Drawing
 	])
 	
+	if test "x$WITH_MESSAGINGMENU" = "xsystem"; then
+		FRONTEND_GNOME_COMPILER_FLAGS+=" -define:MESSAGING_MENU_SHARP"
+	fi
+	if test "x$WITH_MESSAGINGMENU" = "xincluded"; then
+		FRONTEND_GNOME_COMPILER_FLAGS+=" -define:MESSAGING_MENU_SHARP"
+	fi
 	if test "x$WITH_INDICATE" = "xyes"; then
 		FRONTEND_GNOME_COMPILER_FLAGS+=" -define:INDICATE_SHARP"
 	fi
@@ -554,13 +573,10 @@ AC_CONFIG_FILES([
 	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/Engine-Campfire/Makefile
 	src/Server/Makefile
 	src/Server/smuxi-server
 	src/Frontend/Makefile
@@ -582,6 +598,7 @@ AC_CONFIG_FILES([
 	lib/osx/Info.plist
 	po/Makefile.in
 	po-Engine/Makefile.in
+	po-Engine-Campfire/Makefile.in
 	po-Engine-IRC/Makefile.in
 	po-Engine-Twitter/Makefile.in
 	po-Server/Makefile.in
@@ -609,14 +626,15 @@ AC_MSG_RESULT([
 	  Core:                (db4o: $WITH_DB4O)
 	  IRC:                 $ENABLE_ENGINE_IRC
 	  XMPP:                $ENABLE_ENGINE_XMPP
-	  OSCAR:               $ENABLE_ENGINE_OSCAR
-	  MSNP:                $ENABLE_ENGINE_MSNP
 	  Twitter:             $ENABLE_ENGINE_TWITTER
+	  Campfire:            $ENABLE_ENGINE_CAMPFIRE
 
 	* Frontends
 	  ---------
 	  GNOME:               $ENABLE_FRONTEND_GNOME (IRC: $ENABLE_FRONTEND_GNOME_IRC XMPP: $ENABLE_FRONTEND_GNOME_XMPP)
-	  + Messaging Menu:    $WITH_INDICATE
+	  + Messaging Menu     (indicate: Ubuntu <= 12.04, messaging-menu: Ubuntu >= 12.04)
+	    - indicate:        $WITH_INDICATE
+	    - messaging-menu:  $WITH_MESSAGINGMENU
 	  + Notifications:     $WITH_NOTIFY
 	  + Spell Checking:    $WITH_GTKSPELL
 	  + D-Bus:             $WITH_DBUS
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 75ce3ac..f927463 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -1,13 +1,56 @@
-SUBDIRS =	SmartIrc4net
+SUBDIRS =	SmartIrc4net \
+			$(MESSAGINGMENU_SHARP_SUBDIR)
+
+if WITH_MESSAGINGMENU_SHARP_INCLUDED
+MESSAGINGMENU_SHARP_SUBDIR = messagingmenu-sharp
+else
+# HACK: override DIST_SUBDIRS so distcheck/distclean works on systems without
+# libmessaging-menu-dev installed
+DIST_SUBDIRS = $(SUBDIRS)
+endif
 
 OUTPUT_DIR = $(top_builddir)/bin/$(PROFILE)
 OBJECT_DIR = $(OUTPUT_DIR)/obj
 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=
+XBUILD_FLAGS +=  /p:Configuration=Debug /p:SignAssembly=false /p:WarningLevel=0 /p:Warn=0 /p:OutputPath=$(abspath $(OUTPUT_DIR)) /p:BaseIntermediateOutputPath=$(abspath $(OBJECT_DIR))/ /p:IntermediateOutputPath=$(abspath $(OBJECT_DIR))/ /p:DocumentationFile=
+
+SERVICESTACK_TEXT_SUBDIR = ServiceStack.Text
+SERVICESTACK_TEXT_SRCDIR = $(srcdir)/$(SERVICESTACK_TEXT_SUBDIR)/src/ServiceStack.Text
+SERVICESTACK_TEXT_SOURCE_FILES = $(foreach pattern, $(SOURCE_PATTERNS), $(wildcard $(SERVICESTACK_TEXT_SRCDIR)/$(pattern)))
+SERVICESTACK_TEXT_EXTRA_FILES = $(SERVICESTACK_TEXT_BUILD_FILE)
+SERVICESTACK_TEXT_ASSEMBLY_NAME = ServiceStack.Text.dll
+SERVICESTACK_TEXT_ASSEMBLY_TARGET = $(OUTPUT_DIR)/$(SERVICESTACK_TEXT_ASSEMBLY_NAME)
+SERVICESTACK_TEXT_BUILD_FILE = $(SERVICESTACK_TEXT_SRCDIR)/ServiceStack.Text.csproj
+SERVICESTACK_TEXT_XBUILD_FLAGS = $(XBUILD_FLAGS)
+
+SERVICESTACK_SUBDIR = ServiceStack
+SERVICESTACK_SRCDIR = $(srcdir)/$(SERVICESTACK_SUBDIR)
+SERVICESTACK_INTERFACES_SRCDIR = $(srcdir)/$(SERVICESTACK_SUBDIR)/src/ServiceStack.Interfaces
+SERVICESTACK_INTERFACES_SOURCE_FILES = $(foreach pattern, $(SOURCE_PATTERNS), $(wildcard $(SERVICESTACK_INTERFACES_SRCDIR)/$(pattern)))
+SERVICESTACK_INTERFACES_EXTRA_FILES = $(SERVICESTACK_INTERFACES_BUILD_FILE)
+SERVICESTACK_INTERFACES_ASSEMBLY_NAME = ServiceStack.Interfaces.dll
+SERVICESTACK_INTERFACES_ASSEMBLY_TARGET = $(OUTPUT_DIR)/$(SERVICESTACK_INTERFACES_ASSEMBLY_NAME)
+SERVICESTACK_INTERFACES_BUILD_FILE = $(SERVICESTACK_INTERFACES_SRCDIR)/ServiceStack.Interfaces.csproj
+SERVICESTACK_INTERFACES_XBUILD_FLAGS = $(XBUILD_FLAGS)
+SERVICESTACK_COMMON_SRCDIR = $(srcdir)/$(SERVICESTACK_SUBDIR)/src/ServiceStack.Common
+SERVICESTACK_COMMON_SOURCE_FILES = $(foreach pattern, $(SOURCE_PATTERNS), $(wildcard $(SERVICESTACK_COMMON_SRCDIR)/$(pattern)))
+SERVICESTACK_COMMON_EXTRA_FILES = $(SERVICESTACK_COMMON_BUILD_FILE)
+SERVICESTACK_COMMON_ASSEMBLY_NAME = ServiceStack.Common.dll
+SERVICESTACK_COMMON_ASSEMBLY_TARGET = $(OUTPUT_DIR)/$(SERVICESTACK_COMMON_ASSEMBLY_NAME)
+SERVICESTACK_COMMON_BUILD_FILE = $(SERVICESTACK_COMMON_SRCDIR)/ServiceStack.Common.csproj
+SERVICESTACK_COMMON_XBUILD_FLAGS = $(XBUILD_FLAGS)
+
+EXTRA_SERVICESTACK_LIBS = \
+	$(SERVICESTACK_TEXT_ASSEMBLY_TARGET) $(SERVICESTACK_TEXT_ASSEMBLY_TARGET).mdb \
+	$(SERVICESTACK_INTERFACES_ASSEMBLY_TARGET) $(SERVICESTACK_INTERFACES_ASSEMBLY_TARGET).mdb \
+	$(SERVICESTACK_COMMON_ASSEMBLY_TARGET) $(SERVICESTACK_COMMON_ASSEMBLY_TARGET).mdb
 
 JSON_SUBDIR = Newtonsoft.Json
 JSON_SRCDIR = $(srcdir)/$(JSON_SUBDIR)/Src/Newtonsoft.Json
 JSON_SOURCE_FILES = $(foreach pattern, $(SOURCE_PATTERNS), $(wildcard $(JSON_SRCDIR)/$(pattern)))
+JSON_EXTRA_FILES = \
+	$(JSON_BUILD_FILE) \
+	$(JSON_SRCDIR)/Dynamic.snk
 JSON_CLEAN_FILES = $(OBJECT_DIR)/Newtonsoft.Json.Dynamic.snk
 JSON_ASSEMBLY_NAME = Newtonsoft.Json.dll
 JSON_ASSEMBLY_TARGET = $(OUTPUT_DIR)/$(JSON_ASSEMBLY_NAME)
@@ -17,7 +60,13 @@ JSON_XBUILD_FLAGS = $(XBUILD_FLAGS)
 TWITTERIZER_SUBDIR = Twitterizer
 TWITTERIZER_SRCDIR = $(srcdir)/$(TWITTERIZER_SUBDIR)/Twitterizer2
 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_EXTRA_FILES = \
+	$(TWITTERIZER_BUILD_FILE) \
+	$(TWITTERIZER_SRCDIR)/Twitterizer2.snk \
+	$(TWITTERIZER_SRCDIR)/../CommonAssemblyInfo.cs \
+	$(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 \
@@ -31,7 +80,9 @@ 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_EXTRA_FILES = \
+	$(JABBER_NET_BUILD_FILE) \
+	$(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)
@@ -41,24 +92,25 @@ 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_EXTRA_FILES = $(DB4O_BUILD_FILE)
 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_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)
+#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
@@ -77,15 +129,26 @@ EXTRA_DB4O_LIBS = \
 #	$(DB4O_NQ_ASSEMBLY_TARGET) $(DB4O_NQ_ASSEMBLY_TARGET).mdb
 endif
 pkgappdir = $(pkglibdir)
-pkgapp_DATA = $(EXTRA_TWITTER_LIBS) $(EXTRA_XMPP_LIBS) $(EXTRA_DB4O_LIBS)
+pkgapp_DATA = $(EXTRA_SERVICESTACK_LIBS) $(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_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)
+	$(SERVICESTACK_TEXT_SRCDIR) $(SERVICESTACK_TEXT_EXTRA_FILES) \
+	$(SERVICESTACK_INTERFACES_SRCDIR) $(SERVICESTACK_INTERFACES_EXTRA_FILES) \
+	$(SERVICESTACK_COMMON_SRCDIR) $(SERVICESTACK_COMMON_EXTRA_FILES) \
+	$(JSON_SRCDIR) $(JSON_EXTRA_FILES) \
+	$(TWITTERIZER_SRCDIR) $(TWITTERIZER_EXTRA_FILES) \
+	$(JABBER_NET_SRCDIR) $(JABBER_NET_EXTRA_FILES) \
+	$(DB4O_SRCDIR) $(DB4O_EXTRA_FILES)
+
+#	 $(SERVICESTACK_TEXT_SOURCE_FILES) $(SERVICESTACK_TEXT_BUILD_FILE) \
+#	 $(SERVICESTACK_INTERFACES_SOURCE_FILES) $(SERVICESTACK_INTERFACES_BUILD_FILE) \
+#	 $(SERVICESTACK_COMMON_SOURCE_FILES) $(SERVICESTACK_COMMON_BUILD_FILE) \
+#	 $(JSON_SOURCE_FILES) $(JSON_BUILD_FILE) $(JSON_SRCDIR)/Dynamic.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) \
@@ -93,6 +156,15 @@ CLEANFILES = \
 	$(TWITTERIZER_CLEAN_FILES)
 # end of magic
 
+$(SERVICESTACK_TEXT_ASSEMBLY_TARGET) $(SERVICESTACK_TEXT_ASSEMBLY_TARGET).mdb: $(SERVICESTACK_TEXT_BUILD_FILE) $(SERVICESTACK_TEXT_SOURCE_FILES)
+	$(XBUILD) $(SERVICESTACK_TEXT_XBUILD_FLAGS) $(SERVICESTACK_TEXT_BUILD_FILE)
+
+$(SERVICESTACK_INTERFACES_ASSEMBLY_TARGET) $(SERVICESTACK_INTERFACES_ASSEMBLY_TARGET).mdb: $(SERVICESTACK_INTERFACES_BUILD_FILE) $(SERVICESTACK_INTERFACES_SOURCE_FILES)
+	$(XBUILD) $(SERVICESTACK_INTERFACES_XBUILD_FLAGS) $(SERVICESTACK_INTERFACES_BUILD_FILE)
+
+$(SERVICESTACK_COMMON_ASSEMBLY_TARGET) $(SERVICESTACK_COMMON_ASSEMBLY_TARGET).mdb: $(SERVICESTACK_TEXT_ASSEMBLY_TARGET) $(SERVICESTACK_COMMON_BUILD_FILE) $(SERVICESTACK_COMMON_SOURCE_FILES)
+	$(XBUILD) $(SERVICESTACK_COMMON_XBUILD_FLAGS) $(SERVICESTACK_COMMON_BUILD_FILE)
+
 $(JSON_ASSEMBLY_TARGET) $(JSON_ASSEMBLY_TARGET).mdb: $(JSON_BUILD_FILE) $(JSON_SOURCE_FILES)
 	$(XBUILD) $(JSON_XBUILD_FLAGS) $(JSON_BUILD_FILE)
 
@@ -105,13 +177,16 @@ $(JABBER_NET_ASSEMBLY_TARGET) $(JABBER_NET_ASSEMBLY_TARGET).mdb: $(JABBER_NET_BU
 $(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_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)
+#$(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:
+	$(XBUILD) $(SERVICESTACK_TEXT_XBUILD_FLAGS) /t:Clean $(SERVICESTACK_TEXT_BUILD_FILE)
+	$(XBUILD) $(SERVICESTACK_INTERFACES_XBUILD_FLAGS) /t:Clean $(SERVICESTACK_INTERFACES_BUILD_FILE)
+	$(XBUILD) $(SERVICESTACK_COMMON_XBUILD_FLAGS) /t:Clean $(SERVICESTACK_COMMON_BUILD_FILE)
 if ENABLE_ENGINE_TWITTER
 	$(XBUILD) $(JSON_XBUILD_FLAGS) /t:Clean $(JSON_BUILD_FILE)
 	$(XBUILD) $(TWITTERIZER_XBUILD_FLAGS) /t:Clean $(TWITTERIZER_BUILD_FILE)
@@ -124,3 +199,78 @@ if BUNDLE_DB4O
 #	$(XBUILD) $(DB4O_INSTR_XBUILD_FLAGS) /t:Clean $(DB4O_INSTR_BUILD_FILE)
 #	$(XBUILD) $(DB4O_NQ_XBUILD_FLAGS) /t:Clean $(DB4O_NQ_BUILD_FILE)
 endif
+
+distdir: $(DISTFILES) $(DIST_SUBDIRS)
+	$(am__remove_distdir)
+	test -d "$(distdir)" || mkdir "$(distdir)"
+	@for DISTFILE in $(DISTFILES); do \
+		if [ -d "$$DISTFILE" ]; then \
+			mkdir -p $(distdir)/$(srcdir)/$$DISTFILE; \
+			rsync -a \
+				--prune-empty-dirs \
+				--include='*/' \
+				--include='*.cs' \
+				--exclude='*' \
+				$$DISTFILE/ $(distdir)/$(srcdir)/$$DISTFILE; \
+		else \
+			DISTFILES="$$DISTFILES $$DISTFILE"; \
+		fi \
+	done; \
+	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 -z "$$file"; then continue; fi; \
+	  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
+	@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
diff --git a/lib/Makefile.in b/lib/Makefile.in
index 6c8557b..a601c90 100644
--- a/lib/Makefile.in
+++ b/lib/Makefile.in
@@ -55,8 +55,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
@@ -112,7 +115,6 @@ AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
 	distdir
 ETAGS = etags
 CTAGS = ctags
-DIST_SUBDIRS = $(SUBDIRS)
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 am__relativize = \
   dir0=`pwd`; \
@@ -181,9 +183,8 @@ 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_CAMPFIRE = @GETTEXT_PACKAGE_ENGINE_CAMPFIRE@
 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@
@@ -195,6 +196,9 @@ 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@
+GIO_SHARP_CFLAGS = @GIO_SHARP_CFLAGS@
+GIO_SHARP_FILES = @GIO_SHARP_FILES@
+GIO_SHARP_LIBS = @GIO_SHARP_LIBS@
 GLADE_SHARP_20_CFLAGS = @GLADE_SHARP_20_CFLAGS@
 GLADE_SHARP_20_LIBS = @GLADE_SHARP_20_LIBS@
 GLIB_SHARP_20_CFLAGS = @GLIB_SHARP_20_CFLAGS@
@@ -241,6 +245,11 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
+MESSAGINGMENU_SHARP_CFLAGS = @MESSAGINGMENU_SHARP_CFLAGS@
+MESSAGINGMENU_SHARP_FILES = @MESSAGINGMENU_SHARP_FILES@
+MESSAGINGMENU_SHARP_LIBS = @MESSAGINGMENU_SHARP_LIBS@
+MESSAGING_MENU_CFLAGS = @MESSAGING_MENU_CFLAGS@
+MESSAGING_MENU_LIBS = @MESSAGING_MENU_LIBS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
 MONO_MODULE_CFLAGS = @MONO_MODULE_CFLAGS@
@@ -248,8 +257,6 @@ 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@
@@ -262,8 +269,6 @@ 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@
@@ -292,7 +297,7 @@ USE_NLS = @USE_NLS@
 VERSION = @VERSION@
 XBUILD = @XBUILD@
 XBUILD_FLAGS = @XBUILD_FLAGS@ /p:Configuration=Debug \
-	/p:SignAssembly=false /p:WarningLevel=0 \
+	/p:SignAssembly=false /p:WarningLevel=0 /p:Warn=0 \
 	/p:OutputPath=$(abspath $(OUTPUT_DIR)) \
 	/p:BaseIntermediateOutputPath=$(abspath $(OBJECT_DIR))/ \
 	/p:IntermediateOutputPath=$(abspath $(OBJECT_DIR))/ \
@@ -360,13 +365,52 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 twitter_api_key = @twitter_api_key@
-SUBDIRS = SmartIrc4net
+SUBDIRS = SmartIrc4net \
+			$(MESSAGINGMENU_SHARP_SUBDIR)
+
+ at WITH_MESSAGINGMENU_SHARP_INCLUDED_TRUE@MESSAGINGMENU_SHARP_SUBDIR = messagingmenu-sharp
+# HACK: override DIST_SUBDIRS so distcheck/distclean works on systems without
+# libmessaging-menu-dev installed
+ at WITH_MESSAGINGMENU_SHARP_INCLUDED_FALSE@DIST_SUBDIRS = $(SUBDIRS)
 OUTPUT_DIR = $(top_builddir)/bin/$(PROFILE)
 OBJECT_DIR = $(OUTPUT_DIR)/obj
 SOURCE_PATTERNS = *.cs */*.cs */*/*.cs */*/*/*.cs */*/*/*/*.cs */*/*/*/*/*.cs
+SERVICESTACK_TEXT_SUBDIR = ServiceStack.Text
+SERVICESTACK_TEXT_SRCDIR = $(srcdir)/$(SERVICESTACK_TEXT_SUBDIR)/src/ServiceStack.Text
+SERVICESTACK_TEXT_SOURCE_FILES = $(foreach pattern, $(SOURCE_PATTERNS), $(wildcard $(SERVICESTACK_TEXT_SRCDIR)/$(pattern)))
+SERVICESTACK_TEXT_EXTRA_FILES = $(SERVICESTACK_TEXT_BUILD_FILE)
+SERVICESTACK_TEXT_ASSEMBLY_NAME = ServiceStack.Text.dll
+SERVICESTACK_TEXT_ASSEMBLY_TARGET = $(OUTPUT_DIR)/$(SERVICESTACK_TEXT_ASSEMBLY_NAME)
+SERVICESTACK_TEXT_BUILD_FILE = $(SERVICESTACK_TEXT_SRCDIR)/ServiceStack.Text.csproj
+SERVICESTACK_TEXT_XBUILD_FLAGS = $(XBUILD_FLAGS)
+SERVICESTACK_SUBDIR = ServiceStack
+SERVICESTACK_SRCDIR = $(srcdir)/$(SERVICESTACK_SUBDIR)
+SERVICESTACK_INTERFACES_SRCDIR = $(srcdir)/$(SERVICESTACK_SUBDIR)/src/ServiceStack.Interfaces
+SERVICESTACK_INTERFACES_SOURCE_FILES = $(foreach pattern, $(SOURCE_PATTERNS), $(wildcard $(SERVICESTACK_INTERFACES_SRCDIR)/$(pattern)))
+SERVICESTACK_INTERFACES_EXTRA_FILES = $(SERVICESTACK_INTERFACES_BUILD_FILE)
+SERVICESTACK_INTERFACES_ASSEMBLY_NAME = ServiceStack.Interfaces.dll
+SERVICESTACK_INTERFACES_ASSEMBLY_TARGET = $(OUTPUT_DIR)/$(SERVICESTACK_INTERFACES_ASSEMBLY_NAME)
+SERVICESTACK_INTERFACES_BUILD_FILE = $(SERVICESTACK_INTERFACES_SRCDIR)/ServiceStack.Interfaces.csproj
+SERVICESTACK_INTERFACES_XBUILD_FLAGS = $(XBUILD_FLAGS)
+SERVICESTACK_COMMON_SRCDIR = $(srcdir)/$(SERVICESTACK_SUBDIR)/src/ServiceStack.Common
+SERVICESTACK_COMMON_SOURCE_FILES = $(foreach pattern, $(SOURCE_PATTERNS), $(wildcard $(SERVICESTACK_COMMON_SRCDIR)/$(pattern)))
+SERVICESTACK_COMMON_EXTRA_FILES = $(SERVICESTACK_COMMON_BUILD_FILE)
+SERVICESTACK_COMMON_ASSEMBLY_NAME = ServiceStack.Common.dll
+SERVICESTACK_COMMON_ASSEMBLY_TARGET = $(OUTPUT_DIR)/$(SERVICESTACK_COMMON_ASSEMBLY_NAME)
+SERVICESTACK_COMMON_BUILD_FILE = $(SERVICESTACK_COMMON_SRCDIR)/ServiceStack.Common.csproj
+SERVICESTACK_COMMON_XBUILD_FLAGS = $(XBUILD_FLAGS)
+EXTRA_SERVICESTACK_LIBS = \
+	$(SERVICESTACK_TEXT_ASSEMBLY_TARGET) $(SERVICESTACK_TEXT_ASSEMBLY_TARGET).mdb \
+	$(SERVICESTACK_INTERFACES_ASSEMBLY_TARGET) $(SERVICESTACK_INTERFACES_ASSEMBLY_TARGET).mdb \
+	$(SERVICESTACK_COMMON_ASSEMBLY_TARGET) $(SERVICESTACK_COMMON_ASSEMBLY_TARGET).mdb
+
 JSON_SUBDIR = Newtonsoft.Json
 JSON_SRCDIR = $(srcdir)/$(JSON_SUBDIR)/Src/Newtonsoft.Json
 JSON_SOURCE_FILES = $(foreach pattern, $(SOURCE_PATTERNS), $(wildcard $(JSON_SRCDIR)/$(pattern)))
+JSON_EXTRA_FILES = \
+	$(JSON_BUILD_FILE) \
+	$(JSON_SRCDIR)/Dynamic.snk
+
 JSON_CLEAN_FILES = $(OBJECT_DIR)/Newtonsoft.Json.Dynamic.snk
 JSON_ASSEMBLY_NAME = Newtonsoft.Json.dll
 JSON_ASSEMBLY_TARGET = $(OUTPUT_DIR)/$(JSON_ASSEMBLY_NAME)
@@ -375,7 +419,14 @@ JSON_XBUILD_FLAGS = $(XBUILD_FLAGS)
 TWITTERIZER_SUBDIR = Twitterizer
 TWITTERIZER_SRCDIR = $(srcdir)/$(TWITTERIZER_SUBDIR)/Twitterizer2
 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_EXTRA_FILES = \
+	$(TWITTERIZER_BUILD_FILE) \
+	$(TWITTERIZER_SRCDIR)/Twitterizer2.snk \
+	$(TWITTERIZER_SRCDIR)/../CommonAssemblyInfo.cs \
+	$(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 \
@@ -389,7 +440,10 @@ 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_EXTRA_FILES = \
+	$(JABBER_NET_BUILD_FILE) \
+	$(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)
@@ -398,22 +452,25 @@ 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_EXTRA_FILES = $(DB4O_BUILD_FILE)
 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)
+
+#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
 @ENABLE_ENGINE_TWITTER_TRUE at EXTRA_TWITTER_LIBS = \
@@ -429,15 +486,26 @@ DB4O_NQ_XBUILD_FLAGS = $(DB4O_XBUILD_FLAGS)
 #	$(DB4O_INSTR_ASSEMBLY_TARGET) $(DB4O_INSTR_ASSEMBLY_TARGET).mdb \
 #	$(DB4O_NQ_ASSEMBLY_TARGET) $(DB4O_NQ_ASSEMBLY_TARGET).mdb
 pkgappdir = $(pkglibdir)
-pkgapp_DATA = $(EXTRA_TWITTER_LIBS) $(EXTRA_XMPP_LIBS) $(EXTRA_DB4O_LIBS)
+pkgapp_DATA = $(EXTRA_SERVICESTACK_LIBS) $(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_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)
-
+	$(SERVICESTACK_TEXT_SRCDIR) $(SERVICESTACK_TEXT_EXTRA_FILES) \
+	$(SERVICESTACK_INTERFACES_SRCDIR) $(SERVICESTACK_INTERFACES_EXTRA_FILES) \
+	$(SERVICESTACK_COMMON_SRCDIR) $(SERVICESTACK_COMMON_EXTRA_FILES) \
+	$(JSON_SRCDIR) $(JSON_EXTRA_FILES) \
+	$(TWITTERIZER_SRCDIR) $(TWITTERIZER_EXTRA_FILES) \
+	$(JABBER_NET_SRCDIR) $(JABBER_NET_EXTRA_FILES) \
+	$(DB4O_SRCDIR) $(DB4O_EXTRA_FILES)
+
+
+#	 $(SERVICESTACK_TEXT_SOURCE_FILES) $(SERVICESTACK_TEXT_BUILD_FILE) \
+#	 $(SERVICESTACK_INTERFACES_SOURCE_FILES) $(SERVICESTACK_INTERFACES_BUILD_FILE) \
+#	 $(SERVICESTACK_COMMON_SOURCE_FILES) $(SERVICESTACK_COMMON_BUILD_FILE) \
+#	 $(JSON_SOURCE_FILES) $(JSON_BUILD_FILE) $(JSON_SRCDIR)/Dynamic.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) \
@@ -638,62 +706,6 @@ GTAGS:
 
 distclean-tags:
 	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-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
-	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
-	  if test "$$subdir" = .; then :; else \
-	    $(am__make_dryrun) \
-	      || test -d "$(distdir)/$$subdir" \
-	      || $(MKDIR_P) "$(distdir)/$$subdir" \
-	      || exit 1; \
-	    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-recursive
 all-am: Makefile $(DATA)
@@ -819,6 +831,15 @@ uninstall-am: uninstall-pkgappDATA
 
 # end of magic
 
+$(SERVICESTACK_TEXT_ASSEMBLY_TARGET) $(SERVICESTACK_TEXT_ASSEMBLY_TARGET).mdb: $(SERVICESTACK_TEXT_BUILD_FILE) $(SERVICESTACK_TEXT_SOURCE_FILES)
+	$(XBUILD) $(SERVICESTACK_TEXT_XBUILD_FLAGS) $(SERVICESTACK_TEXT_BUILD_FILE)
+
+$(SERVICESTACK_INTERFACES_ASSEMBLY_TARGET) $(SERVICESTACK_INTERFACES_ASSEMBLY_TARGET).mdb: $(SERVICESTACK_INTERFACES_BUILD_FILE) $(SERVICESTACK_INTERFACES_SOURCE_FILES)
+	$(XBUILD) $(SERVICESTACK_INTERFACES_XBUILD_FLAGS) $(SERVICESTACK_INTERFACES_BUILD_FILE)
+
+$(SERVICESTACK_COMMON_ASSEMBLY_TARGET) $(SERVICESTACK_COMMON_ASSEMBLY_TARGET).mdb: $(SERVICESTACK_TEXT_ASSEMBLY_TARGET) $(SERVICESTACK_COMMON_BUILD_FILE) $(SERVICESTACK_COMMON_SOURCE_FILES)
+	$(XBUILD) $(SERVICESTACK_COMMON_XBUILD_FLAGS) $(SERVICESTACK_COMMON_BUILD_FILE)
+
 $(JSON_ASSEMBLY_TARGET) $(JSON_ASSEMBLY_TARGET).mdb: $(JSON_BUILD_FILE) $(JSON_SOURCE_FILES)
 	$(XBUILD) $(JSON_XBUILD_FLAGS) $(JSON_BUILD_FILE)
 
@@ -831,13 +852,16 @@ $(JABBER_NET_ASSEMBLY_TARGET) $(JABBER_NET_ASSEMBLY_TARGET).mdb: $(JABBER_NET_BU
 $(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_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)
+#$(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:
+	$(XBUILD) $(SERVICESTACK_TEXT_XBUILD_FLAGS) /t:Clean $(SERVICESTACK_TEXT_BUILD_FILE)
+	$(XBUILD) $(SERVICESTACK_INTERFACES_XBUILD_FLAGS) /t:Clean $(SERVICESTACK_INTERFACES_BUILD_FILE)
+	$(XBUILD) $(SERVICESTACK_COMMON_XBUILD_FLAGS) /t:Clean $(SERVICESTACK_COMMON_BUILD_FILE)
 @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)
 @ENABLE_ENGINE_XMPP_TRUE@	$(XBUILD) $(JABBER_NET_XBUILD_FLAGS) /t:Clean $(JABBER_NET_BUILD_FILE)
@@ -845,6 +869,81 @@ clean-local:
 #	$(XBUILD) $(DB4O_INSTR_XBUILD_FLAGS) /t:Clean $(DB4O_INSTR_BUILD_FILE)
 #	$(XBUILD) $(DB4O_NQ_XBUILD_FLAGS) /t:Clean $(DB4O_NQ_BUILD_FILE)
 
+distdir: $(DISTFILES) $(DIST_SUBDIRS)
+	$(am__remove_distdir)
+	test -d "$(distdir)" || mkdir "$(distdir)"
+	@for DISTFILE in $(DISTFILES); do \
+		if [ -d "$$DISTFILE" ]; then \
+			mkdir -p $(distdir)/$(srcdir)/$$DISTFILE; \
+			rsync -a \
+				--prune-empty-dirs \
+				--include='*/' \
+				--include='*.cs' \
+				--exclude='*' \
+				$$DISTFILE/ $(distdir)/$(srcdir)/$$DISTFILE; \
+		else \
+			DISTFILES="$$DISTFILES $$DISTFILE"; \
+		fi \
+	done; \
+	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 -z "$$file"; then continue; fi; \
+	  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
+	@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
+
 # 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/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonBinaryType.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonBinaryType.cs
index 2c4f7df..0826446 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonBinaryType.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonBinaryType.cs
@@ -1,36 +1,40 @@
-#region License
-// 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.
-#endregion
-
-namespace Newtonsoft.Json.Bson
-{
-  internal enum BsonBinaryType : byte
-  {
-    Function = 0x01,
-    Data = 0x02,
-    Uuid = 0x03,
-    Md5 = 0x05,
-    UserDefined = 0x80
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json.Bson
+{
+  internal enum BsonBinaryType : byte
+  {
+    Binary = 0x00,
+    Function = 0x01,
+    [Obsolete("This type has been deprecated in the BSON specification. Use Binary instead.")]
+    Data = 0x02,
+    Uuid = 0x03,
+    Md5 = 0x05,
+    UserDefined = 0x80
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonBinaryWriter.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonBinaryWriter.cs
index 84a7ffb..78e7c7f 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonBinaryWriter.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonBinaryWriter.cs
@@ -1,297 +1,325 @@
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Linq;
-using System.Text;
-using Newtonsoft.Json.Utilities;
-
-namespace Newtonsoft.Json.Bson
-{
-  internal class BsonBinaryWriter
-  {
-    private static readonly Encoding Encoding = Encoding.UTF8;
-
-    private readonly BinaryWriter _writer;
-
-    private byte[] _largeByteBuffer;
-    private int _maxChars;
-
-    public DateTimeKind DateTimeKindHandling { get; set; }
-
-    public BsonBinaryWriter(Stream stream)
-    {
-      DateTimeKindHandling = DateTimeKind.Utc;
-      _writer = new BinaryWriter(stream);
-    }
-
-    public void Flush()
-    {
-      _writer.Flush();
-    }
-
-    public void WriteToken(BsonToken t)
-    {
-      CalculateSize(t);
-      WriteTokenInternal(t);
-    }
-
-    private void WriteTokenInternal(BsonToken t)
-    {
-      switch (t.Type)
-      {
-        case BsonType.Object:
-          {
-            BsonObject value = (BsonObject) t;
-            _writer.Write(value.CalculatedSize);
-            foreach (BsonProperty property in value)
-            {
-              _writer.Write((sbyte)property.Value.Type);
-              WriteString((string)property.Name.Value, property.Name.ByteCount, null);
-              WriteTokenInternal(property.Value);
-            }
-            _writer.Write((byte)0);
-          }
-          break;
-        case BsonType.Array:
-          {
-            BsonArray value = (BsonArray) t;
-            _writer.Write(value.CalculatedSize);
-            int index = 0;
-            foreach (BsonToken c in value)
-            {
-              _writer.Write((sbyte)c.Type);
-              WriteString(index.ToString(CultureInfo.InvariantCulture), MathUtils.IntLength(index), null);
-              WriteTokenInternal(c);
-              index++;
-            }
-            _writer.Write((byte)0);
-          }
-          break;
-        case BsonType.Integer:
-          {
-            BsonValue value = (BsonValue) t;
-            _writer.Write(Convert.ToInt32(value.Value, CultureInfo.InvariantCulture));
-          }
-          break;
-        case BsonType.Long:
-          {
-            BsonValue value = (BsonValue)t;
-            _writer.Write(Convert.ToInt64(value.Value, CultureInfo.InvariantCulture));
-          }
-          break;
-        case BsonType.Number:
-          {
-            BsonValue value = (BsonValue)t;
-            _writer.Write(Convert.ToDouble(value.Value, CultureInfo.InvariantCulture));
-          }
-          break;
-        case BsonType.String:
-          {
-            BsonString value = (BsonString)t;
-            WriteString((string)value.Value, value.ByteCount, value.CalculatedSize - 4);
-          }
-          break;
-        case BsonType.Boolean:
-          {
-            BsonValue value = (BsonValue)t;
-            _writer.Write((bool)value.Value);
-          }
-          break;
-        case BsonType.Null:
-        case BsonType.Undefined:
-          break;
-        case BsonType.Date:
-          {
-            BsonValue value = (BsonValue)t;
-
-            long ticks = 0;
-
-            if (value.Value is DateTime)
-            {
-              DateTime dateTime = (DateTime) value.Value;
-              if (DateTimeKindHandling == DateTimeKind.Utc)
-                dateTime = dateTime.ToUniversalTime();
-              else if (DateTimeKindHandling == DateTimeKind.Local)
-                dateTime = dateTime.ToLocalTime();
-
-              ticks = JsonConvert.ConvertDateTimeToJavaScriptTicks(dateTime, false);
-            }
-#if !PocketPC && !NET20
-            else
-            {
-              DateTimeOffset dateTimeOffset = (DateTimeOffset) value.Value;
-              ticks = JsonConvert.ConvertDateTimeToJavaScriptTicks(dateTimeOffset.UtcDateTime, dateTimeOffset.Offset);
-            }
-#endif
-
-            _writer.Write(ticks);
-          }
-          break;
-        case BsonType.Binary:
-          {
-            BsonValue value = (BsonValue)t;
-
-            byte[] data = (byte[])value.Value;
-            _writer.Write(data.Length);
-            _writer.Write((byte)BsonBinaryType.Data);
-            _writer.Write(data);
-          }
-          break;
-        case BsonType.Oid:
-          {
-            BsonValue value = (BsonValue)t;
-
-            byte[] data = (byte[])value.Value;
-            _writer.Write(data);
-          }
-          break;
-        case BsonType.Regex:
-          {
-            BsonRegex value = (BsonRegex) t;
-
-            WriteString((string)value.Pattern.Value, value.Pattern.ByteCount, null);
-            WriteString((string)value.Options.Value, value.Options.ByteCount, null);
-          }
-          break;
-        default:
-          throw new ArgumentOutOfRangeException("t", "Unexpected token when writing BSON: {0}".FormatWith(CultureInfo.InvariantCulture, t.Type));
-      }
-    }
-
-    private void WriteString(string s, int byteCount, int? calculatedlengthPrefix)
-    {
-      if (calculatedlengthPrefix != null)
-        _writer.Write(calculatedlengthPrefix.Value);
-
-      if (s != null)
-      {
-        if (_largeByteBuffer == null)
-        {
-          _largeByteBuffer = new byte[256];
-          _maxChars = 256/Encoding.GetMaxByteCount(1);
-        }
-        if (byteCount <= 256)
-        {
-          Encoding.GetBytes(s, 0, s.Length, _largeByteBuffer, 0);
-          _writer.Write(_largeByteBuffer, 0, byteCount);
-        }
-        else
-        {
-          int charCount;
-          int totalCharsWritten = 0;
-          for (int i = s.Length; i > 0; i -= charCount)
-          {
-            charCount = (i > _maxChars) ? _maxChars : i;
-            int count = Encoding.GetBytes(s, totalCharsWritten, charCount, _largeByteBuffer, 0);
-            _writer.Write(_largeByteBuffer, 0, count);
-            totalCharsWritten += charCount;
-          }
-        }
-      }
-
-      _writer.Write((byte)0);
-    }
-
-    private int CalculateSize(int stringByteCount)
-    {
-      return stringByteCount + 1;
-    }
-
-    private int CalculateSizeWithLength(int stringByteCount, bool includeSize)
-    {
-      int baseSize = (includeSize)
-        ? 5 // size bytes + terminator
-        : 1; // terminator
-
-      return baseSize + stringByteCount;
-    }
-
-    private int CalculateSize(BsonToken t)
-    {
-      switch (t.Type)
-      {
-        case BsonType.Object:
-          {
-            BsonObject value = (BsonObject) t;
-
-            int bases = 4;
-            foreach (BsonProperty p in value)
-            {
-              int size = 1;
-              size += CalculateSize(p.Name);
-              size += CalculateSize(p.Value);
-
-              bases += size;
-            }
-            bases += 1;
-            value.CalculatedSize = bases;
-            return bases;
-          }
-        case BsonType.Array:
-          {
-            BsonArray value = (BsonArray)t;
-
-            int size = 4;
-            int index = 0;
-            foreach (BsonToken c in value)
-            {
-              size += 1;
-              size += CalculateSize(MathUtils.IntLength(index));
-              size += CalculateSize(c);
-              index++;
-            }
-            size += 1;
-            value.CalculatedSize = size;
-
-            return value.CalculatedSize;
-          }
-        case BsonType.Integer:
-          return 4;
-        case BsonType.Long:
-          return 8;
-        case BsonType.Number:
-          return 8;
-        case BsonType.String:
-          {
-            BsonString value = (BsonString)t;
-            string s = (string) value.Value;
-            value.ByteCount = (s != null) ? Encoding.GetByteCount(s) : 0;
-            value.CalculatedSize = CalculateSizeWithLength(value.ByteCount, value.IncludeLength);
-
-            return value.CalculatedSize;
-          }
-        case BsonType.Boolean:
-          return 1;
-        case BsonType.Null:
-        case BsonType.Undefined:
-          return 0;
-        case BsonType.Date:
-          return 8;
-        case BsonType.Binary:
-          {
-            BsonValue value = (BsonValue) t;
-
-            byte[] data = (byte[])value.Value;
-            value.CalculatedSize = 4 + 1 + data.Length;
-
-            return value.CalculatedSize;
-          }
-        case BsonType.Oid:
-          return 12;
-        case BsonType.Regex:
-          {
-            BsonRegex value = (BsonRegex) t;
-            int size = 0;
-            size += CalculateSize(value.Pattern);
-            size += CalculateSize(value.Options);
-            value.CalculatedSize = size;
-
-            return value.CalculatedSize;
-          }
-        default:
-          throw new ArgumentOutOfRangeException("t", "Unexpected token when writing BSON: {0}".FormatWith(CultureInfo.InvariantCulture, t.Type));
-      }
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Globalization;
+using System.IO;
+using System.Text;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Bson
+{
+  internal class BsonBinaryWriter
+  {
+    private static readonly Encoding Encoding = new UTF8Encoding(false);
+
+    private readonly BinaryWriter _writer;
+
+    private byte[] _largeByteBuffer;
+
+    public DateTimeKind DateTimeKindHandling { get; set; }
+
+    public BsonBinaryWriter(BinaryWriter writer)
+    {
+      DateTimeKindHandling = DateTimeKind.Utc;
+      _writer = writer;
+    }
+
+    public void Flush()
+    {
+      _writer.Flush();
+    }
+
+    public void Close()
+    {
+#if !(NETFX_CORE || PORTABLE)
+      _writer.Close();
+#else
+      _writer.Dispose();
+#endif
+    }
+
+    public void WriteToken(BsonToken t)
+    {
+      CalculateSize(t);
+      WriteTokenInternal(t);
+    }
+
+    private void WriteTokenInternal(BsonToken t)
+    {
+      switch (t.Type)
+      {
+        case BsonType.Object:
+          {
+            BsonObject value = (BsonObject)t;
+            _writer.Write(value.CalculatedSize);
+            foreach (BsonProperty property in value)
+            {
+              _writer.Write((sbyte)property.Value.Type);
+              WriteString((string)property.Name.Value, property.Name.ByteCount, null);
+              WriteTokenInternal(property.Value);
+            }
+            _writer.Write((byte)0);
+          }
+          break;
+        case BsonType.Array:
+          {
+            BsonArray value = (BsonArray)t;
+            _writer.Write(value.CalculatedSize);
+            int index = 0;
+            foreach (BsonToken c in value)
+            {
+              _writer.Write((sbyte)c.Type);
+              WriteString(index.ToString(CultureInfo.InvariantCulture), MathUtils.IntLength(index), null);
+              WriteTokenInternal(c);
+              index++;
+            }
+            _writer.Write((byte)0);
+          }
+          break;
+        case BsonType.Integer:
+          {
+            BsonValue value = (BsonValue)t;
+            _writer.Write(Convert.ToInt32(value.Value, CultureInfo.InvariantCulture));
+          }
+          break;
+        case BsonType.Long:
+          {
+            BsonValue value = (BsonValue)t;
+            _writer.Write(Convert.ToInt64(value.Value, CultureInfo.InvariantCulture));
+          }
+          break;
+        case BsonType.Number:
+          {
+            BsonValue value = (BsonValue)t;
+            _writer.Write(Convert.ToDouble(value.Value, CultureInfo.InvariantCulture));
+          }
+          break;
+        case BsonType.String:
+          {
+            BsonString value = (BsonString)t;
+            WriteString((string)value.Value, value.ByteCount, value.CalculatedSize - 4);
+          }
+          break;
+        case BsonType.Boolean:
+          {
+            BsonValue value = (BsonValue)t;
+            _writer.Write((bool)value.Value);
+          }
+          break;
+        case BsonType.Null:
+        case BsonType.Undefined:
+          break;
+        case BsonType.Date:
+          {
+            BsonValue value = (BsonValue)t;
+
+            long ticks = 0;
+
+            if (value.Value is DateTime)
+            {
+              DateTime dateTime = (DateTime)value.Value;
+              if (DateTimeKindHandling == DateTimeKind.Utc)
+                dateTime = dateTime.ToUniversalTime();
+              else if (DateTimeKindHandling == DateTimeKind.Local)
+                dateTime = dateTime.ToLocalTime();
+
+              ticks = JsonConvert.ConvertDateTimeToJavaScriptTicks(dateTime, false);
+            }
+#if !PocketPC && !NET20
+            else
+            {
+              DateTimeOffset dateTimeOffset = (DateTimeOffset)value.Value;
+              ticks = JsonConvert.ConvertDateTimeToJavaScriptTicks(dateTimeOffset.UtcDateTime, dateTimeOffset.Offset);
+            }
+#endif
+
+            _writer.Write(ticks);
+          }
+          break;
+        case BsonType.Binary:
+          {
+            BsonValue value = (BsonValue)t;
+
+            byte[] data = (byte[])value.Value;
+            _writer.Write(data.Length);
+            _writer.Write((byte)BsonBinaryType.Binary);
+            _writer.Write(data);
+          }
+          break;
+        case BsonType.Oid:
+          {
+            BsonValue value = (BsonValue)t;
+
+            byte[] data = (byte[])value.Value;
+            _writer.Write(data);
+          }
+          break;
+        case BsonType.Regex:
+          {
+            BsonRegex value = (BsonRegex)t;
+
+            WriteString((string)value.Pattern.Value, value.Pattern.ByteCount, null);
+            WriteString((string)value.Options.Value, value.Options.ByteCount, null);
+          }
+          break;
+        default:
+          throw new ArgumentOutOfRangeException("t", "Unexpected token when writing BSON: {0}".FormatWith(CultureInfo.InvariantCulture, t.Type));
+      }
+    }
+
+    private void WriteString(string s, int byteCount, int? calculatedlengthPrefix)
+    {
+      if (calculatedlengthPrefix != null)
+        _writer.Write(calculatedlengthPrefix.Value);
+
+      WriteUtf8Bytes(s, byteCount);
+
+      _writer.Write((byte)0);
+    }
+
+    public void WriteUtf8Bytes(string s, int byteCount)
+    {
+      if (s != null)
+      {
+        if (_largeByteBuffer == null)
+        {
+          _largeByteBuffer = new byte[256];
+        }
+        if (byteCount <= 256)
+        {
+          Encoding.GetBytes(s, 0, s.Length, _largeByteBuffer, 0);
+          _writer.Write(_largeByteBuffer, 0, byteCount);
+        }
+        else
+        {
+          byte[] bytes = Encoding.GetBytes(s);
+          _writer.Write(bytes);
+        }
+      }
+    }
+
+    private int CalculateSize(int stringByteCount)
+    {
+      return stringByteCount + 1;
+    }
+
+    private int CalculateSizeWithLength(int stringByteCount, bool includeSize)
+    {
+      int baseSize = (includeSize)
+        ? 5 // size bytes + terminator
+        : 1; // terminator
+
+      return baseSize + stringByteCount;
+    }
+
+    private int CalculateSize(BsonToken t)
+    {
+      switch (t.Type)
+      {
+        case BsonType.Object:
+          {
+            BsonObject value = (BsonObject)t;
+
+            int bases = 4;
+            foreach (BsonProperty p in value)
+            {
+              int size = 1;
+              size += CalculateSize(p.Name);
+              size += CalculateSize(p.Value);
+
+              bases += size;
+            }
+            bases += 1;
+            value.CalculatedSize = bases;
+            return bases;
+          }
+        case BsonType.Array:
+          {
+            BsonArray value = (BsonArray)t;
+
+            int size = 4;
+            int index = 0;
+            foreach (BsonToken c in value)
+            {
+              size += 1;
+              size += CalculateSize(MathUtils.IntLength(index));
+              size += CalculateSize(c);
+              index++;
+            }
+            size += 1;
+            value.CalculatedSize = size;
+
+            return value.CalculatedSize;
+          }
+        case BsonType.Integer:
+          return 4;
+        case BsonType.Long:
+          return 8;
+        case BsonType.Number:
+          return 8;
+        case BsonType.String:
+          {
+            BsonString value = (BsonString)t;
+            string s = (string)value.Value;
+            value.ByteCount = (s != null) ? Encoding.GetByteCount(s) : 0;
+            value.CalculatedSize = CalculateSizeWithLength(value.ByteCount, value.IncludeLength);
+
+            return value.CalculatedSize;
+          }
+        case BsonType.Boolean:
+          return 1;
+        case BsonType.Null:
+        case BsonType.Undefined:
+          return 0;
+        case BsonType.Date:
+          return 8;
+        case BsonType.Binary:
+          {
+            BsonValue value = (BsonValue)t;
+
+            byte[] data = (byte[])value.Value;
+            value.CalculatedSize = 4 + 1 + data.Length;
+
+            return value.CalculatedSize;
+          }
+        case BsonType.Oid:
+          return 12;
+        case BsonType.Regex:
+          {
+            BsonRegex value = (BsonRegex)t;
+            int size = 0;
+            size += CalculateSize(value.Pattern);
+            size += CalculateSize(value.Options);
+            value.CalculatedSize = size;
+
+            return value.CalculatedSize;
+          }
+        default:
+          throw new ArgumentOutOfRangeException("t", "Unexpected token when writing BSON: {0}".FormatWith(CultureInfo.InvariantCulture, t.Type));
+      }
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonObjectId.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonObjectId.cs
index 7fcf223..85cea53 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonObjectId.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonObjectId.cs
@@ -1,58 +1,55 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Newtonsoft.Json.Utilities;
-
-namespace Newtonsoft.Json.Bson
-{
-  /// <summary>
-  /// Represents a BSON Oid (object id).
-  /// </summary>
-  public class BsonObjectId
-  {
-    /// <summary>
-    /// Gets or sets the value of the Oid.
-    /// </summary>
-    /// <value>The value of the Oid.</value>
-    public byte[] Value { get; private set; }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="BsonObjectId"/> class.
-    /// </summary>
-    /// <param name="value">The Oid value.</param>
-    public BsonObjectId(byte[] value)
-    {
-      ValidationUtils.ArgumentNotNull(value, "value");
-      if (value.Length != 12)
-        throw new Exception("An ObjectId must be 12 bytes");
-
-      Value = value;
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Bson
+{
+  /// <summary>
+  /// Represents a BSON Oid (object id).
+  /// </summary>
+  public class BsonObjectId
+  {
+    /// <summary>
+    /// Gets or sets the value of the Oid.
+    /// </summary>
+    /// <value>The value of the Oid.</value>
+    public byte[] Value { get; private set; }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="BsonObjectId"/> class.
+    /// </summary>
+    /// <param name="value">The Oid value.</param>
+    public BsonObjectId(byte[] value)
+    {
+      ValidationUtils.ArgumentNotNull(value, "value");
+      if (value.Length != 12)
+        throw new ArgumentException("An ObjectId must be 12 bytes", "value");
+
+      Value = value;
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonReader.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonReader.cs
index 4b94357..7e39c96 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonReader.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonReader.cs
@@ -1,719 +1,842 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Text;
-using System.IO;
-using Newtonsoft.Json.Utilities;
-using Newtonsoft.Json.Linq;
-
-namespace Newtonsoft.Json.Bson
-{
-  /// <summary>
-  /// Represents a reader that provides fast, non-cached, forward-only access to serialized Json data.
-  /// </summary>
-  public class BsonReader : JsonReader
-  {
-    private const int MaxCharBytesSize = 128;
-    private static readonly byte[] _seqRange1 = new byte[] { 0, 127 }; // range of 1-byte sequence
-    private static readonly byte[] _seqRange2 = new byte[] { 194, 223 }; // range of 2-byte sequence
-    private static readonly byte[] _seqRange3 = new byte[] { 224, 239 }; // range of 3-byte sequence
-    private static readonly byte[] _seqRange4 = new byte[] { 240, 244 }; // range of 4-byte sequence
-
-    private readonly BinaryReader _reader;
-    private readonly List<ContainerContext> _stack;
-
-    private byte[] _byteBuffer;
-    private char[] _charBuffer;
-
-    private BsonType _currentElementType;
-    private BsonReaderState _bsonReaderState;
-    private ContainerContext _currentContext;
-
-    private bool _readRootValueAsArray;
-    private DateTimeKind _dateTimeKindHandling;
-
-    private enum BsonReaderState
-    {
-      Normal,
-      ReferenceStart,
-      ReferenceRef,
-      ReferenceId,
-      CodeWScopeStart,
-      CodeWScopeCode,
-      CodeWScopeScope,
-      CodeWScopeScopeObject,
-      CodeWScopeScopeEnd
-    }
-
-    private class ContainerContext
-    {
-      public readonly BsonType Type;
-      public int Length;
-      public int Position;
-
-      public ContainerContext(BsonType type)
-      {
-        Type = type;
-      }
-    }
-
-    /// <summary>
-    /// Gets or sets a value indicating whether the root object will be read as a JSON array.
-    /// </summary>
-    /// <value>
-    /// 	<c>true</c> if the root object will be read as a JSON array; otherwise, <c>false</c>.
-    /// </value>
-    public bool ReadRootValueAsArray
-    {
-      get { return _readRootValueAsArray; }
-      set { _readRootValueAsArray = value; }
-    }
-
-    /// <summary>
-    /// Gets or sets the <see cref="DateTimeKind" /> used when reading <see cref="DateTime"/> values from BSON.
-    /// </summary>
-    /// <value>The <see cref="DateTimeKind" /> used when reading <see cref="DateTime"/> values from BSON.</value>
-    public DateTimeKind DateTimeKindHandling
-    {
-      get { return _dateTimeKindHandling; }
-      set { _dateTimeKindHandling = value; }
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="BsonReader"/> class.
-    /// </summary>
-    /// <param name="stream">The stream.</param>
-    public BsonReader(Stream stream)
-      : this(stream, false, DateTimeKind.Local)
-    {
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="BsonReader"/> class.
-    /// </summary>
-    /// <param name="stream">The stream.</param>
-    /// <param name="readRootValueAsArray">if set to <c>true</c> the root object will be read as a JSON array.</param>
-    /// <param name="dateTimeKindHandling">The <see cref="DateTimeKind" /> used when reading <see cref="DateTime"/> values from BSON.</param>
-    public BsonReader(Stream stream, bool readRootValueAsArray, DateTimeKind dateTimeKindHandling)
-    {
-      ValidationUtils.ArgumentNotNull(stream, "stream");
-      _reader = new BinaryReader(stream);
-      _stack = new List<ContainerContext>();
-      _readRootValueAsArray = readRootValueAsArray;
-      _dateTimeKindHandling = dateTimeKindHandling;
-    }
-
-    private string ReadElement()
-    {
-      _currentElementType = ReadType();
-      string elementName = ReadString();
-      return elementName;
-    }
-
-    /// <summary>
-    /// Reads the next JSON token from the stream as a <see cref="T:Byte[]"/>.
-    /// </summary>
-    /// <returns>
-    /// A <see cref="T:Byte[]"/> or a null reference if the next JSON token is null.
-    /// </returns>
-    public override byte[] ReadAsBytes()
-    {
-      Read();
-      if (TokenType != JsonToken.Bytes)
-        throw new JsonReaderException("Error reading bytes. Expected bytes but got {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
-
-      return (byte[])Value;
-    }
-
-    /// <summary>
-    /// Reads the next JSON token from the stream.
-    /// </summary>
-    /// <returns>
-    /// true if the next token was read successfully; false if there are no more tokens to read.
-    /// </returns>
-    public override bool Read()
-    {
-      try
-      {
-        switch (_bsonReaderState)
-        {
-          case BsonReaderState.Normal:
-            return ReadNormal();
-          case BsonReaderState.ReferenceStart:
-          case BsonReaderState.ReferenceRef:
-          case BsonReaderState.ReferenceId:
-            return ReadReference();
-          case BsonReaderState.CodeWScopeStart:
-          case BsonReaderState.CodeWScopeCode:
-          case BsonReaderState.CodeWScopeScope:
-          case BsonReaderState.CodeWScopeScopeObject:
-          case BsonReaderState.CodeWScopeScopeEnd:
-            return ReadCodeWScope();
-          default:
-            throw new JsonReaderException("Unexpected state: {0}".FormatWith(CultureInfo.InvariantCulture, _bsonReaderState));
-        }
-      }
-      catch (EndOfStreamException)
-      {
-        return false;
-      }
-    }
-
-    private bool ReadCodeWScope()
-    {
-      switch (_bsonReaderState)
-      {
-        case BsonReaderState.CodeWScopeStart:
-          SetToken(JsonToken.PropertyName, "$code");
-          _bsonReaderState = BsonReaderState.CodeWScopeCode;
-          return true;
-        case BsonReaderState.CodeWScopeCode:
-          // total CodeWScope size - not used
-          ReadInt32();
-
-          SetToken(JsonToken.String, ReadLengthString());
-          _bsonReaderState = BsonReaderState.CodeWScopeScope;
-          return true;
-        case BsonReaderState.CodeWScopeScope:
-          if (CurrentState == State.PostValue)
-          {
-            SetToken(JsonToken.PropertyName, "$scope");
-            return true;
-          }
-          else
-          {
-            SetToken(JsonToken.StartObject);
-            _bsonReaderState = BsonReaderState.CodeWScopeScopeObject;
-
-            ContainerContext newContext = new ContainerContext(BsonType.Object);
-            PushContext(newContext);
-            newContext.Length = ReadInt32();
-
-            return true;
-          }
-        case BsonReaderState.CodeWScopeScopeObject:
-          bool result = ReadNormal();
-          if (result && TokenType == JsonToken.EndObject)
-            _bsonReaderState = BsonReaderState.CodeWScopeScopeEnd;
-
-          return result;
-        case BsonReaderState.CodeWScopeScopeEnd:
-          SetToken(JsonToken.EndObject);
-          _bsonReaderState = BsonReaderState.Normal;
-          return true;
-        default:
-          throw new ArgumentOutOfRangeException();
-      }
-    }
-
-    private bool ReadReference()
-    {
-      switch (CurrentState)
-      {
-        case State.ObjectStart:
-          {
-            SetToken(JsonToken.PropertyName, "$ref");
-            _bsonReaderState = BsonReaderState.ReferenceRef;
-            return true;
-          }
-        case State.Property:
-          {
-            if (_bsonReaderState == BsonReaderState.ReferenceRef)
-            {
-              SetToken(JsonToken.String, ReadLengthString());
-              return true;
-            }
-            else if (_bsonReaderState == BsonReaderState.ReferenceId)
-            {
-              SetToken(JsonToken.Bytes, ReadBytes(12));
-              return true;
-            }
-            else
-            {
-              throw new JsonReaderException("Unexpected state when reading BSON reference: " + _bsonReaderState);
-            }
-          }
-        case State.PostValue:
-          {
-            if (_bsonReaderState == BsonReaderState.ReferenceRef)
-            {
-              SetToken(JsonToken.PropertyName, "$id");
-              _bsonReaderState = BsonReaderState.ReferenceId;
-              return true;
-            }
-            else if (_bsonReaderState == BsonReaderState.ReferenceId)
-            {
-              SetToken(JsonToken.EndObject);
-              _bsonReaderState = BsonReaderState.Normal;
-              return true;
-            }
-            else
-            {
-              throw new JsonReaderException("Unexpected state when reading BSON reference: " + _bsonReaderState);
-            }
-          }
-        default:
-          throw new JsonReaderException("Unexpected state when reading BSON reference: " + CurrentState);
-      }
-    }
-
-    private bool ReadNormal()
-    {
-      switch (CurrentState)
-      {
-        case State.Start:
-          {
-            JsonToken token = (!_readRootValueAsArray) ? JsonToken.StartObject : JsonToken.StartArray;
-            BsonType type = (!_readRootValueAsArray) ? BsonType.Object : BsonType.Array;
-
-            SetToken(token);
-            ContainerContext newContext = new ContainerContext(type);
-            PushContext(newContext);
-            newContext.Length = ReadInt32();
-            return true;
-          }
-        case State.Complete:
-        case State.Closed:
-          return false;
-        case State.Property:
-          {
-            ReadType(_currentElementType);
-            return true;
-          }
-        case State.ObjectStart:
-        case State.ArrayStart:
-        case State.PostValue:
-          ContainerContext context = _currentContext;
-          if (context == null)
-            return false;
-
-          int lengthMinusEnd = context.Length - 1;
-
-          if (context.Position < lengthMinusEnd)
-          {
-            if (context.Type == BsonType.Array)
-            {
-              ReadElement();
-              ReadType(_currentElementType);
-              return true;
-            }
-            else
-            {
-              SetToken(JsonToken.PropertyName, ReadElement());
-              return true;
-            }
-          }
-          else if (context.Position == lengthMinusEnd)
-          {
-            if (ReadByte() != 0)
-              throw new JsonReaderException("Unexpected end of object byte value.");
-
-            PopContext();
-            if (_currentContext != null)
-              MovePosition(context.Length);
-
-            JsonToken endToken = (context.Type == BsonType.Object) ? JsonToken.EndObject : JsonToken.EndArray;
-            SetToken(endToken);
-            return true;
-          }
-          else
-          {
-            throw new JsonReaderException("Read past end of current container context.");
-          }
-        case State.ConstructorStart:
-          break;
-        case State.Constructor:
-          break;
-        case State.Error:
-          break;
-        case State.Finished:
-          break;
-        default:
-          throw new ArgumentOutOfRangeException();
-      }
-
-      return false;
-    }
-
-    private void PopContext()
-    {
-      _stack.RemoveAt(_stack.Count - 1);
-      if (_stack.Count == 0)
-        _currentContext = null;
-      else
-        _currentContext = _stack[_stack.Count - 1];
-    }
-
-    private void PushContext(ContainerContext newContext)
-    {
-      _stack.Add(newContext);
-      _currentContext = newContext;
-    }
-
-    private byte ReadByte()
-    {
-      MovePosition(1);
-      return _reader.ReadByte();
-    }
-
-    private void ReadType(BsonType type)
-    {
-      switch (type)
-      {
-        case BsonType.Number:
-          SetToken(JsonToken.Float, ReadDouble());
-          break;
-        case BsonType.String:
-        case BsonType.Symbol:
-          SetToken(JsonToken.String, ReadLengthString());
-          break;
-        case BsonType.Object:
-          {
-            SetToken(JsonToken.StartObject);
-
-            ContainerContext newContext = new ContainerContext(BsonType.Object);
-            PushContext(newContext);
-            newContext.Length = ReadInt32();
-            break;
-          }
-        case BsonType.Array:
-          {
-            SetToken(JsonToken.StartArray);
-
-            ContainerContext newContext = new ContainerContext(BsonType.Array);
-            PushContext(newContext);
-            newContext.Length = ReadInt32();
-            break;
-          }
-        case BsonType.Binary:
-          SetToken(JsonToken.Bytes, ReadBinary());
-          break;
-        case BsonType.Undefined:
-          SetToken(JsonToken.Undefined);
-          break;
-        case BsonType.Oid:
-          byte[] oid = ReadBytes(12);
-          SetToken(JsonToken.Bytes, oid);
-          break;
-        case BsonType.Boolean:
-          bool b = Convert.ToBoolean(ReadByte());
-          SetToken(JsonToken.Boolean, b);
-          break;
-        case BsonType.Date:
-          long ticks = ReadInt64();
-          DateTime utcDateTime = JsonConvert.ConvertJavaScriptTicksToDateTime(ticks);
-
-          DateTime dateTime;
-          switch (DateTimeKindHandling)
-          {
-            case DateTimeKind.Unspecified:
-              dateTime = DateTime.SpecifyKind(utcDateTime.ToLocalTime(), DateTimeKind.Unspecified);
-              break;
-            case DateTimeKind.Local:
-              dateTime = utcDateTime.ToLocalTime();
-              break;
-            default:
-              dateTime = utcDateTime;
-              break;
-          }
-
-          SetToken(JsonToken.Date, dateTime);
-          break;
-        case BsonType.Null:
-          SetToken(JsonToken.Null);
-          break;
-        case BsonType.Regex:
-          string expression = ReadString();
-          string modifiers = ReadString();
-
-          string regex = @"/" + expression + @"/" + modifiers;
-          SetToken(JsonToken.String, regex);
-          break;
-        case BsonType.Reference:
-          SetToken(JsonToken.StartObject);
-          _bsonReaderState = BsonReaderState.ReferenceStart;
-          break;
-        case BsonType.Code:
-          SetToken(JsonToken.String, ReadLengthString());
-          break;
-        case BsonType.CodeWScope:
-          SetToken(JsonToken.StartObject);
-          _bsonReaderState = BsonReaderState.CodeWScopeStart;
-          break;
-        case BsonType.Integer:
-          SetToken(JsonToken.Integer, (long)ReadInt32());
-          break;
-        case BsonType.TimeStamp:
-        case BsonType.Long:
-          SetToken(JsonToken.Integer, ReadInt64());
-          break;
-        default:
-          throw new ArgumentOutOfRangeException("type", "Unexpected BsonType value: " + type);
-      }
-    }
-
-    private byte[] ReadBinary()
-    {
-      int dataLength = ReadInt32();
-
-      // BsonBinaryType not used
-      ReadByte();
-
-      return ReadBytes(dataLength);
-    }
-
-    private string ReadString()
-    {
-      EnsureBuffers();
-
-      StringBuilder builder = null;
-
-      int totalBytesRead = 0;
-      // used in case of left over multibyte characters in the buffer
-      int offset = 0;
-      do
-      {
-        int count = offset;
-        byte b;
-        while (count < MaxCharBytesSize && (b = _reader.ReadByte()) > 0)
-        {
-          _byteBuffer[count++] = b;
-        }
-        int byteCount = count - offset;
-        totalBytesRead += byteCount;
-
-        if (count < MaxCharBytesSize && builder == null)
-        {
-          // pref optimization to avoid reading into a string builder
-          // if string is smaller than the buffer then return it directly
-          int length = Encoding.UTF8.GetChars(_byteBuffer, 0, byteCount, _charBuffer, 0);
-
-          MovePosition(totalBytesRead + 1);
-          return new string(_charBuffer, 0, length);
-        }
-        else
-        {
-          // calculate the index of the end of the last full character in the buffer
-          int lastFullCharStop = GetLastFullCharStop(count - 1);
-
-          int charCount = Encoding.UTF8.GetChars(_byteBuffer, 0, lastFullCharStop + 1, _charBuffer, 0);
-
-          if (builder == null)
-            builder = new StringBuilder(MaxCharBytesSize * 2);
-
-          builder.Append(_charBuffer, 0, charCount);
-
-          if (lastFullCharStop < byteCount - 1)
-          {
-            offset = byteCount - lastFullCharStop - 1;
-            // copy left over multi byte characters to beginning of buffer for next iteration
-            Array.Copy(_byteBuffer, lastFullCharStop + 1, _byteBuffer, 0, offset);
-          }
-          else
-          {
-            // reached end of string
-            if (count < MaxCharBytesSize)
-            {
-              MovePosition(totalBytesRead + 1);
-              return builder.ToString();
-            }
-
-            offset = 0;
-          }
-        }
-      }
-      while (true);
-    }
-
-    private string ReadLengthString()
-    {
-      int length = ReadInt32();
-
-      MovePosition(length);
-
-      string s = GetString(length - 1);
-      _reader.ReadByte();
-
-      return s;
-    }
-
-    private string GetString(int length)
-    {
-      if (length == 0)
-        return string.Empty;
-
-      EnsureBuffers();
-
-      StringBuilder builder = null;
-
-      int totalBytesRead = 0;
-
-      // used in case of left over multibyte characters in the buffer
-      int offset = 0;
-      do
-      {
-        int count = ((length - totalBytesRead) > MaxCharBytesSize - offset)
-          ? MaxCharBytesSize - offset
-          : length - totalBytesRead;
-
-        int byteCount = _reader.BaseStream.Read(_byteBuffer, offset, count);
-
-        if (byteCount == 0)
-          throw new EndOfStreamException("Unable to read beyond the end of the stream.");
-
-        totalBytesRead += byteCount;
-
-        // Above, byteCount is how many bytes we read this time.
-        // Below, byteCount is how many bytes are in the _byteBuffer.
-        byteCount += offset;
-
-        if (byteCount == length)
-        {
-          // pref optimization to avoid reading into a string builder
-          // first iteration and all bytes read then return string directly
-          int charCount = Encoding.UTF8.GetChars(_byteBuffer, 0, byteCount, _charBuffer, 0);
-          return new string(_charBuffer, 0, charCount);
-        }
-        else
-        {
-          int lastFullCharStop = GetLastFullCharStop(byteCount - 1);
-
-          if (builder == null)
-            builder = new StringBuilder(length);
-
-          int charCount = Encoding.UTF8.GetChars(_byteBuffer, 0, lastFullCharStop + 1, _charBuffer, 0);
-          builder.Append(_charBuffer, 0, charCount);
-
-          if (lastFullCharStop < byteCount - 1)
-          {
-            offset = byteCount - lastFullCharStop - 1;
-            // copy left over multi byte characters to beginning of buffer for next iteration
-            Array.Copy(_byteBuffer, lastFullCharStop + 1, _byteBuffer, 0, offset);
-          }
-          else
-          {
-            offset = 0;
-          }
-        }
-      }
-      while (totalBytesRead < length);
-
-      return builder.ToString();
-    }
-
-    private int GetLastFullCharStop(int start)
-    {
-      int lookbackPos = start;
-      int bis = 0;
-      while (lookbackPos >= 0)
-      {
-        bis = BytesInSequence(_byteBuffer[lookbackPos]);
-        if (bis == 0)
-        {
-          lookbackPos--;
-          continue;
-        }
-        else if (bis == 1)
-        {
-          break;
-        }
-        else
-        {
-          lookbackPos--;
-          break;
-        }
-      }
-      if (bis == start - lookbackPos)
-      {
-        //Full character.
-        return start;
-      }
-      else
-      {
-        return lookbackPos;
-      }
-    }
-
-    private int BytesInSequence(byte b)
-    {
-      if (b <= _seqRange1[1]) return 1;
-      if (b >= _seqRange2[0] && b <= _seqRange2[1]) return 2;
-      if (b >= _seqRange3[0] && b <= _seqRange3[1]) return 3;
-      if (b >= _seqRange4[0] && b <= _seqRange4[1]) return 4;
-      return 0;
-    }
-
-    private void EnsureBuffers()
-    {
-      if (_byteBuffer == null)
-      {
-        _byteBuffer = new byte[MaxCharBytesSize];
-      }
-      if (_charBuffer == null)
-      {
-        int charBufferSize = Encoding.UTF8.GetMaxCharCount(MaxCharBytesSize);
-        _charBuffer = new char[charBufferSize];
-      }
-    }
-
-    private double ReadDouble()
-    {
-      MovePosition(8);
-      return _reader.ReadDouble();
-    }
-
-    private int ReadInt32()
-    {
-      MovePosition(4);
-      return _reader.ReadInt32();
-    }
-
-    private long ReadInt64()
-    {
-      MovePosition(8);
-      return _reader.ReadInt64();
-    }
-
-    private BsonType ReadType()
-    {
-      MovePosition(1);
-      return (BsonType)_reader.ReadSByte();
-    }
-
-    private void MovePosition(int count)
-    {
-      _currentContext.Position += count;
-    }
-
-    private byte[] ReadBytes(int count)
-    {
-      MovePosition(count);
-      return _reader.ReadBytes(count);
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Text;
+using System.IO;
+using Newtonsoft.Json.Utilities;
+using Newtonsoft.Json.Linq;
+
+namespace Newtonsoft.Json.Bson
+{
+  /// <summary>
+  /// Represents a reader that provides fast, non-cached, forward-only access to serialized Json data.
+  /// </summary>
+  public class BsonReader : JsonReader
+  {
+    private const int MaxCharBytesSize = 128;
+    private static readonly byte[] SeqRange1 = new byte[] {0, 127}; // range of 1-byte sequence
+    private static readonly byte[] SeqRange2 = new byte[] {194, 223}; // range of 2-byte sequence
+    private static readonly byte[] SeqRange3 = new byte[] {224, 239}; // range of 3-byte sequence
+    private static readonly byte[] SeqRange4 = new byte[] {240, 244}; // range of 4-byte sequence
+
+    private readonly BinaryReader _reader;
+    private readonly List<ContainerContext> _stack;
+
+    private byte[] _byteBuffer;
+    private char[] _charBuffer;
+
+    private BsonType _currentElementType;
+    private BsonReaderState _bsonReaderState;
+    private ContainerContext _currentContext;
+
+    private bool _readRootValueAsArray;
+    private bool _jsonNet35BinaryCompatibility;
+    private DateTimeKind _dateTimeKindHandling;
+
+    private enum BsonReaderState
+    {
+      Normal,
+      ReferenceStart,
+      ReferenceRef,
+      ReferenceId,
+      CodeWScopeStart,
+      CodeWScopeCode,
+      CodeWScopeScope,
+      CodeWScopeScopeObject,
+      CodeWScopeScopeEnd
+    }
+
+    private class ContainerContext
+    {
+      public readonly BsonType Type;
+      public int Length;
+      public int Position;
+
+      public ContainerContext(BsonType type)
+      {
+        Type = type;
+      }
+    }
+
+    /// <summary>
+    /// Gets or sets a value indicating whether binary data reading should compatible with incorrect Json.NET 3.5 written binary.
+    /// </summary>
+    /// <value>
+    /// 	<c>true</c> if binary data reading will be compatible with incorrect Json.NET 3.5 written binary; otherwise, <c>false</c>.
+    /// </value>
+    public bool JsonNet35BinaryCompatibility
+    {
+      get { return _jsonNet35BinaryCompatibility; }
+      set { _jsonNet35BinaryCompatibility = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets a value indicating whether the root object will be read as a JSON array.
+    /// </summary>
+    /// <value>
+    /// 	<c>true</c> if the root object will be read as a JSON array; otherwise, <c>false</c>.
+    /// </value>
+    public bool ReadRootValueAsArray
+    {
+      get { return _readRootValueAsArray; }
+      set { _readRootValueAsArray = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets the <see cref="DateTimeKind" /> used when reading <see cref="DateTime"/> values from BSON.
+    /// </summary>
+    /// <value>The <see cref="DateTimeKind" /> used when reading <see cref="DateTime"/> values from BSON.</value>
+    public DateTimeKind DateTimeKindHandling
+    {
+      get { return _dateTimeKindHandling; }
+      set { _dateTimeKindHandling = value; }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="BsonReader"/> class.
+    /// </summary>
+    /// <param name="stream">The stream.</param>
+    public BsonReader(Stream stream)
+      : this(stream, false, DateTimeKind.Local)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="BsonReader"/> class.
+    /// </summary>
+    /// <param name="reader">The reader.</param>
+    public BsonReader(BinaryReader reader)
+      : this(reader, false, DateTimeKind.Local)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="BsonReader"/> class.
+    /// </summary>
+    /// <param name="stream">The stream.</param>
+    /// <param name="readRootValueAsArray">if set to <c>true</c> the root object will be read as a JSON array.</param>
+    /// <param name="dateTimeKindHandling">The <see cref="DateTimeKind" /> used when reading <see cref="DateTime"/> values from BSON.</param>
+    public BsonReader(Stream stream, bool readRootValueAsArray, DateTimeKind dateTimeKindHandling)
+    {
+      ValidationUtils.ArgumentNotNull(stream, "stream");
+      _reader = new BinaryReader(stream);
+      _stack = new List<ContainerContext>();
+      _readRootValueAsArray = readRootValueAsArray;
+      _dateTimeKindHandling = dateTimeKindHandling;
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="BsonReader"/> class.
+    /// </summary>
+    /// <param name="reader">The reader.</param>
+    /// <param name="readRootValueAsArray">if set to <c>true</c> the root object will be read as a JSON array.</param>
+    /// <param name="dateTimeKindHandling">The <see cref="DateTimeKind" /> used when reading <see cref="DateTime"/> values from BSON.</param>
+    public BsonReader(BinaryReader reader, bool readRootValueAsArray, DateTimeKind dateTimeKindHandling)
+    {
+      ValidationUtils.ArgumentNotNull(reader, "reader");
+      _reader = reader;
+      _stack = new List<ContainerContext>();
+      _readRootValueAsArray = readRootValueAsArray;
+      _dateTimeKindHandling = dateTimeKindHandling;
+    }
+
+    private string ReadElement()
+    {
+      _currentElementType = ReadType();
+      string elementName = ReadString();
+      return elementName;
+    }
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="T:Byte[]"/>.
+    /// </summary>
+    /// <returns>
+    /// A <see cref="T:Byte[]"/> or a null reference if the next JSON token is null. This method will return <c>null</c> at the end of an array.
+    /// </returns>
+    public override byte[] ReadAsBytes()
+    {
+      return ReadAsBytesInternal();
+    }
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="Nullable{Decimal}"/>.
+    /// </summary>
+    /// <returns>A <see cref="Nullable{Decimal}"/>. This method will return <c>null</c> at the end of an array.</returns>
+    public override decimal? ReadAsDecimal()
+    {
+      return ReadAsDecimalInternal();
+    }
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="Nullable{Int32}"/>.
+    /// </summary>
+    /// <returns>A <see cref="Nullable{Int32}"/>. This method will return <c>null</c> at the end of an array.</returns>
+    public override int? ReadAsInt32()
+    {
+      return ReadAsInt32Internal();
+    }
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="String"/>.
+    /// </summary>
+    /// <returns>A <see cref="String"/>. This method will return <c>null</c> at the end of an array.</returns>
+    public override string ReadAsString()
+    {
+      return ReadAsStringInternal();
+    }
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="Nullable{DateTime}"/>.
+    /// </summary>
+    /// <returns>A <see cref="String"/>. This method will return <c>null</c> at the end of an array.</returns>
+    public override DateTime? ReadAsDateTime()
+    {
+      return ReadAsDateTimeInternal();
+    }
+
+#if !NET20
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="Nullable{DateTimeOffset}"/>.
+    /// </summary>
+    /// <returns>
+    /// A <see cref="Nullable{DateTimeOffset}"/>. This method will return <c>null</c> at the end of an array.
+    /// </returns>
+    public override DateTimeOffset? ReadAsDateTimeOffset()
+    {
+      return ReadAsDateTimeOffsetInternal();
+    }
+#endif
+
+    /// <summary>
+    /// Reads the next JSON token from the stream.
+    /// </summary>
+    /// <returns>
+    /// true if the next token was read successfully; false if there are no more tokens to read.
+    /// </returns>
+    public override bool Read()
+    {
+      _readType = Json.ReadType.Read;
+
+      return ReadInternal();
+    }
+
+    internal override bool ReadInternal()
+    {
+      try
+      {
+        bool success;
+
+        switch (_bsonReaderState)
+        {
+          case BsonReaderState.Normal:
+            success = ReadNormal();
+            break;
+          case BsonReaderState.ReferenceStart:
+          case BsonReaderState.ReferenceRef:
+          case BsonReaderState.ReferenceId:
+            success = ReadReference();
+            break;
+          case BsonReaderState.CodeWScopeStart:
+          case BsonReaderState.CodeWScopeCode:
+          case BsonReaderState.CodeWScopeScope:
+          case BsonReaderState.CodeWScopeScopeObject:
+          case BsonReaderState.CodeWScopeScopeEnd:
+            success = ReadCodeWScope();
+            break;
+          default:
+            throw JsonReaderException.Create(this, "Unexpected state: {0}".FormatWith(CultureInfo.InvariantCulture, _bsonReaderState));
+        }
+
+        if (!success)
+        {
+          SetToken(JsonToken.None);
+          return false;
+        }
+
+        return true;
+      }
+      catch (EndOfStreamException)
+      {
+        SetToken(JsonToken.None);
+        return false;
+      }
+    }
+
+    /// <summary>
+    /// Changes the <see cref="JsonReader.State"/> to Closed.
+    /// </summary>
+    public override void Close()
+    {
+      base.Close();
+
+      if (CloseInput && _reader != null)
+#if !(NETFX_CORE || PORTABLE)
+        _reader.Close();
+#else
+        _reader.Dispose();
+#endif
+    }
+
+    private bool ReadCodeWScope()
+    {
+      switch (_bsonReaderState)
+      {
+        case BsonReaderState.CodeWScopeStart:
+          SetToken(JsonToken.PropertyName, "$code");
+          _bsonReaderState = BsonReaderState.CodeWScopeCode;
+          return true;
+        case BsonReaderState.CodeWScopeCode:
+          // total CodeWScope size - not used
+          ReadInt32();
+
+          SetToken(JsonToken.String, ReadLengthString());
+          _bsonReaderState = BsonReaderState.CodeWScopeScope;
+          return true;
+        case BsonReaderState.CodeWScopeScope:
+          if (CurrentState == State.PostValue)
+          {
+            SetToken(JsonToken.PropertyName, "$scope");
+            return true;
+          }
+          else
+          {
+            SetToken(JsonToken.StartObject);
+            _bsonReaderState = BsonReaderState.CodeWScopeScopeObject;
+
+            ContainerContext newContext = new ContainerContext(BsonType.Object);
+            PushContext(newContext);
+            newContext.Length = ReadInt32();
+
+            return true;
+          }
+        case BsonReaderState.CodeWScopeScopeObject:
+          bool result = ReadNormal();
+          if (result && TokenType == JsonToken.EndObject)
+            _bsonReaderState = BsonReaderState.CodeWScopeScopeEnd;
+
+          return result;
+        case BsonReaderState.CodeWScopeScopeEnd:
+          SetToken(JsonToken.EndObject);
+          _bsonReaderState = BsonReaderState.Normal;
+          return true;
+        default:
+          throw new ArgumentOutOfRangeException();
+      }
+    }
+
+    private bool ReadReference()
+    {
+      switch (CurrentState)
+      {
+        case State.ObjectStart:
+          {
+            SetToken(JsonToken.PropertyName, "$ref");
+            _bsonReaderState = BsonReaderState.ReferenceRef;
+            return true;
+          }
+        case State.Property:
+          {
+            if (_bsonReaderState == BsonReaderState.ReferenceRef)
+            {
+              SetToken(JsonToken.String, ReadLengthString());
+              return true;
+            }
+            else if (_bsonReaderState == BsonReaderState.ReferenceId)
+            {
+              SetToken(JsonToken.Bytes, ReadBytes(12));
+              return true;
+            }
+            else
+            {
+              throw JsonReaderException.Create(this, "Unexpected state when reading BSON reference: " + _bsonReaderState);
+            }
+          }
+        case State.PostValue:
+          {
+            if (_bsonReaderState == BsonReaderState.ReferenceRef)
+            {
+              SetToken(JsonToken.PropertyName, "$id");
+              _bsonReaderState = BsonReaderState.ReferenceId;
+              return true;
+            }
+            else if (_bsonReaderState == BsonReaderState.ReferenceId)
+            {
+              SetToken(JsonToken.EndObject);
+              _bsonReaderState = BsonReaderState.Normal;
+              return true;
+            }
+            else
+            {
+              throw JsonReaderException.Create(this, "Unexpected state when reading BSON reference: " + _bsonReaderState);
+            }
+          }
+        default:
+          throw JsonReaderException.Create(this, "Unexpected state when reading BSON reference: " + CurrentState);
+      }
+    }
+
+    private bool ReadNormal()
+    {
+      switch (CurrentState)
+      {
+        case State.Start:
+          {
+            JsonToken token = (!_readRootValueAsArray) ? JsonToken.StartObject : JsonToken.StartArray;
+            BsonType type = (!_readRootValueAsArray) ? BsonType.Object : BsonType.Array;
+
+            SetToken(token);
+            ContainerContext newContext = new ContainerContext(type);
+            PushContext(newContext);
+            newContext.Length = ReadInt32();
+            return true;
+          }
+        case State.Complete:
+        case State.Closed:
+          return false;
+        case State.Property:
+          {
+            ReadType(_currentElementType);
+            return true;
+          }
+        case State.ObjectStart:
+        case State.ArrayStart:
+        case State.PostValue:
+          ContainerContext context = _currentContext;
+          if (context == null)
+            return false;
+
+          int lengthMinusEnd = context.Length - 1;
+
+          if (context.Position < lengthMinusEnd)
+          {
+            if (context.Type == BsonType.Array)
+            {
+              ReadElement();
+              ReadType(_currentElementType);
+              return true;
+            }
+            else
+            {
+              SetToken(JsonToken.PropertyName, ReadElement());
+              return true;
+            }
+          }
+          else if (context.Position == lengthMinusEnd)
+          {
+            if (ReadByte() != 0)
+              throw JsonReaderException.Create(this, "Unexpected end of object byte value.");
+
+            PopContext();
+            if (_currentContext != null)
+              MovePosition(context.Length);
+
+            JsonToken endToken = (context.Type == BsonType.Object) ? JsonToken.EndObject : JsonToken.EndArray;
+            SetToken(endToken);
+            return true;
+          }
+          else
+          {
+            throw JsonReaderException.Create(this, "Read past end of current container context.");
+          }
+        case State.ConstructorStart:
+          break;
+        case State.Constructor:
+          break;
+        case State.Error:
+          break;
+        case State.Finished:
+          break;
+        default:
+          throw new ArgumentOutOfRangeException();
+      }
+
+      return false;
+    }
+
+    private void PopContext()
+    {
+      _stack.RemoveAt(_stack.Count - 1);
+      if (_stack.Count == 0)
+        _currentContext = null;
+      else
+        _currentContext = _stack[_stack.Count - 1];
+    }
+
+    private void PushContext(ContainerContext newContext)
+    {
+      _stack.Add(newContext);
+      _currentContext = newContext;
+    }
+
+    private byte ReadByte()
+    {
+      MovePosition(1);
+      return _reader.ReadByte();
+    }
+
+    private void ReadType(BsonType type)
+    {
+      switch (type)
+      {
+        case BsonType.Number:
+          SetToken(JsonToken.Float, ReadDouble());
+          break;
+        case BsonType.String:
+        case BsonType.Symbol:
+          SetToken(JsonToken.String, ReadLengthString());
+          break;
+        case BsonType.Object:
+          {
+            SetToken(JsonToken.StartObject);
+
+            ContainerContext newContext = new ContainerContext(BsonType.Object);
+            PushContext(newContext);
+            newContext.Length = ReadInt32();
+            break;
+          }
+        case BsonType.Array:
+          {
+            SetToken(JsonToken.StartArray);
+
+            ContainerContext newContext = new ContainerContext(BsonType.Array);
+            PushContext(newContext);
+            newContext.Length = ReadInt32();
+            break;
+          }
+        case BsonType.Binary:
+          SetToken(JsonToken.Bytes, ReadBinary());
+          break;
+        case BsonType.Undefined:
+          SetToken(JsonToken.Undefined);
+          break;
+        case BsonType.Oid:
+          byte[] oid = ReadBytes(12);
+          SetToken(JsonToken.Bytes, oid);
+          break;
+        case BsonType.Boolean:
+          bool b = Convert.ToBoolean(ReadByte());
+          SetToken(JsonToken.Boolean, b);
+          break;
+        case BsonType.Date:
+          long ticks = ReadInt64();
+          DateTime utcDateTime = JsonConvert.ConvertJavaScriptTicksToDateTime(ticks);
+
+          DateTime dateTime;
+          switch (DateTimeKindHandling)
+          {
+            case DateTimeKind.Unspecified:
+              dateTime = DateTime.SpecifyKind(utcDateTime, DateTimeKind.Unspecified);
+              break;
+            case DateTimeKind.Local:
+              dateTime = utcDateTime.ToLocalTime();
+              break;
+            default:
+              dateTime = utcDateTime;
+              break;
+          }
+
+          SetToken(JsonToken.Date, dateTime);
+          break;
+        case BsonType.Null:
+          SetToken(JsonToken.Null);
+          break;
+        case BsonType.Regex:
+          string expression = ReadString();
+          string modifiers = ReadString();
+
+          string regex = @"/" + expression + @"/" + modifiers;
+          SetToken(JsonToken.String, regex);
+          break;
+        case BsonType.Reference:
+          SetToken(JsonToken.StartObject);
+          _bsonReaderState = BsonReaderState.ReferenceStart;
+          break;
+        case BsonType.Code:
+          SetToken(JsonToken.String, ReadLengthString());
+          break;
+        case BsonType.CodeWScope:
+          SetToken(JsonToken.StartObject);
+          _bsonReaderState = BsonReaderState.CodeWScopeStart;
+          break;
+        case BsonType.Integer:
+          SetToken(JsonToken.Integer, (long) ReadInt32());
+          break;
+        case BsonType.TimeStamp:
+        case BsonType.Long:
+          SetToken(JsonToken.Integer, ReadInt64());
+          break;
+        default:
+          throw new ArgumentOutOfRangeException("type", "Unexpected BsonType value: " + type);
+      }
+    }
+
+    private byte[] ReadBinary()
+    {
+      int dataLength = ReadInt32();
+
+      BsonBinaryType binaryType = (BsonBinaryType) ReadByte();
+
+#pragma warning disable 612,618
+      // the old binary type has the data length repeated in the data for some reason
+      if (binaryType == BsonBinaryType.Data && !_jsonNet35BinaryCompatibility)
+      {
+        dataLength = ReadInt32();
+      }
+#pragma warning restore 612,618
+
+      return ReadBytes(dataLength);
+    }
+
+    private string ReadString()
+    {
+      EnsureBuffers();
+
+      StringBuilder builder = null;
+
+      int totalBytesRead = 0;
+      // used in case of left over multibyte characters in the buffer
+      int offset = 0;
+      do
+      {
+        int count = offset;
+        byte b;
+        while (count < MaxCharBytesSize && (b = _reader.ReadByte()) > 0)
+        {
+          _byteBuffer[count++] = b;
+        }
+        int byteCount = count - offset;
+        totalBytesRead += byteCount;
+
+        if (count < MaxCharBytesSize && builder == null)
+        {
+          // pref optimization to avoid reading into a string builder
+          // if string is smaller than the buffer then return it directly
+          int length = Encoding.UTF8.GetChars(_byteBuffer, 0, byteCount, _charBuffer, 0);
+
+          MovePosition(totalBytesRead + 1);
+          return new string(_charBuffer, 0, length);
+        }
+        else
+        {
+          // calculate the index of the end of the last full character in the buffer
+          int lastFullCharStop = GetLastFullCharStop(count - 1);
+
+          int charCount = Encoding.UTF8.GetChars(_byteBuffer, 0, lastFullCharStop + 1, _charBuffer, 0);
+
+          if (builder == null)
+            builder = new StringBuilder(MaxCharBytesSize*2);
+
+          builder.Append(_charBuffer, 0, charCount);
+
+          if (lastFullCharStop < byteCount - 1)
+          {
+            offset = byteCount - lastFullCharStop - 1;
+            // copy left over multi byte characters to beginning of buffer for next iteration
+            Array.Copy(_byteBuffer, lastFullCharStop + 1, _byteBuffer, 0, offset);
+          }
+          else
+          {
+            // reached end of string
+            if (count < MaxCharBytesSize)
+            {
+              MovePosition(totalBytesRead + 1);
+              return builder.ToString();
+            }
+
+            offset = 0;
+          }
+        }
+      } while (true);
+    }
+
+    private string ReadLengthString()
+    {
+      int length = ReadInt32();
+
+      MovePosition(length);
+
+      string s = GetString(length - 1);
+      _reader.ReadByte();
+
+      return s;
+    }
+
+    private string GetString(int length)
+    {
+      if (length == 0)
+        return string.Empty;
+
+      EnsureBuffers();
+
+      StringBuilder builder = null;
+
+      int totalBytesRead = 0;
+
+      // used in case of left over multibyte characters in the buffer
+      int offset = 0;
+      do
+      {
+        int count = ((length - totalBytesRead) > MaxCharBytesSize - offset)
+                      ? MaxCharBytesSize - offset
+                      : length - totalBytesRead;
+
+        int byteCount = _reader.Read(_byteBuffer, offset, count);
+
+        if (byteCount == 0)
+          throw new EndOfStreamException("Unable to read beyond the end of the stream.");
+
+        totalBytesRead += byteCount;
+
+        // Above, byteCount is how many bytes we read this time.
+        // Below, byteCount is how many bytes are in the _byteBuffer.
+        byteCount += offset;
+
+        if (byteCount == length)
+        {
+          // pref optimization to avoid reading into a string builder
+          // first iteration and all bytes read then return string directly
+          int charCount = Encoding.UTF8.GetChars(_byteBuffer, 0, byteCount, _charBuffer, 0);
+          return new string(_charBuffer, 0, charCount);
+        }
+        else
+        {
+          int lastFullCharStop = GetLastFullCharStop(byteCount - 1);
+
+          if (builder == null)
+            builder = new StringBuilder(length);
+
+          int charCount = Encoding.UTF8.GetChars(_byteBuffer, 0, lastFullCharStop + 1, _charBuffer, 0);
+          builder.Append(_charBuffer, 0, charCount);
+
+          if (lastFullCharStop < byteCount - 1)
+          {
+            offset = byteCount - lastFullCharStop - 1;
+            // copy left over multi byte characters to beginning of buffer for next iteration
+            Array.Copy(_byteBuffer, lastFullCharStop + 1, _byteBuffer, 0, offset);
+          }
+          else
+          {
+            offset = 0;
+          }
+        }
+      } while (totalBytesRead < length);
+
+      return builder.ToString();
+    }
+
+    private int GetLastFullCharStop(int start)
+    {
+      int lookbackPos = start;
+      int bis = 0;
+      while (lookbackPos >= 0)
+      {
+        bis = BytesInSequence(_byteBuffer[lookbackPos]);
+        if (bis == 0)
+        {
+          lookbackPos--;
+          continue;
+        }
+        else if (bis == 1)
+        {
+          break;
+        }
+        else
+        {
+          lookbackPos--;
+          break;
+        }
+      }
+      if (bis == start - lookbackPos)
+      {
+        //Full character.
+        return start;
+      }
+      else
+      {
+        return lookbackPos;
+      }
+    }
+
+    private int BytesInSequence(byte b)
+    {
+      if (b <= SeqRange1[1]) return 1;
+      if (b >= SeqRange2[0] && b <= SeqRange2[1]) return 2;
+      if (b >= SeqRange3[0] && b <= SeqRange3[1]) return 3;
+      if (b >= SeqRange4[0] && b <= SeqRange4[1]) return 4;
+      return 0;
+    }
+
+    private void EnsureBuffers()
+    {
+      if (_byteBuffer == null)
+      {
+        _byteBuffer = new byte[MaxCharBytesSize];
+      }
+      if (_charBuffer == null)
+      {
+        int charBufferSize = Encoding.UTF8.GetMaxCharCount(MaxCharBytesSize);
+        _charBuffer = new char[charBufferSize];
+      }
+    }
+
+    private double ReadDouble()
+    {
+      MovePosition(8);
+      return _reader.ReadDouble();
+    }
+
+    private int ReadInt32()
+    {
+      MovePosition(4);
+      return _reader.ReadInt32();
+    }
+
+    private long ReadInt64()
+    {
+      MovePosition(8);
+      return _reader.ReadInt64();
+    }
+
+    private BsonType ReadType()
+    {
+      MovePosition(1);
+      return (BsonType) _reader.ReadSByte();
+    }
+
+    private void MovePosition(int count)
+    {
+      _currentContext.Position += count;
+    }
+
+    private byte[] ReadBytes(int count)
+    {
+      MovePosition(count);
+      return _reader.ReadBytes(count);
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonToken.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonToken.cs
index ff4b21d..97a98ae 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonToken.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonToken.cs
@@ -1,121 +1,146 @@
-using System.Collections;
-using System.Collections.Generic;
-
-namespace Newtonsoft.Json.Bson
-{
-  internal abstract class BsonToken
-  {
-    public abstract BsonType Type { get; }
-    public BsonToken Parent { get; set; }
-    public int CalculatedSize { get; set; }
-  }
-
-  internal class BsonObject : BsonToken, IEnumerable<BsonProperty>
-  {
-    private readonly List<BsonProperty> _children = new List<BsonProperty>();
-
-    public void Add(string name, BsonToken token)
-    {
-      _children.Add(new BsonProperty { Name = new BsonString(name, false), Value = token });
-      token.Parent = this;
-    }
-
-    public override BsonType Type
-    {
-      get { return BsonType.Object; }
-    }
-
-    public IEnumerator<BsonProperty> GetEnumerator()
-    {
-      return _children.GetEnumerator();
-    }
-
-    IEnumerator IEnumerable.GetEnumerator()
-    {
-      return GetEnumerator();
-    }
-  }
-
-  internal class BsonArray : BsonToken, IEnumerable<BsonToken>
-  {
-    private readonly List<BsonToken> _children = new List<BsonToken>();
-
-    public void Add(BsonToken token)
-    {
-      _children.Add(token);
-      token.Parent = this;
-    }
-
-    public override BsonType Type
-    {
-      get { return BsonType.Array; }
-    }
-
-    public IEnumerator<BsonToken> GetEnumerator()
-    {
-      return _children.GetEnumerator();
-    }
-
-    IEnumerator IEnumerable.GetEnumerator()
-    {
-      return GetEnumerator();
-    }
-  }
-
-  internal class BsonValue : BsonToken
-  {
-    private object _value;
-    private BsonType _type;
-
-    public BsonValue(object value, BsonType type)
-    {
-      _value = value;
-      _type = type;
-    }
-
-    public object Value
-    {
-      get { return _value; }
-    }
-
-    public override BsonType Type
-    {
-      get { return _type; }
-    }
-  }
-
-  internal class BsonString : BsonValue
-  {
-    public int ByteCount { get; set; }
-    public bool IncludeLength { get; set; }
-
-    public BsonString(object value, bool includeLength)
-      : base(value, BsonType.String)
-    {
-      IncludeLength = includeLength;
-    }
-  }
-
-  internal class BsonRegex : BsonToken
-  {
-    public BsonString Pattern { get; set; }
-    public BsonString Options { get; set; }
-
-    public BsonRegex(string pattern, string options)
-    {
-      Pattern = new BsonString(pattern, false);
-      Options = new BsonString(options, false);
-    }
-
-    public override BsonType Type
-    {
-      get { return BsonType.Regex; }
-    }
-  }
-
-  internal class BsonProperty
-  {
-    public BsonString Name { get; set; }
-    public BsonToken Value { get; set; }
-  }
+#region License
+// 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.
+#endregion
+
+using System.Collections;
+using System.Collections.Generic;
+
+namespace Newtonsoft.Json.Bson
+{
+  internal abstract class BsonToken
+  {
+    public abstract BsonType Type { get; }
+    public BsonToken Parent { get; set; }
+    public int CalculatedSize { get; set; }
+  }
+
+  internal class BsonObject : BsonToken, IEnumerable<BsonProperty>
+  {
+    private readonly List<BsonProperty> _children = new List<BsonProperty>();
+
+    public void Add(string name, BsonToken token)
+    {
+      _children.Add(new BsonProperty { Name = new BsonString(name, false), Value = token });
+      token.Parent = this;
+    }
+
+    public override BsonType Type
+    {
+      get { return BsonType.Object; }
+    }
+
+    public IEnumerator<BsonProperty> GetEnumerator()
+    {
+      return _children.GetEnumerator();
+    }
+
+    IEnumerator IEnumerable.GetEnumerator()
+    {
+      return GetEnumerator();
+    }
+  }
+
+  internal class BsonArray : BsonToken, IEnumerable<BsonToken>
+  {
+    private readonly List<BsonToken> _children = new List<BsonToken>();
+
+    public void Add(BsonToken token)
+    {
+      _children.Add(token);
+      token.Parent = this;
+    }
+
+    public override BsonType Type
+    {
+      get { return BsonType.Array; }
+    }
+
+    public IEnumerator<BsonToken> GetEnumerator()
+    {
+      return _children.GetEnumerator();
+    }
+
+    IEnumerator IEnumerable.GetEnumerator()
+    {
+      return GetEnumerator();
+    }
+  }
+
+  internal class BsonValue : BsonToken
+  {
+    private readonly object _value;
+    private readonly BsonType _type;
+
+    public BsonValue(object value, BsonType type)
+    {
+      _value = value;
+      _type = type;
+    }
+
+    public object Value
+    {
+      get { return _value; }
+    }
+
+    public override BsonType Type
+    {
+      get { return _type; }
+    }
+  }
+
+  internal class BsonString : BsonValue
+  {
+    public int ByteCount { get; set; }
+    public bool IncludeLength { get; set; }
+
+    public BsonString(object value, bool includeLength)
+      : base(value, BsonType.String)
+    {
+      IncludeLength = includeLength;
+    }
+  }
+
+  internal class BsonRegex : BsonToken
+  {
+    public BsonString Pattern { get; set; }
+    public BsonString Options { get; set; }
+
+    public BsonRegex(string pattern, string options)
+    {
+      Pattern = new BsonString(pattern, false);
+      Options = new BsonString(options, false);
+    }
+
+    public override BsonType Type
+    {
+      get { return BsonType.Regex; }
+    }
+  }
+
+  internal class BsonProperty
+  {
+    public BsonString Name { get; set; }
+    public BsonToken Value { get; set; }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonType.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonType.cs
index 7b6def2..f4e1214 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonType.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonType.cs
@@ -1,51 +1,51 @@
-#region License
-// 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.
-#endregion
-
-namespace Newtonsoft.Json.Bson
-{
-  internal enum BsonType : sbyte 
-  {
-    Number = 1,
-    String = 2,
-    Object = 3,
-    Array = 4,
-    Binary = 5,
-    Undefined = 6,
-    Oid = 7,
-    Boolean = 8,
-    Date = 9,
-    Null = 10,
-    Regex = 11,
-    Reference = 12,
-    Code = 13,
-    Symbol = 14,
-    CodeWScope = 15,
-    Integer = 16,
-    TimeStamp = 17,
-    Long = 18,
-    MinKey = -1,
-    MaxKey = 127
-  }
+#region License
+// 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.
+#endregion
+
+namespace Newtonsoft.Json.Bson
+{
+  internal enum BsonType : sbyte 
+  {
+    Number = 1,
+    String = 2,
+    Object = 3,
+    Array = 4,
+    Binary = 5,
+    Undefined = 6,
+    Oid = 7,
+    Boolean = 8,
+    Date = 9,
+    Null = 10,
+    Regex = 11,
+    Reference = 12,
+    Code = 13,
+    Symbol = 14,
+    CodeWScope = 15,
+    Integer = 16,
+    TimeStamp = 17,
+    Long = 18,
+    MinKey = -1,
+    MaxKey = 127
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonWriter.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonWriter.cs
index d3a380e..02b2e7f 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonWriter.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonWriter.cs
@@ -1,431 +1,494 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-using Newtonsoft.Json.Utilities;
-using Newtonsoft.Json.Linq;
-using System.Globalization;
-
-namespace Newtonsoft.Json.Bson
-{
-  /// <summary>
-  /// Represents a writer that provides a fast, non-cached, forward-only way of generating Json data.
-  /// </summary>
-  public class BsonWriter : JsonWriter
-  {
-    private readonly BsonBinaryWriter _writer;
-
-    private BsonToken _root;
-    private BsonToken _parent;
-    private string _propertyName;
-
-    /// <summary>
-    /// Gets or sets the <see cref="DateTimeKind" /> used when writing <see cref="DateTime"/> values to BSON.
-    /// When set to <see cref="DateTimeKind.Unspecified" /> no conversion will occur.
-    /// </summary>
-    /// <value>The <see cref="DateTimeKind" /> used when writing <see cref="DateTime"/> values to BSON.</value>
-    public DateTimeKind DateTimeKindHandling
-    {
-      get { return _writer.DateTimeKindHandling; }
-      set { _writer.DateTimeKindHandling = value; }
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="BsonWriter"/> class.
-    /// </summary>
-    /// <param name="stream">The stream.</param>
-    public BsonWriter(Stream stream)
-    {
-      ValidationUtils.ArgumentNotNull(stream, "stream");
-      _writer = new BsonBinaryWriter(stream);
-    }
-
-    /// <summary>
-    /// Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream.
-    /// </summary>
-    public override void Flush()
-    {
-      _writer.Flush();
-    }
-
-    /// <summary>
-    /// Writes the end.
-    /// </summary>
-    /// <param name="token">The token.</param>
-    protected override void WriteEnd(JsonToken token)
-    {
-      base.WriteEnd(token);
-      RemoveParent();
-
-      if (Top == 0)
-      {
-        _writer.WriteToken(_root);
-      }
-    }
-
-    /// <summary>
-    /// Writes out a comment <code>/*...*/</code> containing the specified text.
-    /// </summary>
-    /// <param name="text">Text to place inside the comment.</param>
-    public override void WriteComment(string text)
-    {
-      throw new JsonWriterException("Cannot write JSON comment as BSON.");
-    }
-
-    /// <summary>
-    /// Writes the start of a constructor with the given name.
-    /// </summary>
-    /// <param name="name">The name of the constructor.</param>
-    public override void WriteStartConstructor(string name)
-    {
-      throw new JsonWriterException("Cannot write JSON constructor as BSON.");
-    }
-
-    /// <summary>
-    /// Writes raw JSON.
-    /// </summary>
-    /// <param name="json">The raw JSON to write.</param>
-    public override void WriteRaw(string json)
-    {
-      throw new JsonWriterException("Cannot write raw JSON as BSON.");
-    }
-
-    /// <summary>
-    /// Writes raw JSON where a value is expected and updates the writer's state.
-    /// </summary>
-    /// <param name="json">The raw JSON to write.</param>
-    public override void WriteRawValue(string json)
-    {
-      throw new JsonWriterException("Cannot write raw JSON as BSON.");
-    }
-
-    /// <summary>
-    /// Writes the beginning of a Json array.
-    /// </summary>
-    public override void WriteStartArray()
-    {
-      base.WriteStartArray();
-
-      AddParent(new BsonArray());
-    }
-
-    /// <summary>
-    /// Writes the beginning of a Json object.
-    /// </summary>
-    public override void WriteStartObject()
-    {
-      base.WriteStartObject();
-
-      AddParent(new BsonObject());
-    }
-
-    /// <summary>
-    /// Writes the property name of a name/value pair on a Json object.
-    /// </summary>
-    /// <param name="name">The name of the property.</param>
-    public override void WritePropertyName(string name)
-    {
-      base.WritePropertyName(name);
-
-      _propertyName = name;
-    }
-
-    private void AddParent(BsonToken container)
-    {
-      AddToken(container);
-      _parent = container;
-    }
-
-    private void RemoveParent()
-    {
-      _parent = _parent.Parent;
-    }
-
-    private void AddValue(object value, BsonType type)
-    {
-      AddToken(new BsonValue(value, type));
-    }
-
-    internal void AddToken(BsonToken token)
-    {
-      if (_parent != null)
-      {
-        if (_parent is BsonObject)
-        {
-          ((BsonObject)_parent).Add(_propertyName, token);
-          _propertyName = null;
-        }
-        else
-        {
-          ((BsonArray)_parent).Add(token);
-        }
-      }
-      else
-      {
-        _parent = token;
-        _root = token;
-      }
-    }
-
-    #region WriteValue methods
-    /// <summary>
-    /// Writes a null value.
-    /// </summary>
-    public override void WriteNull()
-    {
-      base.WriteNull();
-      AddValue(null, BsonType.Null);
-    }
-
-    /// <summary>
-    /// Writes an undefined value.
-    /// </summary>
-    public override void WriteUndefined()
-    {
-      base.WriteUndefined();
-      AddValue(null, BsonType.Undefined);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="String"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="String"/> value to write.</param>
-    public override void WriteValue(string value)
-    {
-      base.WriteValue(value);
-      if (value == null)
-        AddValue(null, BsonType.Null);
-      else
-        AddToken(new BsonString(value, true));
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Int32"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Int32"/> value to write.</param>
-    public override void WriteValue(int value)
-    {
-      base.WriteValue(value);
-      AddValue(value, BsonType.Integer);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="UInt32"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="UInt32"/> value to write.</param>
-    [CLSCompliant(false)]
-    public override void WriteValue(uint value)
-    {
-      if (value > int.MaxValue)
-        throw new JsonWriterException("Value is too large to fit in a signed 32 bit integer. BSON does not support unsigned values.");
-
-      base.WriteValue(value);
-      AddValue(value, BsonType.Integer);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Int64"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Int64"/> value to write.</param>
-    public override void WriteValue(long value)
-    {
-      base.WriteValue(value);
-      AddValue(value, BsonType.Long);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="UInt64"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="UInt64"/> value to write.</param>
-    [CLSCompliant(false)]
-    public override void WriteValue(ulong value)
-    {
-      if (value > long.MaxValue)
-        throw new JsonWriterException("Value is too large to fit in a signed 64 bit integer. BSON does not support unsigned values.");
-
-      base.WriteValue(value);
-      AddValue(value, BsonType.Long);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Single"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Single"/> value to write.</param>
-    public override void WriteValue(float value)
-    {
-      base.WriteValue(value);
-      AddValue(value, BsonType.Number);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Double"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Double"/> value to write.</param>
-    public override void WriteValue(double value)
-    {
-      base.WriteValue(value);
-      AddValue(value, BsonType.Number);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Boolean"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Boolean"/> value to write.</param>
-    public override void WriteValue(bool value)
-    {
-      base.WriteValue(value);
-      AddValue(value, BsonType.Boolean);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Int16"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Int16"/> value to write.</param>
-    public override void WriteValue(short value)
-    {
-      base.WriteValue(value);
-      AddValue(value, BsonType.Integer);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="UInt16"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="UInt16"/> value to write.</param>
-    [CLSCompliant(false)]
-    public override void WriteValue(ushort value)
-    {
-      base.WriteValue(value);
-      AddValue(value, BsonType.Integer);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Char"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Char"/> value to write.</param>
-    public override void WriteValue(char value)
-    {
-      base.WriteValue(value);
-      AddToken(new BsonString(value.ToString(), true));
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Byte"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Byte"/> value to write.</param>
-    public override void WriteValue(byte value)
-    {
-      base.WriteValue(value);
-      AddValue(value, BsonType.Integer);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="SByte"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="SByte"/> value to write.</param>
-    [CLSCompliant(false)]
-    public override void WriteValue(sbyte value)
-    {
-      base.WriteValue(value);
-      AddValue(value, BsonType.Integer);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Decimal"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Decimal"/> value to write.</param>
-    public override void WriteValue(decimal value)
-    {
-      base.WriteValue(value);
-      AddValue(value, BsonType.Number);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="DateTime"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="DateTime"/> value to write.</param>
-    public override void WriteValue(DateTime value)
-    {
-      base.WriteValue(value);
-      AddValue(value, BsonType.Date);
-    }
-
-#if !PocketPC && !NET20
-    /// <summary>
-    /// Writes a <see cref="DateTimeOffset"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="DateTimeOffset"/> value to write.</param>
-    public override void WriteValue(DateTimeOffset value)
-    {
-      base.WriteValue(value);
-      AddValue(value, BsonType.Date);
-    }
-#endif
-
-    /// <summary>
-    /// Writes a <see cref="T:Byte[]"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="T:Byte[]"/> value to write.</param>
-    public override void WriteValue(byte[] value)
-    {
-      base.WriteValue(value);
-      AddValue(value, BsonType.Binary);
-    }
-    #endregion
-
-    /// <summary>
-    /// Writes a <see cref="T:Byte[]"/> value that represents a BSON object id.
-    /// </summary>
-    /// <param name="value"></param>
-    public void WriteObjectId(byte[] value)
-    {
-      ValidationUtils.ArgumentNotNull(value, "value");
-
-      if (value.Length != 12)
-        throw new Exception("An object id must be 12 bytes");
-
-      // hack to update the writer state
-      AutoComplete(JsonToken.Undefined);
-      AddValue(value, BsonType.Oid);
-    }
-
-    /// <summary>
-    /// Writes a BSON regex.
-    /// </summary>
-    /// <param name="pattern">The regex pattern.</param>
-    /// <param name="options">The regex options.</param>
-    public void WriteRegex(string pattern, string options)
-    {
-      ValidationUtils.ArgumentNotNull(pattern, "pattern");
-
-      // hack to update the writer state
-      AutoComplete(JsonToken.Undefined);
-      AddToken(new BsonRegex(pattern, options));
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using Newtonsoft.Json.Utilities;
+using Newtonsoft.Json.Linq;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Bson
+{
+  /// <summary>
+  /// Represents a writer that provides a fast, non-cached, forward-only way of generating Json data.
+  /// </summary>
+  public class BsonWriter : JsonWriter
+  {
+    private readonly BsonBinaryWriter _writer;
+
+    private BsonToken _root;
+    private BsonToken _parent;
+    private string _propertyName;
+
+    /// <summary>
+    /// Gets or sets the <see cref="DateTimeKind" /> used when writing <see cref="DateTime"/> values to BSON.
+    /// When set to <see cref="DateTimeKind.Unspecified" /> no conversion will occur.
+    /// </summary>
+    /// <value>The <see cref="DateTimeKind" /> used when writing <see cref="DateTime"/> values to BSON.</value>
+    public DateTimeKind DateTimeKindHandling
+    {
+      get { return _writer.DateTimeKindHandling; }
+      set { _writer.DateTimeKindHandling = value; }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="BsonWriter"/> class.
+    /// </summary>
+    /// <param name="stream">The stream.</param>
+    public BsonWriter(Stream stream)
+    {
+      ValidationUtils.ArgumentNotNull(stream, "stream");
+      _writer = new BsonBinaryWriter(new BinaryWriter(stream));
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="BsonWriter"/> class.
+    /// </summary>
+    /// <param name="writer">The writer.</param>
+    public BsonWriter(BinaryWriter writer)
+    {
+      ValidationUtils.ArgumentNotNull(writer, "writer");
+      _writer = new BsonBinaryWriter(writer);
+    }
+
+    /// <summary>
+    /// Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream.
+    /// </summary>
+    public override void Flush()
+    {
+      _writer.Flush();
+    }
+
+    /// <summary>
+    /// Writes the end.
+    /// </summary>
+    /// <param name="token">The token.</param>
+    protected override void WriteEnd(JsonToken token)
+    {
+      base.WriteEnd(token);
+      RemoveParent();
+
+      if (Top == 0)
+      {
+        _writer.WriteToken(_root);
+      }
+    }
+
+    /// <summary>
+    /// Writes out a comment <code>/*...*/</code> containing the specified text.
+    /// </summary>
+    /// <param name="text">Text to place inside the comment.</param>
+    public override void WriteComment(string text)
+    {
+      throw JsonWriterException.Create(this, "Cannot write JSON comment as BSON.", null);
+    }
+
+    /// <summary>
+    /// Writes the start of a constructor with the given name.
+    /// </summary>
+    /// <param name="name">The name of the constructor.</param>
+    public override void WriteStartConstructor(string name)
+    {
+      throw JsonWriterException.Create(this, "Cannot write JSON constructor as BSON.", null);
+    }
+
+    /// <summary>
+    /// Writes raw JSON.
+    /// </summary>
+    /// <param name="json">The raw JSON to write.</param>
+    public override void WriteRaw(string json)
+    {
+      throw JsonWriterException.Create(this, "Cannot write raw JSON as BSON.", null);
+    }
+
+    /// <summary>
+    /// Writes raw JSON where a value is expected and updates the writer's state.
+    /// </summary>
+    /// <param name="json">The raw JSON to write.</param>
+    public override void WriteRawValue(string json)
+    {
+      throw JsonWriterException.Create(this, "Cannot write raw JSON as BSON.", null);
+    }
+
+    /// <summary>
+    /// Writes the beginning of a Json array.
+    /// </summary>
+    public override void WriteStartArray()
+    {
+      base.WriteStartArray();
+
+      AddParent(new BsonArray());
+    }
+
+    /// <summary>
+    /// Writes the beginning of a Json object.
+    /// </summary>
+    public override void WriteStartObject()
+    {
+      base.WriteStartObject();
+
+      AddParent(new BsonObject());
+    }
+
+    /// <summary>
+    /// Writes the property name of a name/value pair on a Json object.
+    /// </summary>
+    /// <param name="name">The name of the property.</param>
+    public override void WritePropertyName(string name)
+    {
+      base.WritePropertyName(name);
+
+      _propertyName = name;
+    }
+
+    /// <summary>
+    /// Closes this stream and the underlying stream.
+    /// </summary>
+    public override void Close()
+    {
+      base.Close();
+
+      if (CloseOutput && _writer != null)
+        _writer.Close();
+    }
+
+    private void AddParent(BsonToken container)
+    {
+      AddToken(container);
+      _parent = container;
+    }
+
+    private void RemoveParent()
+    {
+      _parent = _parent.Parent;
+    }
+
+    private void AddValue(object value, BsonType type)
+    {
+      AddToken(new BsonValue(value, type));
+    }
+
+    internal void AddToken(BsonToken token)
+    {
+      if (_parent != null)
+      {
+        if (_parent is BsonObject)
+        {
+          ((BsonObject) _parent).Add(_propertyName, token);
+          _propertyName = null;
+        }
+        else
+        {
+          ((BsonArray) _parent).Add(token);
+        }
+      }
+      else
+      {
+        if (token.Type != BsonType.Object && token.Type != BsonType.Array)
+          throw JsonWriterException.Create(this, "Error writing {0} value. BSON must start with an Object or Array.".FormatWith(CultureInfo.InvariantCulture, token.Type), null);
+
+        _parent = token;
+        _root = token;
+      }
+    }
+
+    #region WriteValue methods
+
+    /// <summary>
+    /// Writes a null value.
+    /// </summary>
+    public override void WriteNull()
+    {
+      base.WriteNull();
+      AddValue(null, BsonType.Null);
+    }
+
+    /// <summary>
+    /// Writes an undefined value.
+    /// </summary>
+    public override void WriteUndefined()
+    {
+      base.WriteUndefined();
+      AddValue(null, BsonType.Undefined);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="String"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="String"/> value to write.</param>
+    public override void WriteValue(string value)
+    {
+      base.WriteValue(value);
+      if (value == null)
+        AddValue(null, BsonType.Null);
+      else
+        AddToken(new BsonString(value, true));
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Int32"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Int32"/> value to write.</param>
+    public override void WriteValue(int value)
+    {
+      base.WriteValue(value);
+      AddValue(value, BsonType.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="UInt32"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="UInt32"/> value to write.</param>
+    [CLSCompliant(false)]
+    public override void WriteValue(uint value)
+    {
+      if (value > int.MaxValue)
+        throw JsonWriterException.Create(this, "Value is too large to fit in a signed 32 bit integer. BSON does not support unsigned values.", null);
+
+      base.WriteValue(value);
+      AddValue(value, BsonType.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Int64"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Int64"/> value to write.</param>
+    public override void WriteValue(long value)
+    {
+      base.WriteValue(value);
+      AddValue(value, BsonType.Long);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="UInt64"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="UInt64"/> value to write.</param>
+    [CLSCompliant(false)]
+    public override void WriteValue(ulong value)
+    {
+      if (value > long.MaxValue)
+        throw JsonWriterException.Create(this, "Value is too large to fit in a signed 64 bit integer. BSON does not support unsigned values.", null);
+
+      base.WriteValue(value);
+      AddValue(value, BsonType.Long);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Single"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Single"/> value to write.</param>
+    public override void WriteValue(float value)
+    {
+      base.WriteValue(value);
+      AddValue(value, BsonType.Number);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Double"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Double"/> value to write.</param>
+    public override void WriteValue(double value)
+    {
+      base.WriteValue(value);
+      AddValue(value, BsonType.Number);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Boolean"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Boolean"/> value to write.</param>
+    public override void WriteValue(bool value)
+    {
+      base.WriteValue(value);
+      AddValue(value, BsonType.Boolean);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Int16"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Int16"/> value to write.</param>
+    public override void WriteValue(short value)
+    {
+      base.WriteValue(value);
+      AddValue(value, BsonType.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="UInt16"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="UInt16"/> value to write.</param>
+    [CLSCompliant(false)]
+    public override void WriteValue(ushort value)
+    {
+      base.WriteValue(value);
+      AddValue(value, BsonType.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Char"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Char"/> value to write.</param>
+    public override void WriteValue(char value)
+    {
+      base.WriteValue(value);
+      string s = null;
+#if !(NETFX_CORE || PORTABLE)
+      s = value.ToString(CultureInfo.InvariantCulture);
+#else
+      s = value.ToString();
+#endif
+      AddToken(new BsonString(s, true));
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Byte"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Byte"/> value to write.</param>
+    public override void WriteValue(byte value)
+    {
+      base.WriteValue(value);
+      AddValue(value, BsonType.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="SByte"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="SByte"/> value to write.</param>
+    [CLSCompliant(false)]
+    public override void WriteValue(sbyte value)
+    {
+      base.WriteValue(value);
+      AddValue(value, BsonType.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Decimal"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Decimal"/> value to write.</param>
+    public override void WriteValue(decimal value)
+    {
+      base.WriteValue(value);
+      AddValue(value, BsonType.Number);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="DateTime"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="DateTime"/> value to write.</param>
+    public override void WriteValue(DateTime value)
+    {
+      base.WriteValue(value);
+      value = JsonConvert.EnsureDateTime(value, DateTimeZoneHandling);
+      AddValue(value, BsonType.Date);
+    }
+
+#if !PocketPC && !NET20
+    /// <summary>
+    /// Writes a <see cref="DateTimeOffset"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="DateTimeOffset"/> value to write.</param>
+    public override void WriteValue(DateTimeOffset value)
+    {
+      base.WriteValue(value);
+      AddValue(value, BsonType.Date);
+    }
+#endif
+
+    /// <summary>
+    /// Writes a <see cref="T:Byte[]"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="T:Byte[]"/> value to write.</param>
+    public override void WriteValue(byte[] value)
+    {
+      base.WriteValue(value);
+      AddValue(value, BsonType.Binary);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Guid"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Guid"/> value to write.</param>
+    public override void WriteValue(Guid value)
+    {
+      base.WriteValue(value);
+      AddToken(new BsonString(value.ToString(), true));
+    }
+
+    /// <summary>
+    /// Writes a <see cref="TimeSpan"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="TimeSpan"/> value to write.</param>
+    public override void WriteValue(TimeSpan value)
+    {
+      base.WriteValue(value);
+      AddToken(new BsonString(value.ToString(), true));
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Uri"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Uri"/> value to write.</param>
+    public override void WriteValue(Uri value)
+    {
+      base.WriteValue(value);
+      AddToken(new BsonString(value.ToString(), true));
+    }
+
+    #endregion
+
+    /// <summary>
+    /// Writes a <see cref="T:Byte[]"/> value that represents a BSON object id.
+    /// </summary>
+    /// <param name="value">The Object ID value to write.</param>
+    public void WriteObjectId(byte[] value)
+    {
+      ValidationUtils.ArgumentNotNull(value, "value");
+
+      if (value.Length != 12)
+        throw JsonWriterException.Create(this, "An object id must be 12 bytes", null);
+
+      // hack to update the writer state
+      AutoComplete(JsonToken.Undefined);
+      AddValue(value, BsonType.Oid);
+    }
+
+    /// <summary>
+    /// Writes a BSON regex.
+    /// </summary>
+    /// <param name="pattern">The regex pattern.</param>
+    /// <param name="options">The regex options.</param>
+    public void WriteRegex(string pattern, string options)
+    {
+      ValidationUtils.ArgumentNotNull(pattern, "pattern");
+
+      // hack to update the writer state
+      AutoComplete(JsonToken.Undefined);
+      AddToken(new BsonRegex(pattern, options));
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/ConstructorHandling.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/ConstructorHandling.cs
index 591d150..34b8487 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/ConstructorHandling.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/ConstructorHandling.cs
@@ -1,47 +1,42 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Newtonsoft.Json
-{
-  /// <summary>
-  /// Specifies how constructors are used when initializing objects during deserialization by the <see cref="JsonSerializer"/>.
-  /// </summary>
-  public enum ConstructorHandling
-  {
-    /// <summary>
-    /// First attempt to use the public default constructor then fall back to single paramatized constructor.
-    /// </summary>
-    Default = 0,
-    /// <summary>
-    /// Allow Json.NET to use a non-public default constructor.
-    /// </summary>
-    AllowNonPublicDefaultConstructor = 1
-  }
+#region License
+// 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.
+#endregion
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Specifies how constructors are used when initializing objects during deserialization by the <see cref="JsonSerializer"/>.
+  /// </summary>
+  public enum ConstructorHandling
+  {
+    /// <summary>
+    /// First attempt to use the public default constructor, then fall back to single paramatized constructor, then the non-public default constructor.
+    /// </summary>
+    Default = 0,
+    /// <summary>
+    /// Json.NET will use a non-public default constructor before falling back to a paramatized constructor.
+    /// </summary>
+    AllowNonPublicDefaultConstructor = 1
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/BinaryConverter.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/BinaryConverter.cs
index c92c6f7..f0ed62e 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/BinaryConverter.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/BinaryConverter.cs
@@ -1,147 +1,182 @@
-#region License
-// 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.
-#endregion
-
-using System;
-#if !SILVERLIGHT
-using System.Data.SqlTypes;
-#endif
-using System.Globalization;
-using Newtonsoft.Json.Utilities;
-
-namespace Newtonsoft.Json.Converters
-{
-#if !SILVERLIGHT && !PocketPC && !NET20
-  internal interface IBinary
-  {
-    byte[] ToArray();
-  }
-#endif
-
-  /// <summary>
-  /// Converts a binary value to and from a base 64 string value.
-  /// </summary>
-  public class BinaryConverter : JsonConverter
-  {
-#if !SILVERLIGHT && !PocketPC && !NET20
-    private const string BinaryTypeName = "System.Data.Linq.Binary";
-#endif
-
-    /// <summary>
-    /// Writes the JSON representation of the object.
-    /// </summary>
-    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
-    /// <param name="value">The value.</param>
-    /// <param name="serializer">The calling serializer.</param>
-    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
-    {
-      if (value == null)
-      {
-        writer.WriteNull();
-        return;
-      }
-
-      byte[] data = GetByteArray(value);
-
-      writer.WriteValue(data);
-    }
-
-    private byte[] GetByteArray(object value)
-    {
-#if !SILVERLIGHT && !PocketPC && !NET20
-      if (value.GetType().AssignableToTypeName(BinaryTypeName))
-      {
-        IBinary binary = DynamicWrapper.CreateWrapper<IBinary>(value);
-        return binary.ToArray();
-      }
-#endif
-#if !SILVERLIGHT
-      if (value is SqlBinary)
-        return ((SqlBinary) value).Value;
-#endif
-      throw new Exception("Unexpected value type when writing binary: {0}".FormatWith(CultureInfo.InvariantCulture, value.GetType()));
-    }
-
-    /// <summary>
-    /// Reads the JSON representation of the object.
-    /// </summary>
-    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
-    /// <param name="objectType">Type of the object.</param>
-    /// <param name="existingValue">The existing value of object being read.</param>
-    /// <param name="serializer">The calling serializer.</param>
-    /// <returns>The object value.</returns>
-    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
-    {
-      Type t = (ReflectionUtils.IsNullableType(objectType))
-        ? Nullable.GetUnderlyingType(objectType)
-        : objectType;
-
-      if (reader.TokenType == JsonToken.Null)
-      {
-        if (!ReflectionUtils.IsNullable(objectType))
-          throw new Exception("Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType));
-
-        return null;
-      }
-
-      if (reader.TokenType != JsonToken.String)
-        throw new Exception("Unexpected token parsing binary. Expected String, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
-
-      // current token is already at base64 string
-      // unable to call ReadAsBytes so do it the old fashion way
-      string encodedData = reader.Value.ToString();
-      byte[] data = Convert.FromBase64String(encodedData);
-
-#if !SILVERLIGHT && !PocketPC && !NET20
-      if (t.AssignableToTypeName(BinaryTypeName))
-        return Activator.CreateInstance(t, data);
-#endif
-#if !SILVERLIGHT
-      if (t == typeof(SqlBinary))
-        return new SqlBinary(data);
-#endif
-      throw new Exception("Unexpected object type when writing binary: {0}".FormatWith(CultureInfo.InvariantCulture, objectType));
-    }
-
-    /// <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)
-    {
-#if !SILVERLIGHT && !PocketPC && !NET20
-      if (objectType.AssignableToTypeName(BinaryTypeName))
-        return true;
-#endif
-#if !SILVERLIGHT
-      if (objectType == typeof(SqlBinary) || objectType == typeof(SqlBinary?))
-        return true;
-#endif
-      return false;
-    }
-  }
-}
\ No newline at end of file
+#region License
+// 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.
+#endregion
+
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+using System;
+using System.Data.SqlTypes;
+using System.Globalization;
+using Newtonsoft.Json.Utilities;
+using System.Collections.Generic;
+
+namespace Newtonsoft.Json.Converters
+{
+#if !NET20
+  internal interface IBinary
+  {
+    byte[] ToArray();
+  }
+#endif
+
+  /// <summary>
+  /// Converts a binary value to and from a base 64 string value.
+  /// </summary>
+  public class BinaryConverter : JsonConverter
+  {
+#if !NET20
+    private const string BinaryTypeName = "System.Data.Linq.Binary";
+#endif
+
+    /// <summary>
+    /// Writes the JSON representation of the object.
+    /// </summary>
+    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
+    /// <param name="value">The value.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+    {
+      if (value == null)
+      {
+        writer.WriteNull();
+        return;
+      }
+
+      byte[] data = GetByteArray(value);
+
+      writer.WriteValue(data);
+    }
+
+    private byte[] GetByteArray(object value)
+    {
+#if !(NET20)
+      if (value.GetType().AssignableToTypeName(BinaryTypeName))
+      {
+        IBinary binary = DynamicWrapper.CreateWrapper<IBinary>(value);
+        return binary.ToArray();
+      }
+#endif
+      if (value is SqlBinary)
+        return ((SqlBinary) value).Value;
+
+      throw new JsonSerializationException("Unexpected value type when writing binary: {0}".FormatWith(CultureInfo.InvariantCulture, value.GetType()));
+    }
+
+    /// <summary>
+    /// Reads the JSON representation of the object.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
+    /// <param name="objectType">Type of the object.</param>
+    /// <param name="existingValue">The existing value of object being read.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    /// <returns>The object value.</returns>
+    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+    {
+      Type t = (ReflectionUtils.IsNullableType(objectType))
+        ? Nullable.GetUnderlyingType(objectType)
+        : objectType;
+
+      if (reader.TokenType == JsonToken.Null)
+      {
+        if (!ReflectionUtils.IsNullable(objectType))
+          throw JsonSerializationException.Create(reader, "Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType));
+
+        return null;
+      }
+
+      byte[] data;
+
+      if (reader.TokenType == JsonToken.StartArray)
+      {
+        data = ReadByteArray(reader);
+      }
+      else if (reader.TokenType == JsonToken.String)
+      {
+        // current token is already at base64 string
+        // unable to call ReadAsBytes so do it the old fashion way
+        string encodedData = reader.Value.ToString();
+        data = Convert.FromBase64String(encodedData);
+      }
+      else
+      {
+        throw JsonSerializationException.Create(reader, "Unexpected token parsing binary. Expected String or StartArray, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
+      }
+
+      
+#if !NET20
+      if (t.AssignableToTypeName(BinaryTypeName))
+        return Activator.CreateInstance(t, data);
+#endif
+
+      if (t == typeof(SqlBinary))
+        return new SqlBinary(data);
+
+      throw JsonSerializationException.Create(reader, "Unexpected object type when writing binary: {0}".FormatWith(CultureInfo.InvariantCulture, objectType));
+    }
+
+    private byte[] ReadByteArray(JsonReader reader)
+    {
+      List<byte> byteList = new List<byte>();
+
+      while (reader.Read())
+      {
+        switch (reader.TokenType)
+        {
+          case JsonToken.Integer:
+            byteList.Add(Convert.ToByte(reader.Value, CultureInfo.InvariantCulture));
+            break;
+          case JsonToken.EndArray:
+            return byteList.ToArray();
+          case JsonToken.Comment:
+            // skip
+            break;
+          default:
+            throw JsonSerializationException.Create(reader, "Unexpected token when reading bytes: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
+        }
+      }
+
+      throw JsonSerializationException.Create(reader, "Unexpected end when reading bytes.");
+    }
+
+    /// <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)
+    {
+#if !NET20
+      if (objectType.AssignableToTypeName(BinaryTypeName))
+        return true;
+#endif
+
+      if (objectType == typeof(SqlBinary) || objectType == typeof(SqlBinary?))
+        return true;
+
+      return false;
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/BsonObjectIdConverter.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/BsonObjectIdConverter.cs
index e5697c2..38dd0e6 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/BsonObjectIdConverter.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/BsonObjectIdConverter.cs
@@ -1,67 +1,89 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Newtonsoft.Json.Bson;
-using System.Globalization;
-using Newtonsoft.Json.Utilities;
-
-namespace Newtonsoft.Json.Converters
-{
-  /// <summary>
-  /// Converts a <see cref="BsonObjectId"/> to and from JSON and BSON.
-  /// </summary>
-  public class BsonObjectIdConverter : JsonConverter
-  {
-    /// <summary>
-    /// Writes the JSON representation of the object.
-    /// </summary>
-    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
-    /// <param name="value">The value.</param>
-    /// <param name="serializer">The calling serializer.</param>
-    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
-    {
-      BsonObjectId objectId = (BsonObjectId) value;
-
-      BsonWriter bsonWriter = writer as BsonWriter;
-      if (bsonWriter != null)
-      {
-        bsonWriter.WriteObjectId(objectId.Value);
-      }
-      else
-      {
-        writer.WriteValue(objectId.Value);
-      }
-    }
-
-    /// <summary>
-    /// Reads the JSON representation of the object.
-    /// </summary>
-    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
-    /// <param name="objectType">Type of the object.</param>
-    /// <param name="existingValue">The existing value of object being read.</param>
-    /// <param name="serializer">The calling serializer.</param>
-    /// <returns>The object value.</returns>
-    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
-    {
-      if (reader.TokenType != JsonToken.Bytes)
-        throw new JsonSerializationException("Expected Bytes but got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
-
-      byte[] value = (byte[])reader.Value;
-
-      return new BsonObjectId(value);
-    }
-
-    /// <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 (BsonObjectId));
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using Newtonsoft.Json.Bson;
+using System.Globalization;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Converters
+{
+  /// <summary>
+  /// Converts a <see cref="BsonObjectId"/> to and from JSON and BSON.
+  /// </summary>
+  public class BsonObjectIdConverter : JsonConverter
+  {
+    /// <summary>
+    /// Writes the JSON representation of the object.
+    /// </summary>
+    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
+    /// <param name="value">The value.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+    {
+      BsonObjectId objectId = (BsonObjectId) value;
+
+      BsonWriter bsonWriter = writer as BsonWriter;
+      if (bsonWriter != null)
+      {
+        bsonWriter.WriteObjectId(objectId.Value);
+      }
+      else
+      {
+        writer.WriteValue(objectId.Value);
+      }
+    }
+
+    /// <summary>
+    /// Reads the JSON representation of the object.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
+    /// <param name="objectType">Type of the object.</param>
+    /// <param name="existingValue">The existing value of object being read.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    /// <returns>The object value.</returns>
+    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+    {
+      if (reader.TokenType != JsonToken.Bytes)
+        throw new JsonSerializationException("Expected Bytes but got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
+
+      byte[] value = (byte[])reader.Value;
+
+      return new BsonObjectId(value);
+    }
+
+    /// <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 (BsonObjectId));
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/CustomCreationConverter.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/CustomCreationConverter.cs
index a7eb499..1534759 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/CustomCreationConverter.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/CustomCreationConverter.cs
@@ -1,98 +1,99 @@
-#region License
-// 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.
-#endregion
-
-using System;
-
-namespace Newtonsoft.Json.Converters
-{
-  /// <summary>
-  /// Create a custom object
-  /// </summary>
-  /// <typeparam name="T"></typeparam>
-  public abstract class CustomCreationConverter<T> : JsonConverter
-  {
-    /// <summary>
-    /// Writes the JSON representation of the object.
-    /// </summary>
-    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
-    /// <param name="value">The value.</param>
-    /// <param name="serializer">The calling serializer.</param>
-    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
-    {
-      throw new NotSupportedException("CustomCreationConverter should only be used while deserializing.");
-    }
-
-    /// <summary>
-    /// Reads the JSON representation of the object.
-    /// </summary>
-    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
-    /// <param name="objectType">Type of the object.</param>
-    /// <param name="existingValue">The existing value of object being read.</param>
-    /// <param name="serializer">The calling serializer.</param>
-    /// <returns>The object value.</returns>
-    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
-    {
-      if (reader.TokenType == JsonToken.Null)
-        return null;
-
-      T value = Create(objectType);
-      if (value == null)
-        throw new JsonSerializationException("No object created.");
-
-      serializer.Populate(reader, value);
-      return value;
-    }
-
-    /// <summary>
-    /// Creates an object which will then be populated by the serializer.
-    /// </summary>
-    /// <param name="objectType">Type of the object.</param>
-    /// <returns></returns>
-    public abstract T Create(Type objectType);
-
-    /// <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 typeof (T).IsAssignableFrom(objectType);
-    }
-
-    /// <summary>
-    /// Gets a value indicating whether this <see cref="JsonConverter"/> can write JSON.
-    /// </summary>
-    /// <value>
-    /// 	<c>true</c> if this <see cref="JsonConverter"/> can write JSON; otherwise, <c>false</c>.
-    /// </value>
-    public override bool CanWrite
-    {
-      get { return false; }
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Converters
+{
+  /// <summary>
+  /// Create a custom object
+  /// </summary>
+  /// <typeparam name="T">The object type to convert.</typeparam>
+  public abstract class CustomCreationConverter<T> : JsonConverter
+  {
+    /// <summary>
+    /// Writes the JSON representation of the object.
+    /// </summary>
+    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
+    /// <param name="value">The value.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+    {
+      throw new NotSupportedException("CustomCreationConverter should only be used while deserializing.");
+    }
+
+    /// <summary>
+    /// Reads the JSON representation of the object.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
+    /// <param name="objectType">Type of the object.</param>
+    /// <param name="existingValue">The existing value of object being read.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    /// <returns>The object value.</returns>
+    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+    {
+      if (reader.TokenType == JsonToken.Null)
+        return null;
+
+      T value = Create(objectType);
+      if (value == null)
+        throw new JsonSerializationException("No object created.");
+
+      serializer.Populate(reader, value);
+      return value;
+    }
+
+    /// <summary>
+    /// Creates an object which will then be populated by the serializer.
+    /// </summary>
+    /// <param name="objectType">Type of the object.</param>
+    /// <returns>The created object.</returns>
+    public abstract T Create(Type objectType);
+
+    /// <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 typeof (T).IsAssignableFrom(objectType);
+    }
+
+    /// <summary>
+    /// Gets a value indicating whether this <see cref="JsonConverter"/> can write JSON.
+    /// </summary>
+    /// <value>
+    /// 	<c>true</c> if this <see cref="JsonConverter"/> can write JSON; otherwise, <c>false</c>.
+    /// </value>
+    public override bool CanWrite
+    {
+      get { return false; }
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/DataSetConverter.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/DataSetConverter.cs
index ef4e872..4f74b5d 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/DataSetConverter.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/DataSetConverter.cs
@@ -1,101 +1,103 @@
-#region License
-// 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.
-#endregion
-
-#if !SILVERLIGHT
-using System;
-using System.Data;
-
-namespace Newtonsoft.Json.Converters
-{
-  /// <summary>
-  /// Converts a <see cref="DataSet"/> to and from JSON.
-  /// </summary>
-  public class DataSetConverter : JsonConverter
-  {
-    /// <summary>
-    /// Writes the JSON representation of the object.
-    /// </summary>
-    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
-    /// <param name="value">The value.</param>
-    /// <param name="serializer">The calling serializer.</param>
-    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
-    {
-      DataSet dataSet = (DataSet)value;
-
-      DataTableConverter converter = new DataTableConverter();
-
-      writer.WriteStartObject();
-
-      foreach (DataTable table in dataSet.Tables)
-      {
-        writer.WritePropertyName(table.TableName);
-        
-        converter.WriteJson(writer, table, serializer);
-      }
-
-      writer.WriteEndObject();
-    }
-
-    /// <summary>
-    /// Reads the JSON representation of the object.
-    /// </summary>
-    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
-    /// <param name="objectType">Type of the object.</param>
-    /// <param name="existingValue">The existing value of object being read.</param>
-    /// <param name="serializer">The calling serializer.</param>
-    /// <returns>The object value.</returns>
-    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
-    {
-      DataSet ds = new DataSet();
-
-      DataTableConverter converter = new DataTableConverter();
-
-      reader.Read();
-
-      while (reader.TokenType == JsonToken.PropertyName)
-      {
-        DataTable dt = (DataTable)converter.ReadJson(reader, typeof (DataTable), null, serializer);
-        ds.Tables.Add(dt);
-      }
-
-      reader.Read();
-
-      return ds;
-    }
-
-    /// <summary>
-    /// Determines whether this instance can convert the specified value type.
-    /// </summary>
-    /// <param name="valueType">Type of the value.</param>
-    /// <returns>
-    /// 	<c>true</c> if this instance can convert the specified value type; otherwise, <c>false</c>.
-    /// </returns>
-    public override bool CanConvert(Type valueType)
-    {
-      return (valueType == typeof(DataSet));
-    }
-  }
-}
+#region License
+// 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.
+#endregion
+
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+using System;
+using System.Data;
+using Newtonsoft.Json.Serialization;
+
+namespace Newtonsoft.Json.Converters
+{
+  /// <summary>
+  /// Converts a <see cref="DataSet"/> to and from JSON.
+  /// </summary>
+  public class DataSetConverter : JsonConverter
+  {
+    /// <summary>
+    /// Writes the JSON representation of the object.
+    /// </summary>
+    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
+    /// <param name="value">The value.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+    {
+      DataSet dataSet = (DataSet)value;
+      DefaultContractResolver resolver = serializer.ContractResolver as DefaultContractResolver;
+
+      DataTableConverter converter = new DataTableConverter();
+
+      writer.WriteStartObject();
+
+      foreach (DataTable table in dataSet.Tables)
+      {
+        writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(table.TableName) : table.TableName);
+        
+        converter.WriteJson(writer, table, serializer);
+      }
+
+      writer.WriteEndObject();
+    }
+
+    /// <summary>
+    /// Reads the JSON representation of the object.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
+    /// <param name="objectType">Type of the object.</param>
+    /// <param name="existingValue">The existing value of object being read.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    /// <returns>The object value.</returns>
+    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+    {
+      DataSet ds = new DataSet();
+
+      DataTableConverter converter = new DataTableConverter();
+
+      reader.Read();
+
+      while (reader.TokenType == JsonToken.PropertyName)
+      {
+        DataTable dt = (DataTable)converter.ReadJson(reader, typeof (DataTable), null, serializer);
+        ds.Tables.Add(dt);
+
+        reader.Read();
+      }
+
+      return ds;
+    }
+
+    /// <summary>
+    /// Determines whether this instance can convert the specified value type.
+    /// </summary>
+    /// <param name="valueType">Type of the value.</param>
+    /// <returns>
+    /// 	<c>true</c> if this instance can convert the specified value type; otherwise, <c>false</c>.
+    /// </returns>
+    public override bool CanConvert(Type valueType)
+    {
+      return (valueType == typeof(DataSet));
+    }
+  }
+}
 #endif
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/DataTableConverter.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/DataTableConverter.cs
index 55d98ef..0670a4e 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/DataTableConverter.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/DataTableConverter.cs
@@ -1,153 +1,156 @@
-#region License
-// 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.
-#endregion
-
-#if !SILVERLIGHT
-using System;
-using System.Data;
-
-namespace Newtonsoft.Json.Converters
-{
-  /// <summary>
-  /// Converts a <see cref="DataTable"/> to and from JSON.
-  /// </summary>
-  public class DataTableConverter : JsonConverter
-  {
-    /// <summary>
-    /// Writes the JSON representation of the object.
-    /// </summary>
-    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
-    /// <param name="value">The value.</param>
-    /// <param name="serializer">The calling serializer.</param>
-    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
-    {
-      DataTable table = (DataTable)value;
-
-      writer.WriteStartArray();
-
-      foreach (DataRow row in table.Rows)
-      {
-        writer.WriteStartObject();
-        foreach (DataColumn column in row.Table.Columns)
-        {
-          writer.WritePropertyName(column.ColumnName);
-          serializer.Serialize(writer, row[column]);
-        }
-        writer.WriteEndObject();
-      }
-
-      writer.WriteEndArray();
-    }
-
-    /// <summary>
-    /// Reads the JSON representation of the object.
-    /// </summary>
-    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
-    /// <param name="objectType">Type of the object.</param>
-    /// <param name="existingValue">The existing value of object being read.</param>
-    /// <param name="serializer">The calling serializer.</param>
-    /// <returns>The object value.</returns>
-    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
-    {
-      DataTable dt;
-
-      if (reader.TokenType == JsonToken.PropertyName)
-      {
-        dt = new DataTable((string)reader.Value);
-        reader.Read();
-      }
-      else
-      {
-        dt = new DataTable();
-      }
-
-      reader.Read();
-
-      while (reader.TokenType == JsonToken.StartObject)
-      {
-        DataRow dr = dt.NewRow();
-        reader.Read();
-
-        while (reader.TokenType == JsonToken.PropertyName)
-        {
-          string columnName = (string) reader.Value;
-
-          reader.Read();
-
-          if (!dt.Columns.Contains(columnName))
-          {
-            Type columnType = GetColumnDataType(reader.TokenType);
-            dt.Columns.Add(new DataColumn(columnName, columnType));
-          }
-
-          dr[columnName] = reader.Value;
-          reader.Read();
-        }
-
-        dr.EndEdit();
-        dt.Rows.Add(dr);
-
-        reader.Read();
-      }
-
-      reader.Read();
-
-      return dt;
-    }
-
-    private static Type GetColumnDataType(JsonToken tokenType)
-    {
-      switch (tokenType)
-      {
-        case JsonToken.Integer:
-          return typeof (long);
-        case JsonToken.Float:
-          return typeof (double);
-        case JsonToken.String:
-        case JsonToken.Null:
-        case JsonToken.Undefined:
-          return typeof (string);
-        case JsonToken.Boolean:
-          return typeof (bool);
-        case JsonToken.Date:
-          return typeof (DateTime);
-        default:
-          throw new ArgumentOutOfRangeException();
-      }
-    }
-
-    /// <summary>
-    /// Determines whether this instance can convert the specified value type.
-    /// </summary>
-    /// <param name="valueType">Type of the value.</param>
-    /// <returns>
-    /// 	<c>true</c> if this instance can convert the specified value type; otherwise, <c>false</c>.
-    /// </returns>
-    public override bool CanConvert(Type valueType)
-    {
-      return (valueType == typeof(DataTable));
-    }
-  }
-}
+#region License
+// 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.
+#endregion
+
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+using System;
+using System.Data;
+using Newtonsoft.Json.Serialization;
+
+namespace Newtonsoft.Json.Converters
+{
+  /// <summary>
+  /// Converts a <see cref="DataTable"/> to and from JSON.
+  /// </summary>
+  public class DataTableConverter : JsonConverter
+  {
+    /// <summary>
+    /// Writes the JSON representation of the object.
+    /// </summary>
+    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
+    /// <param name="value">The value.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+    {
+      DataTable table = (DataTable)value;
+      DefaultContractResolver resolver = serializer.ContractResolver as DefaultContractResolver;
+
+      writer.WriteStartArray();
+
+      foreach (DataRow row in table.Rows)
+      {
+        writer.WriteStartObject();
+        foreach (DataColumn column in row.Table.Columns)
+        {
+          if (serializer.NullValueHandling == NullValueHandling.Ignore && (row[column] == null || row[column] == DBNull.Value))
+            continue;
+
+          writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(column.ColumnName) : column.ColumnName);
+          serializer.Serialize(writer, row[column]);
+        }
+        writer.WriteEndObject();
+      }
+
+      writer.WriteEndArray();
+    }
+
+    /// <summary>
+    /// Reads the JSON representation of the object.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
+    /// <param name="objectType">Type of the object.</param>
+    /// <param name="existingValue">The existing value of object being read.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    /// <returns>The object value.</returns>
+    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+    {
+      DataTable dt;
+
+      if (reader.TokenType == JsonToken.PropertyName)
+      {
+        dt = new DataTable((string)reader.Value);
+        reader.Read();
+      }
+      else
+      {
+        dt = new DataTable();
+      }
+
+      reader.Read();
+
+      while (reader.TokenType == JsonToken.StartObject)
+      {
+        DataRow dr = dt.NewRow();
+        reader.Read();
+
+        while (reader.TokenType == JsonToken.PropertyName)
+        {
+          string columnName = (string)reader.Value;
+
+          reader.Read();
+
+          if (!dt.Columns.Contains(columnName))
+          {
+            Type columnType = GetColumnDataType(reader.TokenType);
+            dt.Columns.Add(new DataColumn(columnName, columnType));
+          }
+
+          dr[columnName] = reader.Value ?? DBNull.Value;
+          reader.Read();
+        }
+
+        dr.EndEdit();
+        dt.Rows.Add(dr);
+
+        reader.Read();
+      }
+
+      return dt;
+    }
+
+    private static Type GetColumnDataType(JsonToken tokenType)
+    {
+      switch (tokenType)
+      {
+        case JsonToken.Integer:
+          return typeof (long);
+        case JsonToken.Float:
+          return typeof (double);
+        case JsonToken.String:
+        case JsonToken.Null:
+        case JsonToken.Undefined:
+          return typeof (string);
+        case JsonToken.Boolean:
+          return typeof (bool);
+        case JsonToken.Date:
+          return typeof (DateTime);
+        default:
+          throw new ArgumentOutOfRangeException();
+      }
+    }
+
+    /// <summary>
+    /// Determines whether this instance can convert the specified value type.
+    /// </summary>
+    /// <param name="valueType">Type of the value.</param>
+    /// <returns>
+    /// 	<c>true</c> if this instance can convert the specified value type; otherwise, <c>false</c>.
+    /// </returns>
+    public override bool CanConvert(Type valueType)
+    {
+      return (valueType == typeof(DataTable));
+    }
+  }
+}
 #endif
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/DateTimeConverterBase.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/DateTimeConverterBase.cs
index 8c2f068..b0642ae 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/DateTimeConverterBase.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/DateTimeConverterBase.cs
@@ -1,32 +1,54 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Newtonsoft.Json.Converters
-{
-  /// <summary>
-  /// Provides a base class for converting a <see cref="DateTime"/> to and from JSON.
-  /// </summary>
-  public abstract class DateTimeConverterBase : JsonConverter
-  {
-    /// <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)
-    {
-      if (objectType == typeof(DateTime) || objectType == typeof(DateTime?))
-        return true;
-#if !PocketPC && !NET20
-      if (objectType == typeof(DateTimeOffset) || objectType == typeof(DateTimeOffset?))
-        return true;
-#endif
-
-      return false;
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json.Converters
+{
+  /// <summary>
+  /// Provides a base class for converting a <see cref="DateTime"/> to and from JSON.
+  /// </summary>
+  public abstract class DateTimeConverterBase : JsonConverter
+  {
+    /// <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)
+    {
+      if (objectType == typeof(DateTime) || objectType == typeof(DateTime?))
+        return true;
+#if !PocketPC && !NET20
+      if (objectType == typeof(DateTimeOffset) || objectType == typeof(DateTimeOffset?))
+        return true;
+#endif
+
+      return false;
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/EntityKeyMemberConverter.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/EntityKeyMemberConverter.cs
index 6dfc287..9e7ecd5 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/EntityKeyMemberConverter.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/EntityKeyMemberConverter.cs
@@ -1,140 +1,140 @@
-#region License
-// 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.
-#endregion
-
-#if !PocketPC && !SILVERLIGHT && !NET20
-using System;
-using Newtonsoft.Json.Serialization;
-using System.Globalization;
-using Newtonsoft.Json.Utilities;
-
-namespace Newtonsoft.Json.Converters
-{
-  internal interface IEntityKeyMember
-  {
-    string Key { get; set; }
-    object Value { get; set; }
-  }
-
-  /// <summary>
-  /// Converts an Entity Framework EntityKey to and from JSON.
-  /// </summary>
-  public class EntityKeyMemberConverter : JsonConverter
-  {
-    private const string EntityKeyMemberFullTypeName = "System.Data.EntityKeyMember";
-
-    /// <summary>
-    /// Writes the JSON representation of the object.
-    /// </summary>
-    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
-    /// <param name="value">The value.</param>
-    /// <param name="serializer">The calling serializer.</param>
-    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
-    {
-      IEntityKeyMember entityKeyMember = DynamicWrapper.CreateWrapper<IEntityKeyMember>(value);
-      Type keyType = (entityKeyMember.Value != null) ? entityKeyMember.Value.GetType() : null;
-
-      writer.WriteStartObject();
-      writer.WritePropertyName("Key");
-      writer.WriteValue(entityKeyMember.Key);
-      writer.WritePropertyName("Type");
-      writer.WriteValue((keyType != null) ? keyType.FullName : null);
-
-      writer.WritePropertyName("Value");
-
-      if (keyType != null)
-      {
-        string valueJson;
-        if (JsonSerializerInternalWriter.TryConvertToString(entityKeyMember.Value, keyType, out valueJson))
-          writer.WriteValue(valueJson);
-        else
-          writer.WriteValue(entityKeyMember.Value);
-      }
-      else
-      {
-        writer.WriteNull();
-      }
-
-      writer.WriteEndObject();
-    }
-
-    private static void ReadAndAssertProperty(JsonReader reader, string propertyName)
-    {
-      ReadAndAssert(reader);
-
-      if (reader.TokenType != JsonToken.PropertyName || reader.Value.ToString() != propertyName)
-        throw new JsonSerializationException("Expected JSON property '{0}'.".FormatWith(CultureInfo.InvariantCulture, propertyName));
-    }
-
-    private static void ReadAndAssert(JsonReader reader)
-    {
-      if (!reader.Read())
-        throw new JsonSerializationException("Unexpected end.");
-    }
-
-    /// <summary>
-    /// Reads the JSON representation of the object.
-    /// </summary>
-    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
-    /// <param name="objectType">Type of the object.</param>
-    /// <param name="existingValue">The existing value of object being read.</param>
-    /// <param name="serializer">The calling serializer.</param>
-    /// <returns>The object value.</returns>
-    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
-    {
-      IEntityKeyMember entityKeyMember = DynamicWrapper.CreateWrapper<IEntityKeyMember>(Activator.CreateInstance(objectType));
-
-      ReadAndAssertProperty(reader, "Key");
-      ReadAndAssert(reader);
-      entityKeyMember.Key = reader.Value.ToString();
-
-      ReadAndAssertProperty(reader, "Type");
-      ReadAndAssert(reader);
-      string type = reader.Value.ToString();
-
-      Type t = Type.GetType(type);
-
-      ReadAndAssertProperty(reader, "Value");
-      ReadAndAssert(reader);
-      entityKeyMember.Value = serializer.Deserialize(reader, t);
-
-      ReadAndAssert(reader);
-
-      return DynamicWrapper.GetUnderlyingObject(entityKeyMember);
-    }
-
-    /// <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.AssignableToTypeName(EntityKeyMemberFullTypeName));
-    }
-  }
-}
+#region License
+// 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.
+#endregion
+
+#if !(SILVERLIGHT || NET20 || NETFX_CORE || PORTABLE)
+using System;
+using Newtonsoft.Json.Serialization;
+using System.Globalization;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Converters
+{
+  internal interface IEntityKeyMember
+  {
+    string Key { get; set; }
+    object Value { get; set; }
+  }
+
+  /// <summary>
+  /// Converts an Entity Framework EntityKey to and from JSON.
+  /// </summary>
+  public class EntityKeyMemberConverter : JsonConverter
+  {
+    private const string EntityKeyMemberFullTypeName = "System.Data.EntityKeyMember";
+
+    /// <summary>
+    /// Writes the JSON representation of the object.
+    /// </summary>
+    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
+    /// <param name="value">The value.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+    {
+      IEntityKeyMember entityKeyMember = DynamicWrapper.CreateWrapper<IEntityKeyMember>(value);
+      Type keyType = (entityKeyMember.Value != null) ? entityKeyMember.Value.GetType() : null;
+
+      writer.WriteStartObject();
+      writer.WritePropertyName("Key");
+      writer.WriteValue(entityKeyMember.Key);
+      writer.WritePropertyName("Type");
+      writer.WriteValue((keyType != null) ? keyType.FullName : null);
+
+      writer.WritePropertyName("Value");
+
+      if (keyType != null)
+      {
+        string valueJson;
+        if (JsonSerializerInternalWriter.TryConvertToString(entityKeyMember.Value, keyType, out valueJson))
+          writer.WriteValue(valueJson);
+        else
+          writer.WriteValue(entityKeyMember.Value);
+      }
+      else
+      {
+        writer.WriteNull();
+      }
+
+      writer.WriteEndObject();
+    }
+
+    private static void ReadAndAssertProperty(JsonReader reader, string propertyName)
+    {
+      ReadAndAssert(reader);
+
+      if (reader.TokenType != JsonToken.PropertyName || reader.Value.ToString() != propertyName)
+        throw new JsonSerializationException("Expected JSON property '{0}'.".FormatWith(CultureInfo.InvariantCulture, propertyName));
+    }
+
+    private static void ReadAndAssert(JsonReader reader)
+    {
+      if (!reader.Read())
+        throw new JsonSerializationException("Unexpected end.");
+    }
+
+    /// <summary>
+    /// Reads the JSON representation of the object.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
+    /// <param name="objectType">Type of the object.</param>
+    /// <param name="existingValue">The existing value of object being read.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    /// <returns>The object value.</returns>
+    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+    {
+      IEntityKeyMember entityKeyMember = DynamicWrapper.CreateWrapper<IEntityKeyMember>(Activator.CreateInstance(objectType));
+
+      ReadAndAssertProperty(reader, "Key");
+      ReadAndAssert(reader);
+      entityKeyMember.Key = reader.Value.ToString();
+
+      ReadAndAssertProperty(reader, "Type");
+      ReadAndAssert(reader);
+      string type = reader.Value.ToString();
+
+      Type t = Type.GetType(type);
+
+      ReadAndAssertProperty(reader, "Value");
+      ReadAndAssert(reader);
+      entityKeyMember.Value = serializer.Deserialize(reader, t);
+
+      ReadAndAssert(reader);
+
+      return DynamicWrapper.GetUnderlyingObject(entityKeyMember);
+    }
+
+    /// <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.AssignableToTypeName(EntityKeyMemberFullTypeName));
+    }
+  }
+}
 #endif
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/ExpandoObjectConverter.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/ExpandoObjectConverter.cs
new file mode 100644
index 0000000..3fba6d0
--- /dev/null
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/ExpandoObjectConverter.cs
@@ -0,0 +1,165 @@
+#region License
+// 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.
+#endregion
+
+#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
+
+using System;
+using System.Collections.Generic;
+using System.Dynamic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Converters
+{
+  /// <summary>
+  /// Converts an ExpandoObject to and from JSON.
+  /// </summary>
+  public class ExpandoObjectConverter : JsonConverter
+  {
+    /// <summary>
+    /// Writes the JSON representation of the object.
+    /// </summary>
+    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
+    /// <param name="value">The value.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+    {
+      // can write is set to false
+    }
+
+    /// <summary>
+    /// Reads the JSON representation of the object.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
+    /// <param name="objectType">Type of the object.</param>
+    /// <param name="existingValue">The existing value of object being read.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    /// <returns>The object value.</returns>
+    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+    {
+      return ReadValue(reader);
+    }
+
+    private object ReadValue(JsonReader reader)
+    {
+      while (reader.TokenType == JsonToken.Comment)
+      {
+        if (!reader.Read())
+          throw JsonSerializationException.Create(reader, "Unexpected end when reading ExpandoObject.");
+      }
+
+      switch (reader.TokenType)
+      {
+        case JsonToken.StartObject:
+          return ReadObject(reader);
+        case JsonToken.StartArray:
+          return ReadList(reader);
+        default:
+          if (JsonReader.IsPrimitiveToken(reader.TokenType))
+            return reader.Value;
+
+          throw JsonSerializationException.Create(reader, "Unexpected token when converting ExpandoObject: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
+      }
+    }
+
+    private object ReadList(JsonReader reader)
+    {
+      IList<object> list = new List<object>();
+
+      while (reader.Read())
+      {
+        switch (reader.TokenType)
+        {
+          case JsonToken.Comment:
+            break;
+          default:
+            object v = ReadValue(reader);
+
+            list.Add(v);
+            break;
+          case JsonToken.EndArray:
+            return list;
+        }
+      }
+
+      throw JsonSerializationException.Create(reader, "Unexpected end when reading ExpandoObject.");
+    }
+
+    private object ReadObject(JsonReader reader)
+    {
+      IDictionary<string, object> expandoObject = new ExpandoObject();
+
+      while (reader.Read())
+      {
+        switch (reader.TokenType)
+        {
+          case JsonToken.PropertyName:
+            string propertyName = reader.Value.ToString();
+
+            if (!reader.Read())
+              throw JsonSerializationException.Create(reader, "Unexpected end when reading ExpandoObject.");
+
+            object v = ReadValue(reader);
+
+            expandoObject[propertyName] = v;
+            break;
+          case JsonToken.Comment:
+            break;
+          case JsonToken.EndObject:
+            return expandoObject;
+        }
+      }
+
+      throw JsonSerializationException.Create(reader, "Unexpected end when reading ExpandoObject.");
+    }
+
+    /// <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 (ExpandoObject));
+    }
+
+    /// <summary>
+    /// Gets a value indicating whether this <see cref="JsonConverter"/> can write JSON.
+    /// </summary>
+    /// <value>
+    /// 	<c>true</c> if this <see cref="JsonConverter"/> can write JSON; otherwise, <c>false</c>.
+    /// </value>
+    public override bool CanWrite
+    {
+      get { return false; }
+    }
+  }
+}
+
+#endif
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/IsoDateTimeConverter.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/IsoDateTimeConverter.cs
index 2a2dac8..f44115b 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/IsoDateTimeConverter.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/IsoDateTimeConverter.cs
@@ -1,134 +1,169 @@
-using System;
-using System.Globalization;
-using Newtonsoft.Json.Utilities;
-
-namespace Newtonsoft.Json.Converters
-{
-  /// <summary>
-  /// Converts a <see cref="DateTime"/> to and from the ISO 8601 date format (e.g. 2008-04-12T12:53Z).
-  /// </summary>
-  public class IsoDateTimeConverter : DateTimeConverterBase
-  {
-    private const string DefaultDateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";
-
-    private DateTimeStyles _dateTimeStyles = DateTimeStyles.RoundtripKind;
-    private string _dateTimeFormat;
-    private CultureInfo _culture;
-
-    /// <summary>
-    /// Gets or sets the date time styles used when converting a date to and from JSON.
-    /// </summary>
-    /// <value>The date time styles used when converting a date to and from JSON.</value>
-    public DateTimeStyles DateTimeStyles
-    {
-      get { return _dateTimeStyles; }
-      set { _dateTimeStyles = value; }
-    }
-
-    /// <summary>
-    /// Gets or sets the date time format used when converting a date to and from JSON.
-    /// </summary>
-    /// <value>The date time format used when converting a date to and from JSON.</value>
-    public string DateTimeFormat
-    {
-      get { return _dateTimeFormat ?? string.Empty; }
-      set { _dateTimeFormat = StringUtils.NullEmptyString(value); }
-    }
-
-    /// <summary>
-    /// Gets or sets the culture used when converting a date to and from JSON.
-    /// </summary>
-    /// <value>The culture used when converting a date to and from JSON.</value>
-    public CultureInfo Culture
-    {
-      get { return _culture ?? CultureInfo.CurrentCulture; }
-      set { _culture = value; }
-    }
-
-    /// <summary>
-    /// Writes the JSON representation of the object.
-    /// </summary>
-    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
-    /// <param name="value">The value.</param>
-    /// <param name="serializer">The calling serializer.</param>
-    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
-    {
-      string text;
-
-      if (value is DateTime)
-      {
-        DateTime dateTime = (DateTime)value;
-
-        if ((_dateTimeStyles & DateTimeStyles.AdjustToUniversal) == DateTimeStyles.AdjustToUniversal
-          || (_dateTimeStyles & DateTimeStyles.AssumeUniversal) == DateTimeStyles.AssumeUniversal)
-          dateTime = dateTime.ToUniversalTime();
-
-        text = dateTime.ToString(_dateTimeFormat ?? DefaultDateTimeFormat, Culture);
-      }
-#if !PocketPC && !NET20
-      else if (value is DateTimeOffset)
-      {
-        DateTimeOffset dateTimeOffset = (DateTimeOffset)value;
-        if ((_dateTimeStyles & DateTimeStyles.AdjustToUniversal) == DateTimeStyles.AdjustToUniversal
-          || (_dateTimeStyles & DateTimeStyles.AssumeUniversal) == DateTimeStyles.AssumeUniversal)
-          dateTimeOffset = dateTimeOffset.ToUniversalTime();
-
-        text = dateTimeOffset.ToString(_dateTimeFormat ?? DefaultDateTimeFormat, Culture);
-      }
-#endif
-      else
-      {
-        throw new Exception("Unexpected value when converting date. Expected DateTime or DateTimeOffset, got {0}.".FormatWith(CultureInfo.InvariantCulture, ReflectionUtils.GetObjectType(value)));
-      }
-
-      writer.WriteValue(text);
-    }
-
-    /// <summary>
-    /// Reads the JSON representation of the object.
-    /// </summary>
-    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
-    /// <param name="objectType">Type of the object.</param>
-    /// <param name="existingValue">The existing value of object being read.</param>
-    /// <param name="serializer">The calling serializer.</param>
-    /// <returns>The object value.</returns>
-    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
-    {
-      bool nullable = ReflectionUtils.IsNullableType(objectType);
-      Type t = (nullable)
-        ? Nullable.GetUnderlyingType(objectType)
-        : objectType;
-
-      if (reader.TokenType == JsonToken.Null)
-      {
-        if (!ReflectionUtils.IsNullableType(objectType))
-          throw new Exception("Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType));
- 
-        return null;
-      }
-
-      if (reader.TokenType != JsonToken.String)
-        throw new Exception("Unexpected token parsing date. Expected String, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
-
-      string dateText = reader.Value.ToString();
-
-      if (string.IsNullOrEmpty(dateText) && nullable)
-        return null;
-
-#if !PocketPC && !NET20
-      if (t == typeof(DateTimeOffset))
-      {
-        if (!string.IsNullOrEmpty(_dateTimeFormat))
-          return DateTimeOffset.ParseExact(dateText, _dateTimeFormat, Culture, _dateTimeStyles);
-        else
-          return DateTimeOffset.Parse(dateText, Culture, _dateTimeStyles);
-      }
-#endif
-
-      if (!string.IsNullOrEmpty(_dateTimeFormat))
-        return DateTime.ParseExact(dateText, _dateTimeFormat, Culture, _dateTimeStyles);
-      else
-        return DateTime.Parse(dateText, Culture, _dateTimeStyles);
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Globalization;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Converters
+{
+  /// <summary>
+  /// Converts a <see cref="DateTime"/> to and from the ISO 8601 date format (e.g. 2008-04-12T12:53Z).
+  /// </summary>
+  public class IsoDateTimeConverter : DateTimeConverterBase
+  {
+    private const string DefaultDateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";
+
+    private DateTimeStyles _dateTimeStyles = DateTimeStyles.RoundtripKind;
+    private string _dateTimeFormat;
+    private CultureInfo _culture;
+
+    /// <summary>
+    /// Gets or sets the date time styles used when converting a date to and from JSON.
+    /// </summary>
+    /// <value>The date time styles used when converting a date to and from JSON.</value>
+    public DateTimeStyles DateTimeStyles
+    {
+      get { return _dateTimeStyles; }
+      set { _dateTimeStyles = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets the date time format used when converting a date to and from JSON.
+    /// </summary>
+    /// <value>The date time format used when converting a date to and from JSON.</value>
+    public string DateTimeFormat
+    {
+      get { return _dateTimeFormat ?? string.Empty; }
+      set { _dateTimeFormat = StringUtils.NullEmptyString(value); }
+    }
+
+    /// <summary>
+    /// Gets or sets the culture used when converting a date to and from JSON.
+    /// </summary>
+    /// <value>The culture used when converting a date to and from JSON.</value>
+    public CultureInfo Culture
+    {
+      get { return _culture ?? CultureInfo.CurrentCulture; }
+      set { _culture = value; }
+    }
+
+    /// <summary>
+    /// Writes the JSON representation of the object.
+    /// </summary>
+    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
+    /// <param name="value">The value.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+    {
+      string text;
+
+      if (value is DateTime)
+      {
+        DateTime dateTime = (DateTime)value;
+
+        if ((_dateTimeStyles & DateTimeStyles.AdjustToUniversal) == DateTimeStyles.AdjustToUniversal
+          || (_dateTimeStyles & DateTimeStyles.AssumeUniversal) == DateTimeStyles.AssumeUniversal)
+          dateTime = dateTime.ToUniversalTime();
+
+        text = dateTime.ToString(_dateTimeFormat ?? DefaultDateTimeFormat, Culture);
+      }
+#if !PocketPC && !NET20
+      else if (value is DateTimeOffset)
+      {
+        DateTimeOffset dateTimeOffset = (DateTimeOffset)value;
+        if ((_dateTimeStyles & DateTimeStyles.AdjustToUniversal) == DateTimeStyles.AdjustToUniversal
+          || (_dateTimeStyles & DateTimeStyles.AssumeUniversal) == DateTimeStyles.AssumeUniversal)
+          dateTimeOffset = dateTimeOffset.ToUniversalTime();
+
+        text = dateTimeOffset.ToString(_dateTimeFormat ?? DefaultDateTimeFormat, Culture);
+      }
+#endif
+      else
+      {
+        throw new JsonSerializationException("Unexpected value when converting date. Expected DateTime or DateTimeOffset, got {0}.".FormatWith(CultureInfo.InvariantCulture, ReflectionUtils.GetObjectType(value)));
+      }
+
+      writer.WriteValue(text);
+    }
+
+    /// <summary>
+    /// Reads the JSON representation of the object.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
+    /// <param name="objectType">Type of the object.</param>
+    /// <param name="existingValue">The existing value of object being read.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    /// <returns>The object value.</returns>
+    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+    {
+      bool nullable = ReflectionUtils.IsNullableType(objectType);
+      Type t = (nullable)
+        ? Nullable.GetUnderlyingType(objectType)
+        : objectType;
+
+      if (reader.TokenType == JsonToken.Null)
+      {
+        if (!ReflectionUtils.IsNullableType(objectType))
+          throw JsonSerializationException.Create(reader, "Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType));
+ 
+        return null;
+      }
+
+      if (reader.TokenType == JsonToken.Date)
+      {
+#if !PocketPC && !NET20
+        if (t == typeof(DateTimeOffset))
+          return new DateTimeOffset((DateTime)reader.Value);
+#endif
+
+        return reader.Value;
+      }
+
+      if (reader.TokenType != JsonToken.String)
+        throw JsonSerializationException.Create(reader, "Unexpected token parsing date. Expected String, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
+
+      string dateText = reader.Value.ToString();
+
+      if (string.IsNullOrEmpty(dateText) && nullable)
+        return null;
+
+#if !PocketPC && !NET20
+      if (t == typeof(DateTimeOffset))
+      {
+        if (!string.IsNullOrEmpty(_dateTimeFormat))
+          return DateTimeOffset.ParseExact(dateText, _dateTimeFormat, Culture, _dateTimeStyles);
+        else
+          return DateTimeOffset.Parse(dateText, Culture, _dateTimeStyles);
+      }
+#endif
+
+      if (!string.IsNullOrEmpty(_dateTimeFormat))
+        return DateTime.ParseExact(dateText, _dateTimeFormat, Culture, _dateTimeStyles);
+      else
+        return DateTime.Parse(dateText, Culture, _dateTimeStyles);
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/JavaScriptDateTimeConverter.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/JavaScriptDateTimeConverter.cs
index 4d709db..606a64a 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/JavaScriptDateTimeConverter.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/JavaScriptDateTimeConverter.cs
@@ -1,93 +1,118 @@
-using System;
-using System.Globalization;
-using Newtonsoft.Json.Utilities;
-
-namespace Newtonsoft.Json.Converters
-{
-  /// <summary>
-  /// Converts a <see cref="DateTime"/> to and from a JavaScript date constructor (e.g. new Date(52231943)).
-  /// </summary>
-  public class JavaScriptDateTimeConverter : DateTimeConverterBase
-  {
-    /// <summary>
-    /// Writes the JSON representation of the object.
-    /// </summary>
-    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
-    /// <param name="value">The value.</param>
-    /// <param name="serializer">The calling serializer.</param>
-    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
-    {
-      long ticks;
-
-      if (value is DateTime)
-      {
-        DateTime dateTime = (DateTime)value;
-        DateTime utcDateTime = dateTime.ToUniversalTime();
-        ticks = JsonConvert.ConvertDateTimeToJavaScriptTicks(utcDateTime);
-      }
-#if !PocketPC && !NET20
-      else if (value is DateTimeOffset)
-      {
-        DateTimeOffset dateTimeOffset = (DateTimeOffset)value;
-        DateTimeOffset utcDateTimeOffset = dateTimeOffset.ToUniversalTime();
-        ticks = JsonConvert.ConvertDateTimeToJavaScriptTicks(utcDateTimeOffset.UtcDateTime);
-      }
-#endif
-      else
-      {
-        throw new Exception("Expected date object value.");
-      }
-
-      writer.WriteStartConstructor("Date");
-      writer.WriteValue(ticks);
-      writer.WriteEndConstructor();
-    }
-
-    /// <summary>
-    /// Reads the JSON representation of the object.
-    /// </summary>
-    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
-    /// <param name="objectType">Type of the object.</param>
-    /// <param name="existingValue">The existing property value of the JSON that is being converted.</param>
-    /// <param name="serializer">The calling serializer.</param>
-    /// <returns>The object value.</returns>
-    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
-    {
-      Type t = (ReflectionUtils.IsNullableType(objectType))
-        ? Nullable.GetUnderlyingType(objectType)
-        : objectType;
-
-      if (reader.TokenType == JsonToken.Null)
-      {
-        if (!ReflectionUtils.IsNullableType(objectType))
-          throw new Exception("Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType));
-
-        return null;
-      }
-
-      if (reader.TokenType != JsonToken.StartConstructor || string.Compare(reader.Value.ToString(), "Date", StringComparison.Ordinal) != 0)
-        throw new Exception("Unexpected token or value when parsing date. Token: {0}, Value: {1}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType, reader.Value));
-
-      reader.Read();
-
-      if (reader.TokenType != JsonToken.Integer)
-        throw new Exception("Unexpected token parsing date. Expected Integer, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
-
-      long ticks = (long)reader.Value;
-
-      DateTime d = JsonConvert.ConvertJavaScriptTicksToDateTime(ticks);
-
-      reader.Read();
-
-      if (reader.TokenType != JsonToken.EndConstructor)
-        throw new Exception("Unexpected token parsing date. Expected EndConstructor, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
-
-#if !PocketPC && !NET20
-      if (t == typeof(DateTimeOffset))
-        return new DateTimeOffset(d);
-#endif
-
-      return d;
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Globalization;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Converters
+{
+  /// <summary>
+  /// Converts a <see cref="DateTime"/> to and from a JavaScript date constructor (e.g. new Date(52231943)).
+  /// </summary>
+  public class JavaScriptDateTimeConverter : DateTimeConverterBase
+  {
+    /// <summary>
+    /// Writes the JSON representation of the object.
+    /// </summary>
+    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
+    /// <param name="value">The value.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+    {
+      long ticks;
+
+      if (value is DateTime)
+      {
+        DateTime dateTime = (DateTime)value;
+        DateTime utcDateTime = dateTime.ToUniversalTime();
+        ticks = JsonConvert.ConvertDateTimeToJavaScriptTicks(utcDateTime);
+      }
+#if !PocketPC && !NET20
+      else if (value is DateTimeOffset)
+      {
+        DateTimeOffset dateTimeOffset = (DateTimeOffset)value;
+        DateTimeOffset utcDateTimeOffset = dateTimeOffset.ToUniversalTime();
+        ticks = JsonConvert.ConvertDateTimeToJavaScriptTicks(utcDateTimeOffset.UtcDateTime);
+      }
+#endif
+      else
+      {
+        throw new JsonSerializationException("Expected date object value.");
+      }
+
+      writer.WriteStartConstructor("Date");
+      writer.WriteValue(ticks);
+      writer.WriteEndConstructor();
+    }
+
+    /// <summary>
+    /// Reads the JSON representation of the object.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
+    /// <param name="objectType">Type of the object.</param>
+    /// <param name="existingValue">The existing property value of the JSON that is being converted.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    /// <returns>The object value.</returns>
+    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+    {
+      Type t = (ReflectionUtils.IsNullableType(objectType))
+        ? Nullable.GetUnderlyingType(objectType)
+        : objectType;
+
+      if (reader.TokenType == JsonToken.Null)
+      {
+        if (!ReflectionUtils.IsNullable(objectType))
+          throw JsonSerializationException.Create(reader, "Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType));
+
+        return null;
+      }
+
+      if (reader.TokenType != JsonToken.StartConstructor || !string.Equals(reader.Value.ToString(), "Date", StringComparison.Ordinal))
+        throw JsonSerializationException.Create(reader, "Unexpected token or value when parsing date. Token: {0}, Value: {1}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType, reader.Value));
+
+      reader.Read();
+
+      if (reader.TokenType != JsonToken.Integer)
+        throw JsonSerializationException.Create(reader, "Unexpected token parsing date. Expected Integer, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
+
+      long ticks = (long)reader.Value;
+
+      DateTime d = JsonConvert.ConvertJavaScriptTicksToDateTime(ticks);
+
+      reader.Read();
+
+      if (reader.TokenType != JsonToken.EndConstructor)
+        throw JsonSerializationException.Create(reader, "Unexpected token parsing date. Expected EndConstructor, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
+
+#if !PocketPC && !NET20
+      if (t == typeof(DateTimeOffset))
+        return new DateTimeOffset(d);
+#endif
+
+      return d;
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/JsonDateTimeSerializationMode.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/JsonDateTimeSerializationMode.cs
deleted file mode 100644
index 089b89d..0000000
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/JsonDateTimeSerializationMode.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Newtonsoft.Json.Converters
-{
-  /// <summary>
-  /// Specifies whether a DateTime object represents a local time, a Coordinated Universal Time (UTC), or is not specified as either local time or UTC.
-  /// </summary>
-  public enum JsonDateTimeSerializationMode
-  {
-    /// <summary>
-    /// The time represented is local time.
-    /// </summary>
-    Local,
-    /// <summary>
-    /// The time represented is UTC.
-    /// </summary>
-    Utc,
-    /// <summary>
-    /// The time represented is not specified as either local time or Coordinated Universal Time (UTC).
-    /// </summary>
-    Unspecified,
-    /// <summary>
-    /// Preserves the DateTimeKind field of a date when a DateTime object is converted to a string and the string is then converted back to a DateTime object.
-    /// </summary>
-    RoundtripKind
-  }
-}
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/KeyValuePairConverter.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/KeyValuePairConverter.cs
index e546bdb..17f210e 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/KeyValuePairConverter.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/KeyValuePairConverter.cs
@@ -1,75 +1,141 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Newtonsoft.Json.Utilities;
-using System.Reflection;
-
-namespace Newtonsoft.Json.Converters
-{
-  /// <summary>
-  /// Converts a <see cref="KeyValuePair{TKey,TValue}"/> to and from JSON.
-  /// </summary>
-  public class KeyValuePairConverter : JsonConverter
-  {
-    /// <summary>
-    /// Writes the JSON representation of the object.
-    /// </summary>
-    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
-    /// <param name="value">The value.</param>
-    /// <param name="serializer">The calling serializer.</param>
-    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
-    {
-      Type t = value.GetType();
-      PropertyInfo keyProperty = t.GetProperty("Key");
-      PropertyInfo valueProperty = t.GetProperty("Value");
-
-      writer.WriteStartObject();
-      writer.WritePropertyName("Key");
-      serializer.Serialize(writer, ReflectionUtils.GetMemberValue(keyProperty, value));
-      writer.WritePropertyName("Value");
-      serializer.Serialize(writer, ReflectionUtils.GetMemberValue(valueProperty, value));
-      writer.WriteEndObject();
-    }
-
-    /// <summary>
-    /// Reads the JSON representation of the object.
-    /// </summary>
-    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
-    /// <param name="objectType">Type of the object.</param>
-    /// <param name="existingValue">The existing value of object being read.</param>
-    /// <param name="serializer">The calling serializer.</param>
-    /// <returns>The object value.</returns>
-    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
-    {
-      IList<Type> genericArguments = objectType.GetGenericArguments();
-      Type keyType = genericArguments[0];
-      Type valueType = genericArguments[1];
-
-      reader.Read();
-      reader.Read();
-      object key = serializer.Deserialize(reader, keyType);
-      reader.Read();
-      reader.Read();
-      object value = serializer.Deserialize(reader, valueType);
-      reader.Read();
-
-      return ReflectionUtils.CreateInstance(objectType, key, value);
-    }
-
-    /// <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)
-    {
-      if (objectType.IsValueType && objectType.IsGenericType)
-        return (objectType.GetGenericTypeDefinition() == typeof (KeyValuePair<,>));
-
-      return false;
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using Newtonsoft.Json.Serialization;
+using Newtonsoft.Json.Utilities;
+using System.Reflection;
+
+namespace Newtonsoft.Json.Converters
+{
+  /// <summary>
+  /// Converts a <see cref="KeyValuePair{TKey,TValue}"/> to and from JSON.
+  /// </summary>
+  public class KeyValuePairConverter : JsonConverter
+  {
+    private const string KeyName = "Key";
+    private const string ValueName = "Value";
+
+    /// <summary>
+    /// Writes the JSON representation of the object.
+    /// </summary>
+    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
+    /// <param name="value">The value.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+    {
+      Type t = value.GetType();
+      PropertyInfo keyProperty = t.GetProperty(KeyName);
+      PropertyInfo valueProperty = t.GetProperty(ValueName);
+
+      DefaultContractResolver resolver = serializer.ContractResolver as DefaultContractResolver;
+
+      writer.WriteStartObject();
+
+      writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(KeyName) : KeyName);
+      serializer.Serialize(writer, ReflectionUtils.GetMemberValue(keyProperty, value));
+      writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(ValueName) : ValueName);
+      serializer.Serialize(writer, ReflectionUtils.GetMemberValue(valueProperty, value));
+      writer.WriteEndObject();
+    }
+
+    /// <summary>
+    /// Reads the JSON representation of the object.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
+    /// <param name="objectType">Type of the object.</param>
+    /// <param name="existingValue">The existing value of object being read.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    /// <returns>The object value.</returns>
+    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+    {
+      bool isNullable = ReflectionUtils.IsNullableType(objectType);
+
+      if (reader.TokenType == JsonToken.Null)
+      {
+        if (!isNullable)
+          throw JsonSerializationException.Create(reader, "Cannot convert null value to KeyValuePair.");
+
+        return null;
+      }
+
+      Type t = (isNullable)
+       ? Nullable.GetUnderlyingType(objectType)
+       : objectType;
+
+      IList<Type> genericArguments = t.GetGenericArguments();
+      Type keyType = genericArguments[0];
+      Type valueType = genericArguments[1];
+
+      object key = null;
+      object value = null;
+
+      reader.Read();
+
+      while (reader.TokenType == JsonToken.PropertyName)
+      {
+        string propertyName = reader.Value.ToString();
+        if (string.Equals(propertyName, KeyName, StringComparison.OrdinalIgnoreCase))
+        {
+          reader.Read();
+          key = serializer.Deserialize(reader, keyType);
+        }
+        else if (string.Equals(propertyName, ValueName, StringComparison.OrdinalIgnoreCase))
+        {
+          reader.Read();
+          value = serializer.Deserialize(reader, valueType);
+        }
+        else
+        {
+          reader.Skip();
+        }
+
+        reader.Read();
+      }
+
+      return ReflectionUtils.CreateInstance(t, key, value);
+    }
+
+    /// <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)
+    {
+      Type t = (ReflectionUtils.IsNullableType(objectType))
+        ? Nullable.GetUnderlyingType(objectType)
+        : objectType;
+
+      if (t.IsValueType() && t.IsGenericType())
+        return (t.GetGenericTypeDefinition() == typeof(KeyValuePair<,>));
+
+      return false;
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/RegexConverter.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/RegexConverter.cs
index 72c5c8a..dc70c57 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/RegexConverter.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/RegexConverter.cs
@@ -1,152 +1,174 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Text.RegularExpressions;
-using Newtonsoft.Json.Bson;
-using System.Globalization;
-
-namespace Newtonsoft.Json.Converters
-{
-  /// <summary>
-  /// Converts a <see cref="Regex"/> to and from JSON and BSON.
-  /// </summary>
-  public class RegexConverter : JsonConverter
-  {
-    /// <summary>
-    /// Writes the JSON representation of the object.
-    /// </summary>
-    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
-    /// <param name="value">The value.</param>
-    /// <param name="serializer">The calling serializer.</param>
-    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
-    {
-      Regex regex = (Regex) value;
-
-      BsonWriter bsonWriter = writer as BsonWriter;
-      if (bsonWriter != null)
-        WriteBson(bsonWriter, regex);
-      else
-        WriteJson(writer, regex);
-    }
-
-    private bool HasFlag(RegexOptions options, RegexOptions flag)
-    {
-      return ((options & flag) == flag);
-    }
-
-    private void WriteBson(BsonWriter writer, Regex regex)
-    {
-      // Regular expression - The first cstring is the regex pattern, the second
-      // is the regex options string. Options are identified by characters, which 
-      // must be stored in alphabetical order. Valid options are 'i' for case 
-      // insensitive matching, 'm' for multiline matching, 'x' for verbose mode, 
-      // 'l' to make \w, \W, etc. locale dependent, 's' for dotall mode 
-      // ('.' matches everything), and 'u' to make \w, \W, etc. match unicode.
-
-      string options = null;
-
-      if (HasFlag(regex.Options, RegexOptions.IgnoreCase))
-        options += "i";
-
-      if (HasFlag(regex.Options, RegexOptions.Multiline))
-        options += "m";
-
-      if (HasFlag(regex.Options, RegexOptions.Singleline))
-        options += "s";
-
-      options += "u";
-
-      if (HasFlag(regex.Options, RegexOptions.ExplicitCapture))
-        options += "x";
-
-      writer.WriteRegex(regex.ToString(), options);
-    }
-
-    private void WriteJson(JsonWriter writer, Regex regex)
-    {
-      writer.WriteStartObject();
-      writer.WritePropertyName("Pattern");
-      writer.WriteValue(regex.ToString());
-      writer.WritePropertyName("Options");
-      writer.WriteValue(regex.Options);
-      writer.WriteEndObject();
-    }
-
-    /// <summary>
-    /// Reads the JSON representation of the object.
-    /// </summary>
-    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
-    /// <param name="objectType">Type of the object.</param>
-    /// <param name="existingValue">The existing value of object being read.</param>
-    /// <param name="serializer">The calling serializer.</param>
-    /// <returns>The object value.</returns>
-    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
-    {
-      BsonReader bsonReader = reader as BsonReader;
-
-      if (bsonReader != null)
-        return ReadBson(bsonReader);
-      else
-        return ReadJson(reader);
-    }
-
-    private object ReadBson(BsonReader reader)
-    {
-      string regexText = (string)reader.Value;
-      int patternOptionDelimiterIndex = regexText.LastIndexOf(@"/");
-
-      string patternText = regexText.Substring(1, patternOptionDelimiterIndex - 1);
-      string optionsText = regexText.Substring(patternOptionDelimiterIndex + 1);
-
-      RegexOptions options = RegexOptions.None;
-      foreach (char c in optionsText)
-      {
-        switch (c)
-        {
-          case 'i':
-            options |= RegexOptions.IgnoreCase;
-            break;
-          case 'm':
-            options |= RegexOptions.Multiline;
-            break;
-          case 's':
-            options |= RegexOptions.Singleline;
-            break;
-          case 'x':
-            options |= RegexOptions.ExplicitCapture;
-            break;
-        }
-      }
-
-      return new Regex(patternText, options);
-    }
-
-    private Regex ReadJson(JsonReader reader)
-    {
-      reader.Read();
-      reader.Read();
-      string pattern = (string) reader.Value;
-
-      reader.Read();
-      reader.Read();
-      int options = Convert.ToInt32(reader.Value, CultureInfo.InvariantCulture);
-
-      reader.Read();
-
-      return new Regex(pattern, (RegexOptions)options);
-    }
-
-    /// <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 (Regex));
-    }
-  }
-}
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Text.RegularExpressions;
+using Newtonsoft.Json.Bson;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Converters
+{
+  /// <summary>
+  /// Converts a <see cref="Regex"/> to and from JSON and BSON.
+  /// </summary>
+  public class RegexConverter : JsonConverter
+  {
+    /// <summary>
+    /// Writes the JSON representation of the object.
+    /// </summary>
+    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
+    /// <param name="value">The value.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+    {
+      Regex regex = (Regex) value;
+
+      BsonWriter bsonWriter = writer as BsonWriter;
+      if (bsonWriter != null)
+        WriteBson(bsonWriter, regex);
+      else
+        WriteJson(writer, regex);
+    }
+
+    private bool HasFlag(RegexOptions options, RegexOptions flag)
+    {
+      return ((options & flag) == flag);
+    }
+
+    private void WriteBson(BsonWriter writer, Regex regex)
+    {
+      // Regular expression - The first cstring is the regex pattern, the second
+      // is the regex options string. Options are identified by characters, which 
+      // must be stored in alphabetical order. Valid options are 'i' for case 
+      // insensitive matching, 'm' for multiline matching, 'x' for verbose mode, 
+      // 'l' to make \w, \W, etc. locale dependent, 's' for dotall mode 
+      // ('.' matches everything), and 'u' to make \w, \W, etc. match unicode.
+
+      string options = null;
+
+      if (HasFlag(regex.Options, RegexOptions.IgnoreCase))
+        options += "i";
+
+      if (HasFlag(regex.Options, RegexOptions.Multiline))
+        options += "m";
+
+      if (HasFlag(regex.Options, RegexOptions.Singleline))
+        options += "s";
+
+      options += "u";
+
+      if (HasFlag(regex.Options, RegexOptions.ExplicitCapture))
+        options += "x";
+
+      writer.WriteRegex(regex.ToString(), options);
+    }
+
+    private void WriteJson(JsonWriter writer, Regex regex)
+    {
+      writer.WriteStartObject();
+      writer.WritePropertyName("Pattern");
+      writer.WriteValue(regex.ToString());
+      writer.WritePropertyName("Options");
+      writer.WriteValue(regex.Options);
+      writer.WriteEndObject();
+    }
+
+    /// <summary>
+    /// Reads the JSON representation of the object.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
+    /// <param name="objectType">Type of the object.</param>
+    /// <param name="existingValue">The existing value of object being read.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    /// <returns>The object value.</returns>
+    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+    {
+      BsonReader bsonReader = reader as BsonReader;
+
+      if (bsonReader != null)
+        return ReadBson(bsonReader);
+      else
+        return ReadJson(reader);
+    }
+
+    private object ReadBson(BsonReader reader)
+    {
+      string regexText = (string)reader.Value;
+      int patternOptionDelimiterIndex = regexText.LastIndexOf('/');
+
+      string patternText = regexText.Substring(1, patternOptionDelimiterIndex - 1);
+      string optionsText = regexText.Substring(patternOptionDelimiterIndex + 1);
+
+      RegexOptions options = RegexOptions.None;
+      foreach (char c in optionsText)
+      {
+        switch (c)
+        {
+          case 'i':
+            options |= RegexOptions.IgnoreCase;
+            break;
+          case 'm':
+            options |= RegexOptions.Multiline;
+            break;
+          case 's':
+            options |= RegexOptions.Singleline;
+            break;
+          case 'x':
+            options |= RegexOptions.ExplicitCapture;
+            break;
+        }
+      }
+
+      return new Regex(patternText, options);
+    }
+
+    private Regex ReadJson(JsonReader reader)
+    {
+      reader.Read();
+      reader.Read();
+      string pattern = (string)reader.Value;
+
+      reader.Read();
+      reader.Read();
+      int options = Convert.ToInt32(reader.Value, CultureInfo.InvariantCulture);
+
+      reader.Read();
+
+      return new Regex(pattern, (RegexOptions) options);
+    }
+
+    /// <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 (Regex));
+    }
+  }
+}
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/StringEnumConverter.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/StringEnumConverter.cs
index a299697..59ac00b 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/StringEnumConverter.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/StringEnumConverter.cs
@@ -1,108 +1,198 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Globalization;
-using Newtonsoft.Json.Utilities;
-
-namespace Newtonsoft.Json.Converters
-{
-  /// <summary>
-  /// Converts an <see cref="Enum"/> to and from its name string value.
-  /// </summary>
-  public class StringEnumConverter : JsonConverter
-  {
-
-    /// <summary>
-    /// Writes the JSON representation of the object.
-    /// </summary>
-    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
-    /// <param name="value">The value.</param>
-    /// <param name="serializer">The calling serializer.</param>
-    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
-    {
-      if (value == null)
-      {
-        writer.WriteNull();
-        return;
-      }
-
-      Enum e = (Enum) value;
-      string enumName = e.ToString("G");
-
-      if (char.IsNumber(enumName[0]) || enumName[0] == '-')
-        writer.WriteValue(value);
-      else
-        writer.WriteValue(enumName);
-    }
-
-    /// <summary>
-    /// Reads the JSON representation of the object.
-    /// </summary>
-    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
-    /// <param name="objectType">Type of the object.</param>
-    /// <param name="existingValue">The existing value of object being read.</param>
-    /// <param name="serializer">The calling serializer.</param>
-    /// <returns>The object value.</returns>
-    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
-    {
-      Type t = (ReflectionUtils.IsNullableType(objectType))
-        ? Nullable.GetUnderlyingType(objectType)
-        : objectType;
-
-      if (reader.TokenType == JsonToken.Null)
-      {
-        if (!ReflectionUtils.IsNullableType(objectType))
-          throw new Exception("Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType));
-
-        return null;
-      }
-
-      if (reader.TokenType == JsonToken.String)
-        return Enum.Parse(t, reader.Value.ToString(), true);
-      
-      if (reader.TokenType == JsonToken.Integer)
-        return ConvertUtils.ConvertOrCast(reader.Value, CultureInfo.InvariantCulture, t);
-      
-      throw new Exception("Unexpected token when parsing enum. Expected String or Integer, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
-    }
-
-    /// <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)
-    {
-      Type t = (ReflectionUtils.IsNullableType(objectType))
-        ? Nullable.GetUnderlyingType(objectType)
-        : objectType;
-
-      return t.IsEnum;
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Reflection;
+using System.Runtime.Serialization;
+using Newtonsoft.Json.Utilities;
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#else
+using System.Linq;
+#endif
+
+namespace Newtonsoft.Json.Converters
+{
+  /// <summary>
+  /// Converts an <see cref="Enum"/> to and from its name string value.
+  /// </summary>
+  public class StringEnumConverter : JsonConverter
+  {
+    private readonly Dictionary<Type, BidirectionalDictionary<string, string>> _enumMemberNamesPerType = new Dictionary<Type, BidirectionalDictionary<string, string>>();
+
+    /// <summary>
+    /// Gets or sets a value indicating whether the written enum text should be camel case.
+    /// </summary>
+    /// <value><c>true</c> if the written enum text will be camel case; otherwise, <c>false</c>.</value>
+    public bool CamelCaseText { get; set; }
+    
+    /// <summary>
+    /// Writes the JSON representation of the object.
+    /// </summary>
+    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
+    /// <param name="value">The value.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+    {
+      if (value == null)
+      {
+        writer.WriteNull();
+        return;
+      }
+
+      Enum e = (Enum)value;
+
+      string enumName = e.ToString("G");
+
+      if (char.IsNumber(enumName[0]) || enumName[0] == '-')
+      {
+        writer.WriteValue(value);
+      }
+      else
+      {
+        BidirectionalDictionary<string, string> map = GetEnumNameMap(e.GetType());
+
+        string resolvedEnumName;
+        map.TryGetByFirst(enumName, out resolvedEnumName);
+        resolvedEnumName = resolvedEnumName ?? enumName;
+
+        if (CamelCaseText)
+        {
+          string[] names = resolvedEnumName.Split(',').Select(item => StringUtils.ToCamelCase(item.Trim())).ToArray();
+          resolvedEnumName = string.Join(", ", names);
+        }
+
+        writer.WriteValue(resolvedEnumName);
+      }
+    }
+
+    /// <summary>
+    /// Reads the JSON representation of the object.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
+    /// <param name="objectType">Type of the object.</param>
+    /// <param name="existingValue">The existing value of object being read.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    /// <returns>The object value.</returns>
+    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+    {
+      Type t = (ReflectionUtils.IsNullableType(objectType))
+      ? Nullable.GetUnderlyingType(objectType)
+      : objectType;
+
+      if (reader.TokenType == JsonToken.Null)
+      {
+        if (!ReflectionUtils.IsNullableType(objectType))
+          throw JsonSerializationException.Create(reader, "Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType));
+
+        return null;
+      }
+
+      if (reader.TokenType == JsonToken.String)
+      {
+        var map = GetEnumNameMap(t);
+        string resolvedEnumName;
+        map.TryGetBySecond(reader.Value.ToString(), out resolvedEnumName);
+        resolvedEnumName = resolvedEnumName ?? reader.Value.ToString();
+
+        return Enum.Parse(t, resolvedEnumName, true);
+      }
+
+      if (reader.TokenType == JsonToken.Integer)
+        return ConvertUtils.ConvertOrCast(reader.Value, CultureInfo.InvariantCulture, t);
+
+      throw JsonSerializationException.Create(reader, "Unexpected token when parsing enum. Expected String or Integer, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
+    }
+
+    /// <summary>
+    /// A cached representation of the Enum string representation to respect per Enum field name.
+    /// </summary>
+    /// <param name="t">The type of the Enum.</param>
+    /// <returns>A map of enum field name to either the field name, or the configured enum member name (<see cref="EnumMemberAttribute"/>).</returns>
+    private BidirectionalDictionary<string, string> GetEnumNameMap(Type t)
+    {
+      BidirectionalDictionary<string, string> map;
+
+      if (!_enumMemberNamesPerType.TryGetValue(t, out map))
+      {
+        lock (_enumMemberNamesPerType)
+        {
+          if (_enumMemberNamesPerType.TryGetValue(t, out map))
+            return map;
+
+          map = new BidirectionalDictionary<string, string>(
+            StringComparer.OrdinalIgnoreCase,
+            StringComparer.OrdinalIgnoreCase);
+
+          foreach (FieldInfo f in t.GetFields())
+          {
+            string n1 = f.Name;
+            string n2;
+            
+#if !NET20
+            n2 = f.GetCustomAttributes(typeof (EnumMemberAttribute), true)
+                          .Cast<EnumMemberAttribute>()
+                          .Select(a => a.Value)
+                          .SingleOrDefault() ?? f.Name;
+#else
+            n2 = f.Name;
+#endif
+
+            string s;
+            if (map.TryGetBySecond(n2, out s))
+            {
+              throw new InvalidOperationException("Enum name '{0}' already exists on enum '{1}'."
+                .FormatWith(CultureInfo.InvariantCulture, n2, t.Name));
+            }
+
+            map.Add(n1, n2);
+          }
+
+          _enumMemberNamesPerType[t] = map;
+        }
+      }
+
+      return map;
+    }
+
+    /// <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)
+    {
+      Type t = (ReflectionUtils.IsNullableType(objectType))
+      ? Nullable.GetUnderlyingType(objectType)
+      : objectType;
+
+      return t.IsEnum();
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/VersionConverter.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/VersionConverter.cs
new file mode 100644
index 0000000..f4a5b43
--- /dev/null
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/VersionConverter.cs
@@ -0,0 +1,106 @@
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Globalization;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Converters
+{
+  /// <summary>
+  /// Converts a <see cref="Version"/> to and from a string (e.g. "1.2.3.4").
+  /// </summary>
+  public class VersionConverter : JsonConverter
+  {
+    /// <summary>
+    /// Writes the JSON representation of the object.
+    /// </summary>
+    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
+    /// <param name="value">The value.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+    {
+      if (value == null)
+      {
+        writer.WriteNull();
+      }
+      else if (value is Version)
+      {
+        writer.WriteValue(value.ToString());
+      }
+      else
+      {
+        throw new JsonSerializationException("Expected Version object value");
+      }
+    }
+
+    /// <summary>
+    /// Reads the JSON representation of the object.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
+    /// <param name="objectType">Type of the object.</param>
+    /// <param name="existingValue">The existing property value of the JSON that is being converted.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    /// <returns>The object value.</returns>
+    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+    {
+      if (reader.TokenType == JsonToken.Null)
+      {
+        return null;
+      }
+      else
+      {
+        if (reader.TokenType == JsonToken.String)
+        {
+          try
+          {
+            Version v = new Version((string) reader.Value);
+            return v;
+          }
+          catch (Exception ex)
+          {
+            throw JsonSerializationException.Create(reader, "Error parsing version string: {0}".FormatWith(CultureInfo.InvariantCulture, reader.Value), ex);
+          }
+        }
+        else
+        {
+          throw JsonSerializationException.Create(reader, "Unexpected token or value when parsing version. Token: {0}, Value: {1}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType, reader.Value));
+        }
+      }
+    }
+
+    /// <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 (Version);
+    }
+  }
+}
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs
index c73050c..2bcdeaa 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs
@@ -1,1416 +1,1567 @@
-#region License
-// 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.
-#endregion
-
-#if !SILVERLIGHT
-using System;
-using System.Collections.Generic;
-using System.Xml;
-#if !NET20
-using System.Xml.Linq;
-#endif
-using Newtonsoft.Json.Utilities;
-using System.Linq;
-
-namespace Newtonsoft.Json.Converters
-{
-  #region Wrappers
-  internal class XmlDocumentWrapper : XmlNodeWrapper, IXmlDocument
-  {
-    private XmlDocument _document;
-
-    public XmlDocumentWrapper(XmlDocument document)
-      : base(document)
-    {
-      _document = document;
-    }
-
-    public IXmlNode CreateComment(string data)
-    {
-      return new XmlNodeWrapper(_document.CreateComment(data));
-    }
-
-    public IXmlNode CreateTextNode(string text)
-    {
-      return new XmlNodeWrapper(_document.CreateTextNode(text));
-    }
-
-    public IXmlNode CreateCDataSection(string data)
-    {
-      return new XmlNodeWrapper(_document.CreateCDataSection(data));
-    }
-
-    public IXmlNode CreateWhitespace(string text)
-    {
-      return new XmlNodeWrapper(_document.CreateWhitespace(text));
-    }
-
-    public IXmlNode CreateSignificantWhitespace(string text)
-    {
-      return new XmlNodeWrapper(_document.CreateSignificantWhitespace(text));
-    }
-
-    public IXmlNode CreateXmlDeclaration(string version, string encoding, string standalone)
-    {
-      return new XmlNodeWrapper(_document.CreateXmlDeclaration(version, encoding, standalone));
-    }
-
-    public IXmlNode CreateProcessingInstruction(string target, string data)
-    {
-      return new XmlNodeWrapper(_document.CreateProcessingInstruction(target, data));
-    }
-
-    public IXmlElement CreateElement(string elementName)
-    {
-      return new XmlElementWrapper(_document.CreateElement(elementName));
-    }
-
-    public IXmlElement CreateElement(string qualifiedName, string namespaceURI)
-    {
-      return new XmlElementWrapper(_document.CreateElement(qualifiedName, namespaceURI));
-    }
-
-    public IXmlNode CreateAttribute(string name, string value)
-    {
-      XmlNodeWrapper attribute = new XmlNodeWrapper(_document.CreateAttribute(name));
-      attribute.Value = value;
-
-      return attribute;
-    }
-
-    public IXmlNode CreateAttribute(string qualifiedName, string namespaceURI, string value)
-    {
-      XmlNodeWrapper attribute = new XmlNodeWrapper(_document.CreateAttribute(qualifiedName, namespaceURI));
-      attribute.Value = value;
-
-      return attribute;
-    }
-
-    public IXmlElement DocumentElement
-    {
-      get
-      {
-        if (_document.DocumentElement == null)
-          return null;
-
-        return new XmlElementWrapper(_document.DocumentElement);
-      }
-    }
-  }
-
-  internal class XmlElementWrapper : XmlNodeWrapper, IXmlElement
-  {
-    private XmlElement _element;
-
-    public XmlElementWrapper(XmlElement element)
-      : base(element)
-    {
-      _element = element;
-    }
-
-    public void SetAttributeNode(IXmlNode attribute)
-    {
-      XmlNodeWrapper xmlAttributeWrapper = (XmlNodeWrapper)attribute;
-
-      _element.SetAttributeNode((XmlAttribute) xmlAttributeWrapper.WrappedNode);
-    }
-  }
-
-  internal class XmlDeclarationWrapper : XmlNodeWrapper, IXmlDeclaration
-  {
-    private XmlDeclaration _declaration;
-
-    public XmlDeclarationWrapper(XmlDeclaration declaration)
-      : base(declaration)
-    {
-      _declaration = declaration;
-    }
-
-    public string Version
-    {
-      get { return _declaration.Version; }
-    }
-
-    public string Encoding
-    {
-      get { return _declaration.Encoding; }
-      set { _declaration.Encoding = value; }
-    }
-
-    public string Standalone
-    {
-      get { return _declaration.Standalone; }
-      set { _declaration.Standalone = value; }
-    }
-  }
-
-  internal class XmlNodeWrapper : IXmlNode
-  {
-    private readonly XmlNode _node;
-
-    public XmlNodeWrapper(XmlNode node)
-    {
-      _node = node;
-    }
-
-    public object WrappedNode
-    {
-      get { return _node; }
-    }
-
-    public XmlNodeType NodeType
-    {
-      get { return _node.NodeType; }
-    }
-
-    public string Name
-    {
-      get { return _node.Name; }
-    }
-
-    public string LocalName
-    {
-      get { return _node.LocalName; }
-    }
-
-    public IList<IXmlNode> ChildNodes
-    {
-      get { return _node.ChildNodes.Cast<XmlNode>().Select(n => WrapNode(n)).ToList(); }
-    }
-
-    private IXmlNode WrapNode(XmlNode node)
-    {
-      switch (node.NodeType)
-      {
-        case XmlNodeType.Element:
-          return new XmlElementWrapper((XmlElement) node);
-        case XmlNodeType.XmlDeclaration:
-          return new XmlDeclarationWrapper((XmlDeclaration) node);
-        default:
-          return new XmlNodeWrapper(node);
-      }
-    }
-
-    public IList<IXmlNode> Attributes
-    {
-      get
-      {
-        if (_node.Attributes == null)
-          return null;
-
-        return _node.Attributes.Cast<XmlAttribute>().Select(a => WrapNode(a)).ToList();
-      }
-    }
-
-    public IXmlNode ParentNode
-    {
-      get
-      {
-        XmlNode node = (_node is XmlAttribute)
-                         ? ((XmlAttribute) _node).OwnerElement
-                         : _node.ParentNode;
-        
-        if (node == null)
-          return null;
-
-        return WrapNode(node);
-      }
-    }
-
-    public string Value
-    {
-      get { return _node.Value; }
-      set { _node.Value = value; }
-    }
-
-    public IXmlNode AppendChild(IXmlNode newChild)
-    {
-      XmlNodeWrapper xmlNodeWrapper = (XmlNodeWrapper) newChild;
-      _node.AppendChild(xmlNodeWrapper._node);
-
-      return newChild;
-    }
-
-    public string Prefix
-    {
-      get { return _node.Prefix; }
-    }
-
-    public string NamespaceURI
-    {
-      get { return _node.NamespaceURI; }
-    }
-  }
-
-  internal interface IXmlDocument : IXmlNode
-  {
-    IXmlNode CreateComment(string text);
-    IXmlNode CreateTextNode(string text);
-    IXmlNode CreateCDataSection(string data);
-    IXmlNode CreateWhitespace(string text);
-    IXmlNode CreateSignificantWhitespace(string text);
-    IXmlNode CreateXmlDeclaration(string version, string encoding, string standalone);
-    IXmlNode CreateProcessingInstruction(string target, string data);
-    IXmlElement CreateElement(string elementName);
-    IXmlElement CreateElement(string qualifiedName, string namespaceURI);
-    IXmlNode CreateAttribute(string name, string value);
-    IXmlNode CreateAttribute(string qualifiedName, string namespaceURI, string value);
-
-    IXmlElement DocumentElement { get; }
-  }
-
-  internal interface IXmlDeclaration : IXmlNode
-  {
-    string Version { get; }
-    string Encoding { get; set; }
-    string Standalone { get; set; }
-  }
-
-  internal interface IXmlElement : IXmlNode
-  {
-    void SetAttributeNode(IXmlNode attribute);
-  }
-
-  internal interface IXmlNode
-  {
-    XmlNodeType NodeType { get; }
-    string LocalName { get; }
-    IList<IXmlNode> ChildNodes { get; }
-    IList<IXmlNode> Attributes { get; }
-    IXmlNode ParentNode { get; }
-    string Value { get; set; }
-    IXmlNode AppendChild(IXmlNode newChild);
-    string NamespaceURI { get; }
-    object WrappedNode { get; }
-  }
-
-  #if !NET20
-  internal class XDeclarationWrapper : XObjectWrapper, IXmlDeclaration
-  {
-    internal readonly XDeclaration _declaration;
-
-    public XDeclarationWrapper(XDeclaration declaration)
-      : base(null)
-    {
-      _declaration = declaration;
-    }
-
-    public override XmlNodeType NodeType
-    {
-      get { return XmlNodeType.XmlDeclaration; }
-    }
-
-    public string Version
-    {
-      get { return _declaration.Version; }
-    }
-
-    public string Encoding
-    {
-      get { return _declaration.Encoding; }
-      set { _declaration.Encoding = value; }
-    }
-
-    public string Standalone
-    {
-      get { return _declaration.Standalone; }
-      set { _declaration.Standalone = value; }
-    }
-  }
-
-  internal class XDocumentWrapper : XContainerWrapper, IXmlDocument
-  {
-    private XDocument Document
-    {
-      get { return (XDocument)WrappedNode; }
-    }
-
-    public XDocumentWrapper(XDocument document)
-      : base(document)
-    {
-    }
-
-    public override IList<IXmlNode> ChildNodes
-    {
-      get
-      {
-        IList<IXmlNode> childNodes = base.ChildNodes;
-
-        if (Document.Declaration != null)
-          childNodes.Insert(0, new XDeclarationWrapper(Document.Declaration));
-
-        return childNodes;
-      }
-    }
-
-    public IXmlNode CreateComment(string text)
-    {
-      return new XObjectWrapper(new XComment(text));
-    }
-
-    public IXmlNode CreateTextNode(string text)
-    {
-      return new XObjectWrapper(new XText(text));
-    }
-
-    public IXmlNode CreateCDataSection(string data)
-    {
-      return new XObjectWrapper(new XCData(data));
-    }
-
-    public IXmlNode CreateWhitespace(string text)
-    {
-      return new XObjectWrapper(new XText(text));
-    }
-
-    public IXmlNode CreateSignificantWhitespace(string text)
-    {
-      return new XObjectWrapper(new XText(text));
-    }
-
-    public IXmlNode CreateXmlDeclaration(string version, string encoding, string standalone)
-    {
-      return new XDeclarationWrapper(new XDeclaration(version, encoding, standalone));
-    }
-
-    public IXmlNode CreateProcessingInstruction(string target, string data)
-    {
-      return new XProcessingInstructionWrapper(new XProcessingInstruction(target, data));
-    }
-
-    public IXmlElement CreateElement(string elementName)
-    {
-      return new XElementWrapper(new XElement(elementName));
-    }
-
-    public IXmlElement CreateElement(string qualifiedName, string namespaceURI)
-    {
-      string localName = MiscellaneousUtils.GetLocalName(qualifiedName);
-      return new XElementWrapper(new XElement(XName.Get(localName, namespaceURI)));
-    }
-
-    public IXmlNode CreateAttribute(string name, string value)
-    {
-      return new XAttributeWrapper(new XAttribute(name, value));
-    }
-
-    public IXmlNode CreateAttribute(string qualifiedName, string namespaceURI, string value)
-    {
-      string localName = MiscellaneousUtils.GetLocalName(qualifiedName);
-      return new XAttributeWrapper(new XAttribute(XName.Get(localName, namespaceURI), value));
-    }
-
-    public IXmlElement DocumentElement
-    {
-      get
-      {
-        if (Document.Root == null)
-          return null;
-
-        return new XElementWrapper(Document.Root);
-      }
-    }
-
-    public override IXmlNode AppendChild(IXmlNode newChild)
-    {
-      XDeclarationWrapper declarationWrapper = newChild as XDeclarationWrapper;
-      if (declarationWrapper != null)
-      {
-        Document.Declaration = declarationWrapper._declaration;
-        return declarationWrapper;
-      }
-      else
-      {
-        return base.AppendChild(newChild);
-      }
-    }
-  }
-
-  internal class XTextWrapper : XObjectWrapper
-  {
-    private XText Text
-    {
-      get { return (XText)WrappedNode; }
-    }
-
-    public XTextWrapper(XText text)
-      : base(text)
-    {
-    }
-
-    public override string Value
-    {
-      get { return Text.Value; }
-      set { Text.Value = value; }
-    }
-
-    public override IXmlNode ParentNode
-    {
-      get
-      {
-        if (Text.Parent == null)
-          return null;
-        
-        return XContainerWrapper.WrapNode(Text.Parent);
-      }
-    }
-  }
-
-  internal class XCommentWrapper : XObjectWrapper
-  {
-    private XComment Text
-    {
-      get { return (XComment)WrappedNode; }
-    }
-
-    public XCommentWrapper(XComment text)
-      : base(text)
-    {
-    }
-
-    public override string Value
-    {
-      get { return Text.Value; }
-      set { Text.Value = value; }
-    }
-
-    public override IXmlNode ParentNode
-    {
-      get
-      {
-        if (Text.Parent == null)
-          return null;
-
-        return XContainerWrapper.WrapNode(Text.Parent);
-      }
-    }
-  }
-
-  internal class XProcessingInstructionWrapper : XObjectWrapper
-  {
-    private XProcessingInstruction ProcessingInstruction
-    {
-      get { return (XProcessingInstruction)WrappedNode; }
-    }
-
-    public XProcessingInstructionWrapper(XProcessingInstruction processingInstruction)
-      : base(processingInstruction)
-    {
-    }
-
-    public override string LocalName
-    {
-      get { return ProcessingInstruction.Target; }
-    }
-
-    public override string Value
-    {
-      get { return ProcessingInstruction.Data; }
-      set { ProcessingInstruction.Data = value; }
-    }
-  }
-
-  internal class XContainerWrapper : XObjectWrapper
-  {
-    private XContainer Container
-    {
-      get { return (XContainer)WrappedNode; }
-    }
-
-    public XContainerWrapper(XContainer container)
-      : base(container)
-    {
-    }
-
-    public override IList<IXmlNode> ChildNodes
-    {
-      get { return Container.Nodes().Select(n => WrapNode(n)).ToList(); }
-    }
-
-    public override IXmlNode ParentNode
-    {
-      get
-      {
-        if (Container.Parent == null)
-          return null;
-        
-        return WrapNode(Container.Parent);
-      }
-    }
-
-    internal static IXmlNode WrapNode(XObject node)
-    {
-      if (node is XDocument)
-        return new XDocumentWrapper((XDocument)node);
-      else if (node is XElement)
-        return new XElementWrapper((XElement)node);
-      else if (node is XContainer)
-        return new XContainerWrapper((XContainer)node);
-      else if (node is XProcessingInstruction)
-        return new XProcessingInstructionWrapper((XProcessingInstruction)node);
-      else if (node is XText)
-        return new XTextWrapper((XText)node);
-      else if (node is XComment)
-        return new XCommentWrapper((XComment)node);
-      else if (node is XAttribute)
-        return new XAttributeWrapper((XAttribute) node);
-      else
-        return new XObjectWrapper(node);
-    }
-
-    public override IXmlNode AppendChild(IXmlNode newChild)
-    {
-      Container.Add(newChild.WrappedNode);
-      return newChild;
-    }
-  }
-
-  internal class XObjectWrapper : IXmlNode
-  {
-    private readonly XObject _xmlObject;
-
-    public XObjectWrapper(XObject xmlObject)
-    {
-      _xmlObject = xmlObject;
-    }
-
-    public object WrappedNode
-    {
-      get { return _xmlObject; }
-    }
-
-    public virtual XmlNodeType NodeType
-    {
-      get { return _xmlObject.NodeType; }
-    }
-
-    public virtual string LocalName
-    {
-      get { return null; }
-    }
-
-    public virtual IList<IXmlNode> ChildNodes
-    {
-      get { return new List<IXmlNode>(); }
-    }
-
-    public virtual IList<IXmlNode> Attributes
-    {
-      get { return null; }
-    }
-
-    public virtual IXmlNode ParentNode
-    {
-      get { return null; }
-    }
-
-    public virtual string Value
-    {
-      get { return null; }
-      set { throw new InvalidOperationException(); }
-    }
-
-    public virtual IXmlNode AppendChild(IXmlNode newChild)
-    {
-      throw new InvalidOperationException();
-    }
-
-    public virtual string NamespaceURI
-    {
-      get { return null; }
-    }
-  }
-
-  internal class XAttributeWrapper : XObjectWrapper
-  {
-    private XAttribute Attribute
-    {
-      get { return (XAttribute)WrappedNode; }
-    }
-
-    public XAttributeWrapper(XAttribute attribute)
-      : base(attribute)
-    {
-    }
-
-    public override string Value
-    {
-      get { return Attribute.Value; }
-      set { Attribute.Value = value; }
-    }
-
-    public override string LocalName
-    {
-      get { return Attribute.Name.LocalName; }
-    }
-
-    public override string NamespaceURI
-    {
-      get { return Attribute.Name.NamespaceName; }
-    }
-
-    public override IXmlNode ParentNode
-    {
-      get
-      {
-        if (Attribute.Parent == null)
-          return null;
-
-        return XContainerWrapper.WrapNode(Attribute.Parent);
-      }
-    }
-  }
-
-  internal class XElementWrapper : XContainerWrapper, IXmlElement
-  {
-    private XElement Element
-    {
-      get { return (XElement) WrappedNode; }
-    }
-
-    public XElementWrapper(XElement element)
-      : base(element)
-    {
-    }
-
-    public void SetAttributeNode(IXmlNode attribute)
-    {
-      XObjectWrapper wrapper = (XObjectWrapper)attribute;
-      Element.Add(wrapper.WrappedNode);
-    }
-
-    public override IList<IXmlNode> Attributes
-    {
-      get { return Element.Attributes().Select(a => new XAttributeWrapper(a)).Cast<IXmlNode>().ToList(); }
-    }
-
-    public override string Value
-    {
-      get { return Element.Value; }
-      set { Element.Value = value; }
-    }
-
-    public override string LocalName
-    {
-      get { return Element.Name.LocalName; }
-    }
-
-    public override string NamespaceURI
-    {
-      get { return Element.Name.NamespaceName; }
-    }
-  }
-#endif
-  #endregion
-
-  /// <summary>
-  /// Converts an <see cref="XmlNode"/> to and from JSON.
-  /// </summary>
-  public class XmlNodeConverter : JsonConverter
-  {
-    private const string TextName = "#text";
-    private const string CommentName = "#comment";
-    private const string CDataName = "#cdata-section";
-    private const string WhitespaceName = "#whitespace";
-    private const string SignificantWhitespaceName = "#significant-whitespace";
-    private const string DeclarationName = "?xml";
-    private const string JsonNamespaceUri = "http://james.newtonking.com/projects/json";
-
-    /// <summary>
-    /// Gets or sets the name of the root element to insert when deserializing to XML if the JSON structure has produces multiple root elements.
-    /// </summary>
-    /// <value>The name of the deserialize root element.</value>
-    public string DeserializeRootElementName { get; set; }
-
-    #region Writing
-    /// <summary>
-    /// Writes the JSON representation of the object.
-    /// </summary>
-    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
-    /// <param name="serializer">The calling serializer.</param>
-    /// <param name="value">The value.</param>
-    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
-    {
-      IXmlNode node;
-
-      if (value is XmlNode)
-        node = new XmlNodeWrapper((XmlNode)value);
-#if !NET20
-      else if (value is XObject)
-        node = XContainerWrapper.WrapNode((XObject)value);
-#endif
-      else
-        throw new ArgumentException("Value must be an XmlNode", "value");
-
-      XmlNamespaceManager manager = new XmlNamespaceManager(new NameTable());
-      PushParentNamespaces(node, manager);
-
-      writer.WriteStartObject();
-      SerializeNode(writer, node, manager, true);
-      writer.WriteEndObject();
-    }
-
-    private void PushParentNamespaces(IXmlNode node, XmlNamespaceManager manager)
-    {
-      List<IXmlNode> parentElements = null;
-
-      IXmlNode parent = node;
-      while ((parent = parent.ParentNode) != null)
-      {
-        if (parent.NodeType == XmlNodeType.Element)
-        {
-          if (parentElements == null)
-            parentElements = new List<IXmlNode>();
-
-          parentElements.Add(parent);
-        }
-      }
-
-      if (parentElements != null)
-      {
-        parentElements.Reverse();
-
-        foreach (IXmlNode parentElement in parentElements)
-        {
-          manager.PushScope();
-          foreach (IXmlNode attribute in parentElement.Attributes)
-          {
-            if (attribute.NamespaceURI == "http://www.w3.org/2000/xmlns/" && attribute.LocalName != "xmlns")
-              manager.AddNamespace(attribute.LocalName, attribute.Value);
-          }
-        }
-      }
-    }
-
-    private string ResolveFullName(IXmlNode node, XmlNamespaceManager manager)
-    {
-      string prefix = (node.NamespaceURI == null || (node.LocalName == "xmlns" && node.NamespaceURI == "http://www.w3.org/2000/xmlns/"))
-                        ? null
-                        : manager.LookupPrefix(node.NamespaceURI);
-
-      if (!string.IsNullOrEmpty(prefix))
-        return prefix + ":" + node.LocalName;
-      else
-        return node.LocalName;
-    }
-
-    private string GetPropertyName(IXmlNode node, XmlNamespaceManager manager)
-    {
-      switch (node.NodeType)
-      {
-        case XmlNodeType.Attribute:
-          if (node.NamespaceURI == JsonNamespaceUri)
-            return "$" + node.LocalName;
-          else
-            return "@" + ResolveFullName(node, manager);
-        case XmlNodeType.CDATA:
-          return CDataName;
-        case XmlNodeType.Comment:
-          return CommentName;
-        case XmlNodeType.Element:
-          return ResolveFullName(node, manager);
-        case XmlNodeType.ProcessingInstruction:
-          return "?" + ResolveFullName(node, manager);
-        case XmlNodeType.XmlDeclaration:
-          return DeclarationName;
-        case XmlNodeType.SignificantWhitespace:
-          return SignificantWhitespaceName;
-        case XmlNodeType.Text:
-          return TextName;
-        case XmlNodeType.Whitespace:
-          return WhitespaceName;
-        default:
-          throw new JsonSerializationException("Unexpected XmlNodeType when getting node name: " + node.NodeType);
-      }
-    }
-
-    private void SerializeGroupedNodes(JsonWriter writer, IXmlNode node, XmlNamespaceManager manager)
-    {
-      // group nodes together by name
-      Dictionary<string, List<IXmlNode>> nodesGroupedByName = new Dictionary<string, List<IXmlNode>>();
-
-      for (int i = 0; i < node.ChildNodes.Count; i++)
-      {
-        IXmlNode childNode = node.ChildNodes[i];
-        string nodeName = GetPropertyName(childNode, manager);
-
-        List<IXmlNode> nodes;
-        if (!nodesGroupedByName.TryGetValue(nodeName, out nodes))
-        {
-          nodes = new List<IXmlNode>();
-          nodesGroupedByName.Add(nodeName, nodes);
-        }
-
-        nodes.Add(childNode);
-      }
-
-      // loop through grouped nodes. write single name instances as normal,
-      // write multiple names together in an array
-      foreach (KeyValuePair<string, List<IXmlNode>> nodeNameGroup in nodesGroupedByName)
-      {
-        List<IXmlNode> groupedNodes = nodeNameGroup.Value;
-        bool writeArray;
-
-        if (groupedNodes.Count == 1)
-        {
-          IXmlNode singleNode = groupedNodes[0];
-          IXmlNode jsonArrayAttribute = (singleNode.Attributes != null)
-            ? singleNode.Attributes.SingleOrDefault(a => a.LocalName == "Array" && a.NamespaceURI == JsonNamespaceUri)
-            : null;
-          if (jsonArrayAttribute != null)
-            writeArray = XmlConvert.ToBoolean(jsonArrayAttribute.Value);
-          else
-            writeArray = false;
-        }
-        else
-        {
-          writeArray = true;
-        }
-
-        if (!writeArray)
-        {
-          SerializeNode(writer, groupedNodes[0], manager, true);
-        }
-        else
-        {
-          string elementNames = nodeNameGroup.Key;
-          writer.WritePropertyName(elementNames);
-          writer.WriteStartArray();
-
-          for (int i = 0; i < groupedNodes.Count; i++)
-          {
-            SerializeNode(writer, groupedNodes[i], manager, false);
-          }
-
-          writer.WriteEndArray();
-        }
-      }
-    }
-
-    private void SerializeNode(JsonWriter writer, IXmlNode node, XmlNamespaceManager manager, bool writePropertyName)
-    {
-      switch (node.NodeType)
-      {
-        case XmlNodeType.Document:
-        case XmlNodeType.DocumentFragment:
-          SerializeGroupedNodes(writer, node, manager);
-          break;
-        case XmlNodeType.Element:
-          foreach (IXmlNode attribute in node.Attributes)
-          {
-            if (attribute.NamespaceURI == "http://www.w3.org/2000/xmlns/")
-            {
-              string prefix = (attribute.LocalName != "xmlns")
-                                ? attribute.LocalName
-                                : string.Empty;
-
-              manager.AddNamespace(prefix, attribute.Value);
-            }
-          }
-
-          if (writePropertyName)
-            writer.WritePropertyName(GetPropertyName(node, manager));
-
-          if (ValueAttributes(node.Attributes).Count() == 0 && node.ChildNodes.Count == 1
-                  && node.ChildNodes[0].NodeType == XmlNodeType.Text)
-          {
-            // write elements with a single text child as a name value pair
-            writer.WriteValue(node.ChildNodes[0].Value);
-          }
-          else if (node.ChildNodes.Count == 0 && CollectionUtils.IsNullOrEmpty(node.Attributes))
-          {
-            // empty element
-            writer.WriteNull();
-          }
-          else
-          {
-            writer.WriteStartObject();
-
-            for (int i = 0; i < node.Attributes.Count; i++)
-            {
-              SerializeNode(writer, node.Attributes[i], manager, true);
-            }
-
-            SerializeGroupedNodes(writer, node, manager);
-
-            writer.WriteEndObject();
-          }
-
-          break;
-        case XmlNodeType.Comment:
-          if (writePropertyName)
-            writer.WriteComment(node.Value);
-          break;
-        case XmlNodeType.Attribute:
-        case XmlNodeType.Text:
-        case XmlNodeType.CDATA:
-        case XmlNodeType.ProcessingInstruction:
-        case XmlNodeType.Whitespace:
-        case XmlNodeType.SignificantWhitespace:
-          if (node.NamespaceURI == "http://www.w3.org/2000/xmlns/" && node.Value == JsonNamespaceUri)
-            return;
-
-          if (node.NamespaceURI == JsonNamespaceUri)
-          {
-            if (node.LocalName == "Array")
-              return;
-          }
-
-          if (writePropertyName)
-            writer.WritePropertyName(GetPropertyName(node, manager));
-          writer.WriteValue(node.Value);
-          break;
-        case XmlNodeType.XmlDeclaration:
-          IXmlDeclaration declaration = (IXmlDeclaration)node;
-          writer.WritePropertyName(GetPropertyName(node, manager));
-          writer.WriteStartObject();
-
-          if (!string.IsNullOrEmpty(declaration.Version))
-          {
-            writer.WritePropertyName("@version");
-            writer.WriteValue(declaration.Version);
-          }
-          if (!string.IsNullOrEmpty(declaration.Encoding))
-          {
-            writer.WritePropertyName("@encoding");
-            writer.WriteValue(declaration.Encoding);
-          }
-          if (!string.IsNullOrEmpty(declaration.Standalone))
-          {
-            writer.WritePropertyName("@standalone");
-            writer.WriteValue(declaration.Standalone);
-          }
-
-          writer.WriteEndObject();
-          break;
-        default:
-          throw new JsonSerializationException("Unexpected XmlNodeType when serializing nodes: " + node.NodeType);
-      }
-    }
-    #endregion
-
-    #region Reading
-    /// <summary>
-    /// Reads the JSON representation of the object.
-    /// </summary>
-    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
-    /// <param name="objectType">Type of the object.</param>
-    /// <param name="existingValue">The existing value of object being read.</param>
-    /// <param name="serializer">The calling serializer.</param>
-    /// <returns>The object value.</returns>
-    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
-    {
-      XmlNamespaceManager manager = new XmlNamespaceManager(new NameTable());
-      IXmlDocument document;
-      IXmlNode rootNode;
-
-      if (typeof (XmlNode).IsAssignableFrom(objectType))
-      {
-        if (objectType != typeof (XmlDocument))
-          throw new JsonSerializationException("XmlNodeConverter only supports deserializing XmlDocuments");
-
-        XmlDocument d = new XmlDocument();
-        document = new XmlDocumentWrapper(d);
-        rootNode = document;
-      }
-#if !NET20
-      else if (typeof(XObject).IsAssignableFrom(objectType))
-      {
-        if (objectType != typeof (XDocument) && objectType != typeof (XElement))
-          throw new JsonSerializationException("XmlNodeConverter only supports deserializing XDocument or XElement.");
-
-        XDocument d = new XDocument();
-        document = new XDocumentWrapper(d);
-        rootNode = document;
-      }
-#endif
-      else
-      {
-        throw new JsonSerializationException("Unexpected type when converting XML: " + objectType);
-      }
-
-      if (reader.TokenType != JsonToken.StartObject)
-        throw new JsonSerializationException("XmlNodeConverter can only convert JSON that begins with an object.");
-
-      if (!string.IsNullOrEmpty(DeserializeRootElementName))
-      {
-        //rootNode = document.CreateElement(DeserializeRootElementName);
-        //document.AppendChild(rootNode);
-        ReadElement(reader, document, rootNode, DeserializeRootElementName, manager);
-      }
-      else
-      {
-        reader.Read();
-        DeserializeNode(reader, document, manager, rootNode);
-      }
-
-#if !NET20
-      if (objectType == typeof(XElement))
-      {
-        XElement element = (XElement)document.DocumentElement.WrappedNode;
-        element.Remove();
-
-        return element;
-      }
-#endif
-
-      return document.WrappedNode;
-    }
-
-    private void DeserializeValue(JsonReader reader, IXmlDocument document, XmlNamespaceManager manager, string propertyName, IXmlNode currentNode)
-    {
-      switch (propertyName)
-      {
-        case TextName:
-          currentNode.AppendChild(document.CreateTextNode(reader.Value.ToString()));
-          break;
-        case CDataName:
-          currentNode.AppendChild(document.CreateCDataSection(reader.Value.ToString()));
-          break;
-        case WhitespaceName:
-          currentNode.AppendChild(document.CreateWhitespace(reader.Value.ToString()));
-          break;
-        case SignificantWhitespaceName:
-          currentNode.AppendChild(document.CreateSignificantWhitespace(reader.Value.ToString()));
-          break;
-        default:
-          // processing instructions and the xml declaration start with ?
-          if (!string.IsNullOrEmpty(propertyName) && propertyName[0] == '?')
-          {
-            CreateInstruction(reader, document, currentNode, propertyName);
-          }
-          else
-          {
-            if (reader.TokenType == JsonToken.StartArray)
-            {
-              ReadArrayElements(reader, document, propertyName, currentNode, manager);
-              return;
-            }
-
-            // have to wait until attributes have been parsed before creating element
-            // attributes may contain namespace info used by the element
-            ReadElement(reader, document, currentNode, propertyName, manager);
-          }
-          break;
-      }
-    }
-
-    private void ReadElement(JsonReader reader, IXmlDocument document, IXmlNode currentNode, string propertyName, XmlNamespaceManager manager)
-    {
-      Dictionary<string, string> attributeNameValues = ReadAttributeElements(reader, manager);
-
-      string elementPrefix = MiscellaneousUtils.GetPrefix(propertyName);
-
-      IXmlElement element = CreateElement(propertyName, document, elementPrefix, manager);
-
-      currentNode.AppendChild(element);
-
-      // add attributes to newly created element
-      foreach (KeyValuePair<string, string> nameValue in attributeNameValues)
-      {
-        string attributePrefix = MiscellaneousUtils.GetPrefix(nameValue.Key);
-
-        IXmlNode attribute = (!string.IsNullOrEmpty(attributePrefix))
-                               ? document.CreateAttribute(nameValue.Key, manager.LookupNamespace(attributePrefix), nameValue.Value)
-                               : document.CreateAttribute(nameValue.Key, nameValue.Value);
-
-        element.SetAttributeNode(attribute);
-      }
-
-      if (reader.TokenType == JsonToken.String)
-      {
-        element.AppendChild(document.CreateTextNode(reader.Value.ToString()));
-      }
-      else if (reader.TokenType == JsonToken.Integer)
-      {
-        element.AppendChild(document.CreateTextNode(XmlConvert.ToString((long)reader.Value)));
-      }
-      else if (reader.TokenType == JsonToken.Float)
-      {
-        element.AppendChild(document.CreateTextNode(XmlConvert.ToString((double)reader.Value)));
-      }
-      else if (reader.TokenType == JsonToken.Boolean)
-      {
-        element.AppendChild(document.CreateTextNode(XmlConvert.ToString((bool)reader.Value)));
-      }
-      else if (reader.TokenType == JsonToken.Date)
-      {
-        DateTime d = (DateTime)reader.Value;
-        element.AppendChild(document.CreateTextNode(XmlConvert.ToString(d, DateTimeUtils.ToSerializationMode(d.Kind))));
-      }
-      else if (reader.TokenType == JsonToken.Null)
-      {
-        // empty element. do nothing
-      }
-      else
-      {
-        // finished element will have no children to deserialize
-        if (reader.TokenType != JsonToken.EndObject)
-        {
-          manager.PushScope();
-
-          DeserializeNode(reader, document, manager, element);
-
-          manager.PopScope();
-        }
-      }
-    }
-
-    private void ReadArrayElements(JsonReader reader, IXmlDocument document, string propertyName, IXmlNode currentNode, XmlNamespaceManager manager)
-    {
-      string elementPrefix = MiscellaneousUtils.GetPrefix(propertyName);
-
-      IXmlElement nestedArrayElement = CreateElement(propertyName, document, elementPrefix, manager);
-
-      currentNode.AppendChild(nestedArrayElement);
-
-      while (reader.Read() && reader.TokenType != JsonToken.EndArray)
-      {
-        DeserializeValue(reader, document, manager, propertyName, nestedArrayElement);
-      }
-    }
-
-    private Dictionary<string, string> ReadAttributeElements(JsonReader reader, XmlNamespaceManager manager)
-    {
-      Dictionary<string, string> attributeNameValues = new Dictionary<string, string>();
-      bool finishedAttributes = false;
-      bool finishedElement = false;
-
-      // a string token means the element only has a single text child
-      if (reader.TokenType != JsonToken.String
-          && reader.TokenType != JsonToken.Null
-          && reader.TokenType != JsonToken.Boolean
-          && reader.TokenType != JsonToken.Integer
-          && reader.TokenType != JsonToken.Float
-          && reader.TokenType != JsonToken.Date
-          && reader.TokenType != JsonToken.StartConstructor)
-      {
-        // read properties until first non-attribute is encountered
-        while (!finishedAttributes && !finishedElement && reader.Read())
-        {
-          switch (reader.TokenType)
-          {
-            case JsonToken.PropertyName:
-              string attributeName = reader.Value.ToString();
-              string attributeValue;
-              char firstChar = attributeName[0];
-
-              switch (firstChar)
-              {
-                case '@':
-                  attributeName = attributeName.Substring(1);
-                  reader.Read();
-                  attributeValue = reader.Value.ToString();
-                  attributeNameValues.Add(attributeName, attributeValue);
-
-                  string namespacePrefix;
-                  if (IsNamespaceAttribute(attributeName, out namespacePrefix))
-                  {
-                    manager.AddNamespace(namespacePrefix, attributeValue);
-                  }
-                  break;
-                case '$':
-                  attributeName = attributeName.Substring(1);
-                  reader.Read();
-                  attributeValue = reader.Value.ToString();
-
-                  // check that JsonNamespaceUri is in scope
-                  // if it isn't then add it to document and namespace manager
-                  string jsonPrefix = manager.LookupPrefix(JsonNamespaceUri);
-                  if (jsonPrefix == null)
-                  {
-                    // ensure that the prefix used is free
-                    int? i = null;
-                    while (manager.LookupNamespace("json" + i) != null)
-                    {
-                      i = i.GetValueOrDefault() + 1;
-                    }
-                    jsonPrefix = "json" + i;
-
-                    attributeNameValues.Add("xmlns:" + jsonPrefix, JsonNamespaceUri);
-                    manager.AddNamespace(jsonPrefix, JsonNamespaceUri);
-                  }
-
-                  attributeNameValues.Add(jsonPrefix + ":" + attributeName, attributeValue);
-                  break;
-                default:
-                  finishedAttributes = true;
-                  break;
-              }
-              break;
-            case JsonToken.EndObject:
-              finishedElement = true;
-              break;
-            default:
-              throw new JsonSerializationException("Unexpected JsonToken: " + reader.TokenType);
-          }
-        }
-      }
-
-      return attributeNameValues;
-    }
-
-    private void CreateInstruction(JsonReader reader, IXmlDocument document, IXmlNode currentNode, string propertyName)
-    {
-      if (propertyName == DeclarationName)
-      {
-        string version = null;
-        string encoding = null;
-        string standalone = null;
-        while (reader.Read() && reader.TokenType != JsonToken.EndObject)
-        {
-          switch (reader.Value.ToString())
-          {
-            case "@version":
-              reader.Read();
-              version = reader.Value.ToString();
-              break;
-            case "@encoding":
-              reader.Read();
-              encoding = reader.Value.ToString();
-              break;
-            case "@standalone":
-              reader.Read();
-              standalone = reader.Value.ToString();
-              break;
-            default:
-              throw new JsonSerializationException("Unexpected property name encountered while deserializing XmlDeclaration: " + reader.Value);
-          }
-        }
-
-        IXmlNode declaration = document.CreateXmlDeclaration(version, encoding, standalone);
-        currentNode.AppendChild(declaration);
-      }
-      else
-      {
-        IXmlNode instruction = document.CreateProcessingInstruction(propertyName.Substring(1), reader.Value.ToString());
-        currentNode.AppendChild(instruction);
-      }
-    }
-
-    private IXmlElement CreateElement(string elementName, IXmlDocument document, string elementPrefix, XmlNamespaceManager manager)
-    {
-      return (!string.IsNullOrEmpty(elementPrefix))
-               ? document.CreateElement(elementName, manager.LookupNamespace(elementPrefix))
-               : document.CreateElement(elementName);
-    }
-
-    private void DeserializeNode(JsonReader reader, IXmlDocument document, XmlNamespaceManager manager, IXmlNode currentNode)
-    {
-      do
-      {
-        switch (reader.TokenType)
-        {
-          case JsonToken.PropertyName:
-            if (currentNode.NodeType == XmlNodeType.Document && document.DocumentElement != null)
-              throw new JsonSerializationException("JSON root object has multiple properties. The root object must have a single property in order to create a valid XML document. Consider specifing a DeserializeRootElementName.");
-
-            string propertyName = reader.Value.ToString();
-            reader.Read();
-
-            if (reader.TokenType == JsonToken.StartArray)
-            {
-              while (reader.Read() && reader.TokenType != JsonToken.EndArray)
-              {
-                DeserializeValue(reader, document, manager, propertyName, currentNode);
-              }
-            }
-            else
-            {
-              DeserializeValue(reader, document, manager, propertyName, currentNode);
-            }
-            break;
-          case JsonToken.StartConstructor:
-            string constructorName = reader.Value.ToString();
-
-            while (reader.Read() && reader.TokenType != JsonToken.EndConstructor)
-            {
-              DeserializeValue(reader, document, manager, constructorName, currentNode);
-            }
-            break;
-          case JsonToken.Comment:
-            currentNode.AppendChild(document.CreateComment((string)reader.Value));
-            break;
-          case JsonToken.EndObject:
-          case JsonToken.EndArray:
-            return;
-          default:
-            throw new JsonSerializationException("Unexpected JsonToken when deserializing node: " + reader.TokenType);
-        }
-      } while (reader.TokenType == JsonToken.PropertyName || reader.Read());
-      // don't read if current token is a property. token was already read when parsing element attributes
-    }
-
-    /// <summary>
-    /// Checks if the attributeName is a namespace attribute.
-    /// </summary>
-    /// <param name="attributeName">Attribute name to test.</param>
-    /// <param name="prefix">The attribute name prefix if it has one, otherwise an empty string.</param>
-    /// <returns>True if attribute name is for a namespace attribute, otherwise false.</returns>
-    private bool IsNamespaceAttribute(string attributeName, out string prefix)
-    {
-      if (attributeName.StartsWith("xmlns", StringComparison.Ordinal))
-      {
-        if (attributeName.Length == 5)
-        {
-          prefix = string.Empty;
-          return true;
-        }
-        else if (attributeName[5] == ':')
-        {
-          prefix = attributeName.Substring(6, attributeName.Length - 6);
-          return true;
-        }
-      }
-      prefix = null;
-      return false;
-    }
-
-    private IEnumerable<IXmlNode> ValueAttributes(IEnumerable<IXmlNode> c)
-    {
-      return c.Where(a => a.NamespaceURI != JsonNamespaceUri);
-    }
-    #endregion
-
-    /// <summary>
-    /// Determines whether this instance can convert the specified value type.
-    /// </summary>
-    /// <param name="valueType">Type of the value.</param>
-    /// <returns>
-    /// 	<c>true</c> if this instance can convert the specified value type; otherwise, <c>false</c>.
-    /// </returns>
-    public override bool CanConvert(Type valueType)
-    {
-      if (typeof(XmlNode).IsAssignableFrom(valueType))
-        return true;
-#if !NET20
-      if (typeof(XObject).IsAssignableFrom(valueType))
-        return true;
-#endif
-
-      return false;
-    }
-  }
-}
+#region License
+// 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.
+#endregion
+
+#if (!(SILVERLIGHT || PORTABLE) || WINDOWS_PHONE)
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Xml;
+#if !NET20
+using System.Xml.Linq;
+#endif
+using Newtonsoft.Json.Utilities;
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#else
+using System.Linq;
+#endif
+
+namespace Newtonsoft.Json.Converters
+{
+  #region XmlNodeWrappers
+#if !SILVERLIGHT && !NETFX_CORE
+  internal class XmlDocumentWrapper : XmlNodeWrapper, IXmlDocument
+  {
+    private readonly XmlDocument _document;
+
+    public XmlDocumentWrapper(XmlDocument document)
+      : base(document)
+    {
+      _document = document;
+    }
+
+    public IXmlNode CreateComment(string data)
+    {
+      return new XmlNodeWrapper(_document.CreateComment(data));
+    }
+
+    public IXmlNode CreateTextNode(string text)
+    {
+      return new XmlNodeWrapper(_document.CreateTextNode(text));
+    }
+
+    public IXmlNode CreateCDataSection(string data)
+    {
+      return new XmlNodeWrapper(_document.CreateCDataSection(data));
+    }
+
+    public IXmlNode CreateWhitespace(string text)
+    {
+      return new XmlNodeWrapper(_document.CreateWhitespace(text));
+    }
+
+    public IXmlNode CreateSignificantWhitespace(string text)
+    {
+      return new XmlNodeWrapper(_document.CreateSignificantWhitespace(text));
+    }
+
+    public IXmlNode CreateXmlDeclaration(string version, string encoding, string standalone)
+    {
+      return new XmlNodeWrapper(_document.CreateXmlDeclaration(version, encoding, standalone));
+    }
+
+    public IXmlNode CreateProcessingInstruction(string target, string data)
+    {
+      return new XmlNodeWrapper(_document.CreateProcessingInstruction(target, data));
+    }
+
+    public IXmlElement CreateElement(string elementName)
+    {
+      return new XmlElementWrapper(_document.CreateElement(elementName));
+    }
+
+    public IXmlElement CreateElement(string qualifiedName, string namespaceUri)
+    {
+      return new XmlElementWrapper(_document.CreateElement(qualifiedName, namespaceUri));
+    }
+
+    public IXmlNode CreateAttribute(string name, string value)
+    {
+      XmlNodeWrapper attribute = new XmlNodeWrapper(_document.CreateAttribute(name));
+      attribute.Value = value;
+
+      return attribute;
+    }
+
+    public IXmlNode CreateAttribute(string qualifiedName, string namespaceUri, string value)
+    {
+      XmlNodeWrapper attribute = new XmlNodeWrapper(_document.CreateAttribute(qualifiedName, namespaceUri));
+      attribute.Value = value;
+
+      return attribute;
+    }
+
+    public IXmlElement DocumentElement
+    {
+      get
+      {
+        if (_document.DocumentElement == null)
+          return null;
+
+        return new XmlElementWrapper(_document.DocumentElement);
+      }
+    }
+  }
+
+  internal class XmlElementWrapper : XmlNodeWrapper, IXmlElement
+  {
+    private readonly XmlElement _element;
+
+    public XmlElementWrapper(XmlElement element)
+      : base(element)
+    {
+      _element = element;
+    }
+
+    public void SetAttributeNode(IXmlNode attribute)
+    {
+      XmlNodeWrapper xmlAttributeWrapper = (XmlNodeWrapper)attribute;
+
+      _element.SetAttributeNode((XmlAttribute) xmlAttributeWrapper.WrappedNode);
+    }
+
+    public string GetPrefixOfNamespace(string namespaceUri)
+    {
+      return _element.GetPrefixOfNamespace(namespaceUri);
+    }
+  }
+
+  internal class XmlDeclarationWrapper : XmlNodeWrapper, IXmlDeclaration
+  {
+    private readonly XmlDeclaration _declaration;
+
+    public XmlDeclarationWrapper(XmlDeclaration declaration)
+      : base(declaration)
+    {
+      _declaration = declaration;
+    }
+
+    public string Version
+    {
+      get { return _declaration.Version; }
+    }
+
+    public string Encoding
+    {
+      get { return _declaration.Encoding; }
+      set { _declaration.Encoding = value; }
+    }
+
+    public string Standalone
+    {
+      get { return _declaration.Standalone; }
+      set { _declaration.Standalone = value; }
+    }
+  }
+
+  internal class XmlNodeWrapper : IXmlNode
+  {
+    private readonly XmlNode _node;
+
+    public XmlNodeWrapper(XmlNode node)
+    {
+      _node = node;
+    }
+
+    public object WrappedNode
+    {
+      get { return _node; }
+    }
+
+    public XmlNodeType NodeType
+    {
+      get { return _node.NodeType; }
+    }
+
+    public string Name
+    {
+      get { return _node.Name; }
+    }
+
+    public string LocalName
+    {
+      get { return _node.LocalName; }
+    }
+
+    public IList<IXmlNode> ChildNodes
+    {
+      get { return _node.ChildNodes.Cast<XmlNode>().Select(n => WrapNode(n)).ToList(); }
+    }
+
+    private IXmlNode WrapNode(XmlNode node)
+    {
+      switch (node.NodeType)
+      {
+        case XmlNodeType.Element:
+          return new XmlElementWrapper((XmlElement) node);
+        case XmlNodeType.XmlDeclaration:
+          return new XmlDeclarationWrapper((XmlDeclaration) node);
+        default:
+          return new XmlNodeWrapper(node);
+      }
+    }
+
+    public IList<IXmlNode> Attributes
+    {
+      get
+      {
+        if (_node.Attributes == null)
+          return null;
+
+        return _node.Attributes.Cast<XmlAttribute>().Select(a => WrapNode(a)).ToList();
+      }
+    }
+
+    public IXmlNode ParentNode
+    {
+      get
+      {
+        XmlNode node = (_node is XmlAttribute)
+                         ? ((XmlAttribute) _node).OwnerElement
+                         : _node.ParentNode;
+        
+        if (node == null)
+          return null;
+
+        return WrapNode(node);
+      }
+    }
+
+    public string Value
+    {
+      get { return _node.Value; }
+      set { _node.Value = value; }
+    }
+
+    public IXmlNode AppendChild(IXmlNode newChild)
+    {
+      XmlNodeWrapper xmlNodeWrapper = (XmlNodeWrapper) newChild;
+      _node.AppendChild(xmlNodeWrapper._node);
+
+      return newChild;
+    }
+
+    public string Prefix
+    {
+      get { return _node.Prefix; }
+    }
+
+    public string NamespaceUri
+    {
+      get { return _node.NamespaceURI; }
+    }
+  }
+#endif
+  #endregion
+
+  #region Interfaces
+  internal interface IXmlDocument : IXmlNode
+  {
+    IXmlNode CreateComment(string text);
+    IXmlNode CreateTextNode(string text);
+    IXmlNode CreateCDataSection(string data);
+    IXmlNode CreateWhitespace(string text);
+    IXmlNode CreateSignificantWhitespace(string text);
+    IXmlNode CreateXmlDeclaration(string version, string encoding, string standalone);
+    IXmlNode CreateProcessingInstruction(string target, string data);
+    IXmlElement CreateElement(string elementName);
+    IXmlElement CreateElement(string qualifiedName, string namespaceUri);
+    IXmlNode CreateAttribute(string name, string value);
+    IXmlNode CreateAttribute(string qualifiedName, string namespaceUri, string value);
+
+    IXmlElement DocumentElement { get; }
+  }
+
+  internal interface IXmlDeclaration : IXmlNode
+  {
+    string Version { get; }
+    string Encoding { get; set; }
+    string Standalone { get; set; }
+  }
+
+  internal interface IXmlElement : IXmlNode
+  {
+    void SetAttributeNode(IXmlNode attribute);
+    string GetPrefixOfNamespace(string namespaceUri);
+  }
+
+  internal interface IXmlNode
+  {
+    XmlNodeType NodeType { get; }
+    string LocalName { get; }
+    IList<IXmlNode> ChildNodes { get; }
+    IList<IXmlNode> Attributes { get; }
+    IXmlNode ParentNode { get; }
+    string Value { get; set; }
+    IXmlNode AppendChild(IXmlNode newChild);
+    string NamespaceUri { get; }
+    object WrappedNode { get; }
+  }
+  #endregion
+
+  #region XNodeWrappers
+#if !NET20
+  internal class XDeclarationWrapper : XObjectWrapper, IXmlDeclaration
+  {
+    internal XDeclaration Declaration { get; private set; }
+
+    public XDeclarationWrapper(XDeclaration declaration)
+      : base(null)
+    {
+      Declaration = declaration;
+    }
+
+    public override XmlNodeType NodeType
+    {
+      get { return XmlNodeType.XmlDeclaration; }
+    }
+
+    public string Version
+    {
+      get { return Declaration.Version; }
+    }
+
+    public string Encoding
+    {
+      get { return Declaration.Encoding; }
+      set { Declaration.Encoding = value; }
+    }
+
+    public string Standalone
+    {
+      get { return Declaration.Standalone; }
+      set { Declaration.Standalone = value; }
+    }
+  }
+
+  internal class XDocumentWrapper : XContainerWrapper, IXmlDocument
+  {
+    private XDocument Document
+    {
+      get { return (XDocument)WrappedNode; }
+    }
+
+    public XDocumentWrapper(XDocument document)
+      : base(document)
+    {
+    }
+
+    public override IList<IXmlNode> ChildNodes
+    {
+      get
+      {
+        IList<IXmlNode> childNodes = base.ChildNodes;
+
+        if (Document.Declaration != null)
+          childNodes.Insert(0, new XDeclarationWrapper(Document.Declaration));
+
+        return childNodes;
+      }
+    }
+
+    public IXmlNode CreateComment(string text)
+    {
+      return new XObjectWrapper(new XComment(text));
+    }
+
+    public IXmlNode CreateTextNode(string text)
+    {
+      return new XObjectWrapper(new XText(text));
+    }
+
+    public IXmlNode CreateCDataSection(string data)
+    {
+      return new XObjectWrapper(new XCData(data));
+    }
+
+    public IXmlNode CreateWhitespace(string text)
+    {
+      return new XObjectWrapper(new XText(text));
+    }
+
+    public IXmlNode CreateSignificantWhitespace(string text)
+    {
+      return new XObjectWrapper(new XText(text));
+    }
+
+    public IXmlNode CreateXmlDeclaration(string version, string encoding, string standalone)
+    {
+      return new XDeclarationWrapper(new XDeclaration(version, encoding, standalone));
+    }
+
+    public IXmlNode CreateProcessingInstruction(string target, string data)
+    {
+      return new XProcessingInstructionWrapper(new XProcessingInstruction(target, data));
+    }
+
+    public IXmlElement CreateElement(string elementName)
+    {
+      return new XElementWrapper(new XElement(elementName));
+    }
+
+    public IXmlElement CreateElement(string qualifiedName, string namespaceUri)
+    {
+      string localName = MiscellaneousUtils.GetLocalName(qualifiedName);
+      return new XElementWrapper(new XElement(XName.Get(localName, namespaceUri)));
+    }
+
+    public IXmlNode CreateAttribute(string name, string value)
+    {
+      return new XAttributeWrapper(new XAttribute(name, value));
+    }
+
+    public IXmlNode CreateAttribute(string qualifiedName, string namespaceUri, string value)
+    {
+      string localName = MiscellaneousUtils.GetLocalName(qualifiedName);
+      return new XAttributeWrapper(new XAttribute(XName.Get(localName, namespaceUri), value));
+    }
+
+    public IXmlElement DocumentElement
+    {
+      get
+      {
+        if (Document.Root == null)
+          return null;
+
+        return new XElementWrapper(Document.Root);
+      }
+    }
+
+    public override IXmlNode AppendChild(IXmlNode newChild)
+    {
+      XDeclarationWrapper declarationWrapper = newChild as XDeclarationWrapper;
+      if (declarationWrapper != null)
+      {
+        Document.Declaration = declarationWrapper.Declaration;
+        return declarationWrapper;
+      }
+      else
+      {
+        return base.AppendChild(newChild);
+      }
+    }
+  }
+
+  internal class XTextWrapper : XObjectWrapper
+  {
+    private XText Text
+    {
+      get { return (XText)WrappedNode; }
+    }
+
+    public XTextWrapper(XText text)
+      : base(text)
+    {
+    }
+
+    public override string Value
+    {
+      get { return Text.Value; }
+      set { Text.Value = value; }
+    }
+
+    public override IXmlNode ParentNode
+    {
+      get
+      {
+        if (Text.Parent == null)
+          return null;
+        
+        return XContainerWrapper.WrapNode(Text.Parent);
+      }
+    }
+  }
+
+  internal class XCommentWrapper : XObjectWrapper
+  {
+    private XComment Text
+    {
+      get { return (XComment)WrappedNode; }
+    }
+
+    public XCommentWrapper(XComment text)
+      : base(text)
+    {
+    }
+
+    public override string Value
+    {
+      get { return Text.Value; }
+      set { Text.Value = value; }
+    }
+
+    public override IXmlNode ParentNode
+    {
+      get
+      {
+        if (Text.Parent == null)
+          return null;
+
+        return XContainerWrapper.WrapNode(Text.Parent);
+      }
+    }
+  }
+
+  internal class XProcessingInstructionWrapper : XObjectWrapper
+  {
+    private XProcessingInstruction ProcessingInstruction
+    {
+      get { return (XProcessingInstruction)WrappedNode; }
+    }
+
+    public XProcessingInstructionWrapper(XProcessingInstruction processingInstruction)
+      : base(processingInstruction)
+    {
+    }
+
+    public override string LocalName
+    {
+      get { return ProcessingInstruction.Target; }
+    }
+
+    public override string Value
+    {
+      get { return ProcessingInstruction.Data; }
+      set { ProcessingInstruction.Data = value; }
+    }
+  }
+
+  internal class XContainerWrapper : XObjectWrapper
+  {
+    private XContainer Container
+    {
+      get { return (XContainer)WrappedNode; }
+    }
+
+    public XContainerWrapper(XContainer container)
+      : base(container)
+    {
+    }
+
+    public override IList<IXmlNode> ChildNodes
+    {
+      get { return Container.Nodes().Select(n => WrapNode(n)).ToList(); }
+    }
+
+    public override IXmlNode ParentNode
+    {
+      get
+      {
+        if (Container.Parent == null)
+          return null;
+        
+        return WrapNode(Container.Parent);
+      }
+    }
+
+    internal static IXmlNode WrapNode(XObject node)
+    {
+      if (node is XDocument)
+        return new XDocumentWrapper((XDocument)node);
+      else if (node is XElement)
+        return new XElementWrapper((XElement)node);
+      else if (node is XContainer)
+        return new XContainerWrapper((XContainer)node);
+      else if (node is XProcessingInstruction)
+        return new XProcessingInstructionWrapper((XProcessingInstruction)node);
+      else if (node is XText)
+        return new XTextWrapper((XText)node);
+      else if (node is XComment)
+        return new XCommentWrapper((XComment)node);
+      else if (node is XAttribute)
+        return new XAttributeWrapper((XAttribute) node);
+      else
+        return new XObjectWrapper(node);
+    }
+
+    public override IXmlNode AppendChild(IXmlNode newChild)
+    {
+      Container.Add(newChild.WrappedNode);
+      return newChild;
+    }
+  }
+
+  internal class XObjectWrapper : IXmlNode
+  {
+    private readonly XObject _xmlObject;
+
+    public XObjectWrapper(XObject xmlObject)
+    {
+      _xmlObject = xmlObject;
+    }
+
+    public object WrappedNode
+    {
+      get { return _xmlObject; }
+    }
+
+    public virtual XmlNodeType NodeType
+    {
+      get { return _xmlObject.NodeType; }
+    }
+
+    public virtual string LocalName
+    {
+      get { return null; }
+    }
+
+    public virtual IList<IXmlNode> ChildNodes
+    {
+      get { return new List<IXmlNode>(); }
+    }
+
+    public virtual IList<IXmlNode> Attributes
+    {
+      get { return null; }
+    }
+
+    public virtual IXmlNode ParentNode
+    {
+      get { return null; }
+    }
+
+    public virtual string Value
+    {
+      get { return null; }
+      set { throw new InvalidOperationException(); }
+    }
+
+    public virtual IXmlNode AppendChild(IXmlNode newChild)
+    {
+      throw new InvalidOperationException();
+    }
+
+    public virtual string NamespaceUri
+    {
+      get { return null; }
+    }
+  }
+
+  internal class XAttributeWrapper : XObjectWrapper
+  {
+    private XAttribute Attribute
+    {
+      get { return (XAttribute)WrappedNode; }
+    }
+
+    public XAttributeWrapper(XAttribute attribute)
+      : base(attribute)
+    {
+    }
+
+    public override string Value
+    {
+      get { return Attribute.Value; }
+      set { Attribute.Value = value; }
+    }
+
+    public override string LocalName
+    {
+      get { return Attribute.Name.LocalName; }
+    }
+
+    public override string NamespaceUri
+    {
+      get { return Attribute.Name.NamespaceName; }
+    }
+
+    public override IXmlNode ParentNode
+    {
+      get
+      {
+        if (Attribute.Parent == null)
+          return null;
+
+        return XContainerWrapper.WrapNode(Attribute.Parent);
+      }
+    }
+  }
+
+  internal class XElementWrapper : XContainerWrapper, IXmlElement
+  {
+    private XElement Element
+    {
+      get { return (XElement) WrappedNode; }
+    }
+
+    public XElementWrapper(XElement element)
+      : base(element)
+    {
+    }
+
+    public void SetAttributeNode(IXmlNode attribute)
+    {
+      XObjectWrapper wrapper = (XObjectWrapper)attribute;
+      Element.Add(wrapper.WrappedNode);
+    }
+
+    public override IList<IXmlNode> Attributes
+    {
+      get { return Element.Attributes().Select(a => new XAttributeWrapper(a)).Cast<IXmlNode>().ToList(); }
+    }
+
+    public override string Value
+    {
+      get { return Element.Value; }
+      set { Element.Value = value; }
+    }
+
+    public override string LocalName
+    {
+      get { return Element.Name.LocalName; }
+    }
+
+    public override string NamespaceUri
+    {
+      get { return Element.Name.NamespaceName; }
+    }
+
+    public string GetPrefixOfNamespace(string namespaceUri)
+    {
+      return Element.GetPrefixOfNamespace(namespaceUri);
+    }
+  }
+#endif
+  #endregion
+
+  /// <summary>
+  /// Converts XML to and from JSON.
+  /// </summary>
+  public class XmlNodeConverter : JsonConverter
+  {
+    private const string TextName = "#text";
+    private const string CommentName = "#comment";
+    private const string CDataName = "#cdata-section";
+    private const string WhitespaceName = "#whitespace";
+    private const string SignificantWhitespaceName = "#significant-whitespace";
+    private const string DeclarationName = "?xml";
+    private const string JsonNamespaceUri = "http://james.newtonking.com/projects/json";
+
+    /// <summary>
+    /// Gets or sets the name of the root element to insert when deserializing to XML if the JSON structure has produces multiple root elements.
+    /// </summary>
+    /// <value>The name of the deserialize root element.</value>
+    public string DeserializeRootElementName { get; set; }
+
+    /// <summary>
+    /// Gets or sets a flag to indicate whether to write the Json.NET array attribute.
+    /// This attribute helps preserve arrays when converting the written XML back to JSON.
+    /// </summary>
+    /// <value><c>true</c> if the array attibute is written to the XML; otherwise, <c>false</c>.</value>
+    public bool WriteArrayAttribute { get; set; }
+
+    /// <summary>
+    /// Gets or sets a value indicating whether to write the root JSON object.
+    /// </summary>
+    /// <value><c>true</c> if the JSON root object is omitted; otherwise, <c>false</c>.</value>
+    public bool OmitRootObject { get; set; }
+
+    #region Writing
+    /// <summary>
+    /// Writes the JSON representation of the object.
+    /// </summary>
+    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    /// <param name="value">The value.</param>
+    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+    {
+      IXmlNode node = WrapXml(value);
+
+      XmlNamespaceManager manager = new XmlNamespaceManager(new NameTable());
+      PushParentNamespaces(node, manager);
+
+      if (!OmitRootObject)
+        writer.WriteStartObject();
+
+      SerializeNode(writer, node, manager, !OmitRootObject);
+      
+      if (!OmitRootObject)
+        writer.WriteEndObject();
+    }
+
+    private IXmlNode WrapXml(object value)
+    {
+#if !NET20
+      if (value is XObject)
+        return XContainerWrapper.WrapNode((XObject)value);
+#endif
+#if !(SILVERLIGHT || NETFX_CORE)
+      if (value is XmlNode)
+        return new XmlNodeWrapper((XmlNode)value);
+#endif
+      
+      throw new ArgumentException("Value must be an XML object.", "value");
+    }
+
+    private void PushParentNamespaces(IXmlNode node, XmlNamespaceManager manager)
+    {
+      List<IXmlNode> parentElements = null;
+
+      IXmlNode parent = node;
+      while ((parent = parent.ParentNode) != null)
+      {
+        if (parent.NodeType == XmlNodeType.Element)
+        {
+          if (parentElements == null)
+            parentElements = new List<IXmlNode>();
+
+          parentElements.Add(parent);
+        }
+      }
+
+      if (parentElements != null)
+      {
+        parentElements.Reverse();
+
+        foreach (IXmlNode parentElement in parentElements)
+        {
+          manager.PushScope();
+          foreach (IXmlNode attribute in parentElement.Attributes)
+          {
+            if (attribute.NamespaceUri == "http://www.w3.org/2000/xmlns/" && attribute.LocalName != "xmlns")
+              manager.AddNamespace(attribute.LocalName, attribute.Value);
+          }
+        }
+      }
+    }
+
+    private string ResolveFullName(IXmlNode node, XmlNamespaceManager manager)
+    {
+      string prefix = (node.NamespaceUri == null || (node.LocalName == "xmlns" && node.NamespaceUri == "http://www.w3.org/2000/xmlns/"))
+                        ? null
+                        : manager.LookupPrefix(node.NamespaceUri);
+
+      if (!string.IsNullOrEmpty(prefix))
+        return prefix + ":" + node.LocalName;
+      else
+        return node.LocalName;
+    }
+
+    private string GetPropertyName(IXmlNode node, XmlNamespaceManager manager)
+    {
+      switch (node.NodeType)
+      {
+        case XmlNodeType.Attribute:
+          if (node.NamespaceUri == JsonNamespaceUri)
+            return "$" + node.LocalName;
+          else
+            return "@" + ResolveFullName(node, manager);
+        case XmlNodeType.CDATA:
+          return CDataName;
+        case XmlNodeType.Comment:
+          return CommentName;
+        case XmlNodeType.Element:
+          return ResolveFullName(node, manager);
+        case XmlNodeType.ProcessingInstruction:
+          return "?" + ResolveFullName(node, manager);
+        case XmlNodeType.XmlDeclaration:
+          return DeclarationName;
+        case XmlNodeType.SignificantWhitespace:
+          return SignificantWhitespaceName;
+        case XmlNodeType.Text:
+          return TextName;
+        case XmlNodeType.Whitespace:
+          return WhitespaceName;
+        default:
+          throw new JsonSerializationException("Unexpected XmlNodeType when getting node name: " + node.NodeType);
+      }
+    }
+
+    private bool IsArray(IXmlNode node)
+    {
+      IXmlNode jsonArrayAttribute = (node.Attributes != null)
+                                      ? node.Attributes.SingleOrDefault(a => a.LocalName == "Array" && a.NamespaceUri == JsonNamespaceUri)
+                                      : null;
+      
+      return (jsonArrayAttribute != null && XmlConvert.ToBoolean(jsonArrayAttribute.Value));
+    }
+
+    private void SerializeGroupedNodes(JsonWriter writer, IXmlNode node, XmlNamespaceManager manager, bool writePropertyName)
+    {
+      // group nodes together by name
+      Dictionary<string, List<IXmlNode>> nodesGroupedByName = new Dictionary<string, List<IXmlNode>>();
+
+      for (int i = 0; i < node.ChildNodes.Count; i++)
+      {
+        IXmlNode childNode = node.ChildNodes[i];
+        string nodeName = GetPropertyName(childNode, manager);
+
+        List<IXmlNode> nodes;
+        if (!nodesGroupedByName.TryGetValue(nodeName, out nodes))
+        {
+          nodes = new List<IXmlNode>();
+          nodesGroupedByName.Add(nodeName, nodes);
+        }
+
+        nodes.Add(childNode);
+      }
+
+      // loop through grouped nodes. write single name instances as normal,
+      // write multiple names together in an array
+      foreach (KeyValuePair<string, List<IXmlNode>> nodeNameGroup in nodesGroupedByName)
+      {
+        List<IXmlNode> groupedNodes = nodeNameGroup.Value;
+        bool writeArray;
+
+        if (groupedNodes.Count == 1)
+        {
+          writeArray = IsArray(groupedNodes[0]);
+        }
+        else
+        {
+          writeArray = true;
+        }
+
+        if (!writeArray)
+        {
+          SerializeNode(writer, groupedNodes[0], manager, writePropertyName);
+        }
+        else
+        {
+          string elementNames = nodeNameGroup.Key;
+
+          if (writePropertyName)
+            writer.WritePropertyName(elementNames);
+
+          writer.WriteStartArray();
+
+          for (int i = 0; i < groupedNodes.Count; i++)
+          {
+            SerializeNode(writer, groupedNodes[i], manager, false);
+          }
+
+          writer.WriteEndArray();
+        }
+      }
+    }
+
+    private void SerializeNode(JsonWriter writer, IXmlNode node, XmlNamespaceManager manager, bool writePropertyName)
+    {
+      switch (node.NodeType)
+      {
+        case XmlNodeType.Document:
+        case XmlNodeType.DocumentFragment:
+          SerializeGroupedNodes(writer, node, manager, writePropertyName);
+          break;
+        case XmlNodeType.Element:
+          if (IsArray(node) && node.ChildNodes.All(n => n.LocalName == node.LocalName) && node.ChildNodes.Count > 0)
+          {
+            SerializeGroupedNodes(writer, node, manager, false);
+          }
+          else
+          {
+            foreach (IXmlNode attribute in node.Attributes)
+            {
+              if (attribute.NamespaceUri == "http://www.w3.org/2000/xmlns/")
+              {
+                string prefix = (attribute.LocalName != "xmlns")
+                                  ? attribute.LocalName
+                                  : string.Empty;
+
+                manager.AddNamespace(prefix, attribute.Value);
+              }
+            }
+
+            if (writePropertyName)
+              writer.WritePropertyName(GetPropertyName(node, manager));
+
+            if (!ValueAttributes(node.Attributes).Any() && node.ChildNodes.Count == 1
+                && node.ChildNodes[0].NodeType == XmlNodeType.Text)
+            {
+              // write elements with a single text child as a name value pair
+              writer.WriteValue(node.ChildNodes[0].Value);
+            }
+            else if (node.ChildNodes.Count == 0 && CollectionUtils.IsNullOrEmpty(node.Attributes))
+            {
+              // empty element
+              writer.WriteNull();
+            }
+            else
+            {
+              writer.WriteStartObject();
+
+              for (int i = 0; i < node.Attributes.Count; i++)
+              {
+                SerializeNode(writer, node.Attributes[i], manager, true);
+              }
+
+              SerializeGroupedNodes(writer, node, manager, true);
+
+              writer.WriteEndObject();
+            }
+          }
+
+          break;
+        case XmlNodeType.Comment:
+          if (writePropertyName)
+            writer.WriteComment(node.Value);
+          break;
+        case XmlNodeType.Attribute:
+        case XmlNodeType.Text:
+        case XmlNodeType.CDATA:
+        case XmlNodeType.ProcessingInstruction:
+        case XmlNodeType.Whitespace:
+        case XmlNodeType.SignificantWhitespace:
+          if (node.NamespaceUri == "http://www.w3.org/2000/xmlns/" && node.Value == JsonNamespaceUri)
+            return;
+
+          if (node.NamespaceUri == JsonNamespaceUri)
+          {
+            if (node.LocalName == "Array")
+              return;
+          }
+
+          if (writePropertyName)
+            writer.WritePropertyName(GetPropertyName(node, manager));
+          writer.WriteValue(node.Value);
+          break;
+        case XmlNodeType.XmlDeclaration:
+          IXmlDeclaration declaration = (IXmlDeclaration)node;
+          writer.WritePropertyName(GetPropertyName(node, manager));
+          writer.WriteStartObject();
+
+          if (!string.IsNullOrEmpty(declaration.Version))
+          {
+            writer.WritePropertyName("@version");
+            writer.WriteValue(declaration.Version);
+          }
+          if (!string.IsNullOrEmpty(declaration.Encoding))
+          {
+            writer.WritePropertyName("@encoding");
+            writer.WriteValue(declaration.Encoding);
+          }
+          if (!string.IsNullOrEmpty(declaration.Standalone))
+          {
+            writer.WritePropertyName("@standalone");
+            writer.WriteValue(declaration.Standalone);
+          }
+
+          writer.WriteEndObject();
+          break;
+        default:
+          throw new JsonSerializationException("Unexpected XmlNodeType when serializing nodes: " + node.NodeType);
+      }
+    }
+    #endregion
+
+    #region Reading
+    /// <summary>
+    /// Reads the JSON representation of the object.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
+    /// <param name="objectType">Type of the object.</param>
+    /// <param name="existingValue">The existing value of object being read.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    /// <returns>The object value.</returns>
+    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+    {
+      XmlNamespaceManager manager = new XmlNamespaceManager(new NameTable());
+      IXmlDocument document = null;
+      IXmlNode rootNode = null;
+
+#if !NET20
+      if (typeof(XObject).IsAssignableFrom(objectType))
+      {
+        if (objectType != typeof (XDocument) && objectType != typeof (XElement))
+          throw new JsonSerializationException("XmlNodeConverter only supports deserializing XDocument or XElement.");
+
+        XDocument d = new XDocument();
+        document = new XDocumentWrapper(d);
+        rootNode = document;
+      }
+#endif
+#if !(SILVERLIGHT || NETFX_CORE)
+      if (typeof(XmlNode).IsAssignableFrom(objectType))
+      {
+        if (objectType != typeof (XmlDocument))
+          throw new JsonSerializationException("XmlNodeConverter only supports deserializing XmlDocuments");
+
+        XmlDocument d = new XmlDocument();
+        document = new XmlDocumentWrapper(d);
+        rootNode = document;
+      }
+#endif
+      
+      if (document == null || rootNode == null)
+        throw new JsonSerializationException("Unexpected type when converting XML: " + objectType);
+
+      if (reader.TokenType != JsonToken.StartObject)
+        throw new JsonSerializationException("XmlNodeConverter can only convert JSON that begins with an object.");
+
+      if (!string.IsNullOrEmpty(DeserializeRootElementName))
+      {
+        //rootNode = document.CreateElement(DeserializeRootElementName);
+        //document.AppendChild(rootNode);
+        ReadElement(reader, document, rootNode, DeserializeRootElementName, manager);
+      }
+      else
+      {
+        reader.Read();
+        DeserializeNode(reader, document, manager, rootNode);
+      }
+
+#if !NET20
+      if (objectType == typeof(XElement))
+      {
+        XElement element = (XElement)document.DocumentElement.WrappedNode;
+        element.Remove();
+
+        return element;
+      }
+#endif
+
+      return document.WrappedNode;
+    }
+
+    private void DeserializeValue(JsonReader reader, IXmlDocument document, XmlNamespaceManager manager, string propertyName, IXmlNode currentNode)
+    {
+      switch (propertyName)
+      {
+        case TextName:
+          currentNode.AppendChild(document.CreateTextNode(reader.Value.ToString()));
+          break;
+        case CDataName:
+          currentNode.AppendChild(document.CreateCDataSection(reader.Value.ToString()));
+          break;
+        case WhitespaceName:
+          currentNode.AppendChild(document.CreateWhitespace(reader.Value.ToString()));
+          break;
+        case SignificantWhitespaceName:
+          currentNode.AppendChild(document.CreateSignificantWhitespace(reader.Value.ToString()));
+          break;
+        default:
+          // processing instructions and the xml declaration start with ?
+          if (!string.IsNullOrEmpty(propertyName) && propertyName[0] == '?')
+          {
+            CreateInstruction(reader, document, currentNode, propertyName);
+          }
+          else
+          {
+            if (reader.TokenType == JsonToken.StartArray)
+            {
+              // handle nested arrays
+              ReadArrayElements(reader, document, propertyName, currentNode, manager);
+              return;
+            }
+
+            // have to wait until attributes have been parsed before creating element
+            // attributes may contain namespace info used by the element
+            ReadElement(reader, document, currentNode, propertyName, manager);
+          }
+          break;
+      }
+    }
+
+    private void ReadElement(JsonReader reader, IXmlDocument document, IXmlNode currentNode, string propertyName, XmlNamespaceManager manager)
+    {
+      if (string.IsNullOrEmpty(propertyName))
+        throw new JsonSerializationException("XmlNodeConverter cannot convert JSON with an empty property name to XML.");
+
+      Dictionary<string, string> attributeNameValues = ReadAttributeElements(reader, manager);
+
+      string elementPrefix = MiscellaneousUtils.GetPrefix(propertyName);
+
+      if (propertyName.StartsWith("@"))
+      {
+        var attributeName = propertyName.Substring(1);
+        var attributeValue = reader.Value.ToString();
+
+        var attributePrefix = MiscellaneousUtils.GetPrefix(attributeName);
+
+        var attribute = (!string.IsNullOrEmpty(attributePrefix))
+                                 ? document.CreateAttribute(attributeName, manager.LookupNamespace(attributePrefix), attributeValue)
+                                 : document.CreateAttribute(attributeName, attributeValue);
+
+        ((IXmlElement)currentNode).SetAttributeNode(attribute);
+      }
+      else
+      {
+        IXmlElement element = CreateElement(propertyName, document, elementPrefix, manager);
+
+        currentNode.AppendChild(element);
+
+        // add attributes to newly created element
+        foreach (KeyValuePair<string, string> nameValue in attributeNameValues)
+        {
+          string attributePrefix = MiscellaneousUtils.GetPrefix(nameValue.Key);
+
+          IXmlNode attribute = (!string.IsNullOrEmpty(attributePrefix))
+                                 ? document.CreateAttribute(nameValue.Key, manager.LookupNamespace(attributePrefix), nameValue.Value)
+                                 : document.CreateAttribute(nameValue.Key, nameValue.Value);
+
+          element.SetAttributeNode(attribute);
+        }
+
+        if (reader.TokenType == JsonToken.String
+            || reader.TokenType == JsonToken.Integer
+            || reader.TokenType == JsonToken.Float
+            || reader.TokenType == JsonToken.Boolean
+            || reader.TokenType == JsonToken.Date)
+        {
+          element.AppendChild(document.CreateTextNode(ConvertTokenToXmlValue(reader)));
+        }
+        else if (reader.TokenType == JsonToken.Null)
+        {
+          // empty element. do nothing
+        }
+        else
+        {
+          // finished element will have no children to deserialize
+          if (reader.TokenType != JsonToken.EndObject)
+          {
+            manager.PushScope();
+
+            DeserializeNode(reader, document, manager, element);
+
+            manager.PopScope();
+          }
+        }
+      }
+    }
+
+    private string ConvertTokenToXmlValue(JsonReader reader)
+    {
+      if (reader.TokenType == JsonToken.String)
+      {
+        return reader.Value.ToString();
+      }
+      else if (reader.TokenType == JsonToken.Integer)
+      {
+        return XmlConvert.ToString(Convert.ToInt64(reader.Value, CultureInfo.InvariantCulture));
+      }
+      else if (reader.TokenType == JsonToken.Float)
+      {
+        return XmlConvert.ToString(Convert.ToDouble(reader.Value, CultureInfo.InvariantCulture));
+      }
+      else if (reader.TokenType == JsonToken.Boolean)
+      {
+        return XmlConvert.ToString(Convert.ToBoolean(reader.Value, CultureInfo.InvariantCulture));
+      }
+      else if (reader.TokenType == JsonToken.Date)
+      {
+        DateTime d = Convert.ToDateTime(reader.Value, CultureInfo.InvariantCulture);
+#if !NETFX_CORE
+        return XmlConvert.ToString(d, DateTimeUtils.ToSerializationMode(d.Kind));
+#else
+        return XmlConvert.ToString(d);
+#endif   
+      }
+      else if (reader.TokenType == JsonToken.Null)
+      {
+        return null;
+      }
+      else
+      {
+        throw JsonSerializationException.Create(reader, "Cannot get an XML string value from token type '{0}'.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
+      }
+    }
+
+    private void ReadArrayElements(JsonReader reader, IXmlDocument document, string propertyName, IXmlNode currentNode, XmlNamespaceManager manager)
+    {
+      string elementPrefix = MiscellaneousUtils.GetPrefix(propertyName);
+
+      IXmlElement nestedArrayElement = CreateElement(propertyName, document, elementPrefix, manager);
+
+      currentNode.AppendChild(nestedArrayElement);
+
+      int count = 0;
+      while (reader.Read() && reader.TokenType != JsonToken.EndArray)
+      {
+        DeserializeValue(reader, document, manager, propertyName, nestedArrayElement);
+        count++;
+      }
+
+      if (WriteArrayAttribute)
+      {
+        AddJsonArrayAttribute(nestedArrayElement, document);
+      }
+
+      if (count == 1 && WriteArrayAttribute)
+      {
+        IXmlElement arrayElement = nestedArrayElement.ChildNodes.CastValid<IXmlElement>().Single(n => n.LocalName == propertyName);
+        AddJsonArrayAttribute(arrayElement, document);
+      }
+    }
+
+    private void AddJsonArrayAttribute(IXmlElement element, IXmlDocument document)
+    {
+      element.SetAttributeNode(document.CreateAttribute("json:Array", JsonNamespaceUri, "true"));
+
+#if !NET20
+      // linq to xml doesn't automatically include prefixes via the namespace manager
+      if (element is XElementWrapper)
+      {
+        if (element.GetPrefixOfNamespace(JsonNamespaceUri) == null)
+        {
+          element.SetAttributeNode(document.CreateAttribute("xmlns:json", "http://www.w3.org/2000/xmlns/", JsonNamespaceUri));
+        }
+      }
+#endif
+    }
+
+    private Dictionary<string, string> ReadAttributeElements(JsonReader reader, XmlNamespaceManager manager)
+    {
+      Dictionary<string, string> attributeNameValues = new Dictionary<string, string>();
+      bool finishedAttributes = false;
+      bool finishedElement = false;
+
+      // a string token means the element only has a single text child
+      if (reader.TokenType != JsonToken.String
+          && reader.TokenType != JsonToken.Null
+          && reader.TokenType != JsonToken.Boolean
+          && reader.TokenType != JsonToken.Integer
+          && reader.TokenType != JsonToken.Float
+          && reader.TokenType != JsonToken.Date
+          && reader.TokenType != JsonToken.StartConstructor)
+      {
+        // read properties until first non-attribute is encountered
+        while (!finishedAttributes && !finishedElement && reader.Read())
+        {
+          switch (reader.TokenType)
+          {
+            case JsonToken.PropertyName:
+              string attributeName = reader.Value.ToString();
+
+              if (!string.IsNullOrEmpty(attributeName))
+              {
+                char firstChar = attributeName[0];
+                string attributeValue;
+
+                switch (firstChar)
+                {
+                  case '@':
+                    attributeName = attributeName.Substring(1);
+                    reader.Read();
+                    attributeValue = ConvertTokenToXmlValue(reader);
+                    attributeNameValues.Add(attributeName, attributeValue);
+
+                    string namespacePrefix;
+                    if (IsNamespaceAttribute(attributeName, out namespacePrefix))
+                    {
+                      manager.AddNamespace(namespacePrefix, attributeValue);
+                    }
+                    break;
+                  case '$':
+                    attributeName = attributeName.Substring(1);
+                    reader.Read();
+                    attributeValue = reader.Value.ToString();
+
+                    // check that JsonNamespaceUri is in scope
+                    // if it isn't then add it to document and namespace manager
+                    string jsonPrefix = manager.LookupPrefix(JsonNamespaceUri);
+                    if (jsonPrefix == null)
+                    {
+                      // ensure that the prefix used is free
+                      int? i = null;
+                      while (manager.LookupNamespace("json" + i) != null)
+                      {
+                        i = i.GetValueOrDefault() + 1;
+                      }
+                      jsonPrefix = "json" + i;
+
+                      attributeNameValues.Add("xmlns:" + jsonPrefix, JsonNamespaceUri);
+                      manager.AddNamespace(jsonPrefix, JsonNamespaceUri);
+                    }
+
+                    attributeNameValues.Add(jsonPrefix + ":" + attributeName, attributeValue);
+                    break;
+                  default:
+                    finishedAttributes = true;
+                    break;
+                }
+              }
+              else
+              {
+                finishedAttributes = true;
+              }
+
+              break;
+            case JsonToken.EndObject:
+              finishedElement = true;
+              break;
+            default:
+              throw new JsonSerializationException("Unexpected JsonToken: " + reader.TokenType);
+          }
+        }
+      }
+
+      return attributeNameValues;
+    }
+
+    private void CreateInstruction(JsonReader reader, IXmlDocument document, IXmlNode currentNode, string propertyName)
+    {
+      if (propertyName == DeclarationName)
+      {
+        string version = null;
+        string encoding = null;
+        string standalone = null;
+        while (reader.Read() && reader.TokenType != JsonToken.EndObject)
+        {
+          switch (reader.Value.ToString())
+          {
+            case "@version":
+              reader.Read();
+              version = reader.Value.ToString();
+              break;
+            case "@encoding":
+              reader.Read();
+              encoding = reader.Value.ToString();
+              break;
+            case "@standalone":
+              reader.Read();
+              standalone = reader.Value.ToString();
+              break;
+            default:
+              throw new JsonSerializationException("Unexpected property name encountered while deserializing XmlDeclaration: " + reader.Value);
+          }
+        }
+
+        IXmlNode declaration = document.CreateXmlDeclaration(version, encoding, standalone);
+        currentNode.AppendChild(declaration);
+      }
+      else
+      {
+        IXmlNode instruction = document.CreateProcessingInstruction(propertyName.Substring(1), reader.Value.ToString());
+        currentNode.AppendChild(instruction);
+      }
+    }
+
+    private IXmlElement CreateElement(string elementName, IXmlDocument document, string elementPrefix, XmlNamespaceManager manager)
+    {
+      string ns = string.IsNullOrEmpty(elementPrefix) ? manager.DefaultNamespace : manager.LookupNamespace(elementPrefix);
+
+      IXmlElement element = (!string.IsNullOrEmpty(ns)) ? document.CreateElement(elementName, ns) : document.CreateElement(elementName);
+
+      return element;
+    }
+
+    private void DeserializeNode(JsonReader reader, IXmlDocument document, XmlNamespaceManager manager, IXmlNode currentNode)
+    {
+      do
+      {
+        switch (reader.TokenType)
+        {
+          case JsonToken.PropertyName:
+            if (currentNode.NodeType == XmlNodeType.Document && document.DocumentElement != null)
+              throw new JsonSerializationException("JSON root object has multiple properties. The root object must have a single property in order to create a valid XML document. Consider specifing a DeserializeRootElementName.");
+
+            string propertyName = reader.Value.ToString();
+            reader.Read();
+
+            if (reader.TokenType == JsonToken.StartArray)
+            {
+              int count = 0;
+              while (reader.Read() && reader.TokenType != JsonToken.EndArray)
+              {
+                DeserializeValue(reader, document, manager, propertyName, currentNode);
+                count++;
+              }
+
+              if (count == 1 && WriteArrayAttribute)
+              {
+                IXmlElement arrayElement = currentNode.ChildNodes.CastValid<IXmlElement>().Single(n => n.LocalName == propertyName);
+                AddJsonArrayAttribute(arrayElement, document);
+              }
+            }
+            else
+            {
+              DeserializeValue(reader, document, manager, propertyName, currentNode);
+            }
+            break;
+          case JsonToken.StartConstructor:
+            string constructorName = reader.Value.ToString();
+
+            while (reader.Read() && reader.TokenType != JsonToken.EndConstructor)
+            {
+              DeserializeValue(reader, document, manager, constructorName, currentNode);
+            }
+            break;
+          case JsonToken.Comment:
+            currentNode.AppendChild(document.CreateComment((string)reader.Value));
+            break;
+          case JsonToken.EndObject:
+          case JsonToken.EndArray:
+            return;
+          default:
+            throw new JsonSerializationException("Unexpected JsonToken when deserializing node: " + reader.TokenType);
+        }
+      } while (reader.TokenType == JsonToken.PropertyName || reader.Read());
+      // don't read if current token is a property. token was already read when parsing element attributes
+    }
+
+    /// <summary>
+    /// Checks if the attributeName is a namespace attribute.
+    /// </summary>
+    /// <param name="attributeName">Attribute name to test.</param>
+    /// <param name="prefix">The attribute name prefix if it has one, otherwise an empty string.</param>
+    /// <returns>True if attribute name is for a namespace attribute, otherwise false.</returns>
+    private bool IsNamespaceAttribute(string attributeName, out string prefix)
+    {
+      if (attributeName.StartsWith("xmlns", StringComparison.Ordinal))
+      {
+        if (attributeName.Length == 5)
+        {
+          prefix = string.Empty;
+          return true;
+        }
+        else if (attributeName[5] == ':')
+        {
+          prefix = attributeName.Substring(6, attributeName.Length - 6);
+          return true;
+        }
+      }
+      prefix = null;
+      return false;
+    }
+
+    private IEnumerable<IXmlNode> ValueAttributes(IEnumerable<IXmlNode> c)
+    {
+      return c.Where(a => a.NamespaceUri != JsonNamespaceUri);
+    }
+    #endregion
+
+    /// <summary>
+    /// Determines whether this instance can convert the specified value type.
+    /// </summary>
+    /// <param name="valueType">Type of the value.</param>
+    /// <returns>
+    /// 	<c>true</c> if this instance can convert the specified value type; otherwise, <c>false</c>.
+    /// </returns>
+    public override bool CanConvert(Type valueType)
+    {
+#if !NET20
+      if (typeof(XObject).IsAssignableFrom(valueType))
+        return true;
+#endif
+#if !(SILVERLIGHT || NETFX_CORE)
+      if (typeof(XmlNode).IsAssignableFrom(valueType))
+        return true;
+#endif
+
+      return false;
+    }
+  }
+}
 #endif
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/DateFormatHandling.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/DateFormatHandling.cs
new file mode 100644
index 0000000..428dcac
--- /dev/null
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/DateFormatHandling.cs
@@ -0,0 +1,42 @@
+#region License
+// 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.
+#endregion
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Specifies how dates are formatted when writing JSON text.
+  /// </summary>
+  public enum DateFormatHandling
+  {
+    /// <summary>
+    /// Dates are written in the ISO 8601 format, e.g. "2012-03-21T05:40Z".
+    /// </summary>
+    IsoDateFormat,
+    /// <summary>
+    /// Dates are written in the Microsoft JSON format, e.g. "\/Date(1198908717056)\/".
+    /// </summary>
+    MicrosoftDateFormat
+  }
+}
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/DateParseHandling.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/DateParseHandling.cs
new file mode 100644
index 0000000..225ff37
--- /dev/null
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/DateParseHandling.cs
@@ -0,0 +1,48 @@
+#region License
+// 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.
+#endregion
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Specifies how date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed when reading JSON text.
+  /// </summary>
+  public enum DateParseHandling
+  {
+    /// <summary>
+    /// Date formatted strings are not parsed to a date type and are read as strings.
+    /// </summary>
+    None,
+    /// <summary>
+    /// Date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed to <see cref="DateTime"/>.
+    /// </summary>
+    DateTime,
+#if !NET20
+    /// <summary>
+    /// Date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed to <see cref="DateTimeOffset"/>.
+    /// </summary>
+    DateTimeOffset
+#endif
+  }
+}
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/DateTimeZoneHandling.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/DateTimeZoneHandling.cs
new file mode 100644
index 0000000..79ec22b
--- /dev/null
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/DateTimeZoneHandling.cs
@@ -0,0 +1,53 @@
+#region License
+// 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.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Specifies how to treat the time value when converting between string and <see cref="DateTime"/>.
+  /// </summary>
+  public enum DateTimeZoneHandling
+  {
+    /// <summary>
+    /// Treat as local time. If the <see cref="DateTime"/> object represents a Coordinated Universal Time (UTC), it is converted to the local time.
+    /// </summary>
+    Local,
+    /// <summary>
+    /// Treat as a UTC. If the <see cref="DateTime"/> object represents a local time, it is converted to a UTC.
+    /// </summary>
+    Utc,
+    /// <summary>
+    /// Treat as a local time if a <see cref="DateTime"/> is being converted to a string.
+    /// If a string is being converted to <see cref="DateTime"/>, convert to a local time if a time zone is specified.
+    /// </summary>
+    Unspecified,
+    /// <summary>
+    /// Time zone information should be preserved when converting.
+    /// </summary>
+    RoundtripKind
+  }
+}
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/DefaultValueHandling.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/DefaultValueHandling.cs
index 570d684..91d3738 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/DefaultValueHandling.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/DefaultValueHandling.cs
@@ -1,47 +1,60 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Newtonsoft.Json
-{
-  /// <summary>
-  /// Specifies default value handling options for the <see cref="JsonSerializer"/>.
-  /// </summary>
-  public enum DefaultValueHandling
-  {
-    /// <summary>
-    /// Include default values when serializing and deserializing objects.
-    /// </summary>
-    Include = 0,
-    /// <summary>
-    /// Ignore default values when serializing and deserializing objects.
-    /// </summary>
-    Ignore = 1
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Specifies default value handling options for the <see cref="JsonSerializer"/>.
+  /// </summary>
+  /// <example>
+  ///   <code lang="cs" source="..\Src\Newtonsoft.Json.Tests\Documentation\SerializationTests.cs" region="ReducingSerializedJsonSizeDefaultValueHandlingObject" title="DefaultValueHandling Class" />
+  ///   <code lang="cs" source="..\Src\Newtonsoft.Json.Tests\Documentation\SerializationTests.cs" region="ReducingSerializedJsonSizeDefaultValueHandlingExample" title="DefaultValueHandling Ignore Example" />
+  /// </example>
+  [Flags]
+  public enum DefaultValueHandling
+  {
+    /// <summary>
+    /// Include members where the member value is the same as the member's default value when serializing objects.
+    /// Included members are written to JSON. Has no effect when deserializing.
+    /// </summary>
+    Include = 0,
+    /// <summary>
+    /// Ignore members where the member value is the same as the member's default value when serializing objects
+    /// so that is is not written to JSON, and ignores setting members when the JSON value equals the member's default value.
+    /// </summary>
+    Ignore = 1,
+    /// <summary>
+    /// Members with a default value but no JSON will be set to their default value when deserializing.
+    /// </summary>
+    Populate = 2,
+    /// <summary>
+    /// Ignore members where the member value is the same as the member's default value when serializing objects
+    /// and sets members to their default value when deserializing.
+    /// </summary>
+    IgnoreAndPopulate = Ignore | Populate
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/FormatterAssemblyStyle.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/FormatterAssemblyStyle.cs
index 7cfff8b..215e866 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/FormatterAssemblyStyle.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/FormatterAssemblyStyle.cs
@@ -1,19 +1,19 @@
-#if SILVERLIGHT || PocketPC
-namespace System.Runtime.Serialization.Formatters
-{
-  /// <summary>
-  /// Indicates the method that will be used during deserialization for locating and loading assemblies.
-  /// </summary>
-  public enum FormatterAssemblyStyle
-  {
-    /// <summary>
-    /// In simple mode, the assembly used during deserialization need not match exactly the assembly used during serialization. Specifically, the version numbers need not match as the LoadWithPartialName method is used to load the assembly.
-    /// </summary>
-    Simple,
-    /// <summary>
-    /// In full mode, the assembly used during deserialization must match exactly the assembly used during serialization. The Load method of the Assembly class is used to load the assembly.
-    /// </summary>
-    Full
-  }
-}
+#if SILVERLIGHT || PocketPC || NETFX_CORE || PORTABLE
+namespace System.Runtime.Serialization.Formatters
+{
+  /// <summary>
+  /// Indicates the method that will be used during deserialization for locating and loading assemblies.
+  /// </summary>
+  public enum FormatterAssemblyStyle
+  {
+    /// <summary>
+    /// In simple mode, the assembly used during deserialization need not match exactly the assembly used during serialization. Specifically, the version numbers need not match as the LoadWithPartialName method is used to load the assembly.
+    /// </summary>
+    Simple,
+    /// <summary>
+    /// In full mode, the assembly used during deserialization must match exactly the assembly used during serialization. The Load method of the Assembly class is used to load the assembly.
+    /// </summary>
+    Full
+  }
+}
 #endif
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Formatting.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Formatting.cs
new file mode 100644
index 0000000..c3121aa
--- /dev/null
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Formatting.cs
@@ -0,0 +1,42 @@
+#region License
+// 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.
+#endregion
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Specifies formatting options for the <see cref="JsonTextWriter"/>.
+  /// </summary>
+  public enum Formatting
+  {
+    /// <summary>
+    /// No special formatting is applied. This is the default.
+    /// </summary>
+    None,
+    /// <summary>
+    /// Causes child objects to be indented according to the <see cref="JsonTextWriter.Indentation"/> and <see cref="JsonTextWriter.IndentChar"/> settings.
+    /// </summary>
+    Indented
+  }
+}
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/IJsonLineInfo.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/IJsonLineInfo.cs
index 29c38f0..f863e30 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/IJsonLineInfo.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/IJsonLineInfo.cs
@@ -1,32 +1,52 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Newtonsoft.Json
-{
-  /// <summary>
-  /// Provides an interface to enable a class to return line and position information.
-  /// </summary>
-  public interface IJsonLineInfo
-  {
-    /// <summary>
-    /// Gets a value indicating whether the class can return line information.
-    /// </summary>
-    /// <returns>
-    /// 	<c>true</c> if LineNumber and LinePosition can be provided; otherwise, <c>false</c>.
-    /// </returns>
-    bool HasLineInfo();
-
-    /// <summary>
-    /// Gets the current line number.
-    /// </summary>
-    /// <value>The current line number or 0 if no line information is available (for example, HasLineInfo returns false).</value>
-    int LineNumber { get; }
-    /// <summary>
-    /// Gets the current line position.
-    /// </summary>
-    /// <value>The current line position or 0 if no line information is available (for example, HasLineInfo returns false).</value>
-    int LinePosition { get; }
-  }
+#region License
+// 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.
+#endregion
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Provides an interface to enable a class to return line and position information.
+  /// </summary>
+  public interface IJsonLineInfo
+  {
+    /// <summary>
+    /// Gets a value indicating whether the class can return line information.
+    /// </summary>
+    /// <returns>
+    /// 	<c>true</c> if LineNumber and LinePosition can be provided; otherwise, <c>false</c>.
+    /// </returns>
+    bool HasLineInfo();
+
+    /// <summary>
+    /// Gets the current line number.
+    /// </summary>
+    /// <value>The current line number or 0 if no line information is available (for example, HasLineInfo returns false).</value>
+    int LineNumber { get; }
+    /// <summary>
+    /// Gets the current line position.
+    /// </summary>
+    /// <value>The current line position or 0 if no line information is available (for example, HasLineInfo returns false).</value>
+    int LinePosition { get; }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonArrayAttribute.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonArrayAttribute.cs
index 64a5d02..440c1a9 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonArrayAttribute.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonArrayAttribute.cs
@@ -1,76 +1,73 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Newtonsoft.Json
-{
-  /// <summary>
-  /// Instructs the <see cref="JsonSerializer"/> how to serialize the collection.
-  /// </summary>
-  [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
-  public sealed class JsonArrayAttribute : JsonContainerAttribute
-  {
-    private bool _allowNullItems;
-
-    /// <summary>
-    /// Gets or sets a value indicating whether null items are allowed in the collection.
-    /// </summary>
-    /// <value><c>true</c> if null items are allowed in the collection; otherwise, <c>false</c>.</value>
-    public bool AllowNullItems
-    {
-      get { return _allowNullItems; }
-      set { _allowNullItems = value; }
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonArrayAttribute"/> class.
-    /// </summary>
-    public JsonArrayAttribute()
-    {
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonObjectAttribute"/> class with a flag indicating whether the array can contain null items
-    /// </summary>
-    /// <param name="allowNullItems">A flag indicating whether the array can contain null items.</param>
-    public JsonArrayAttribute(bool allowNullItems)
-    {
-      _allowNullItems = allowNullItems;
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonArrayAttribute"/> class with the specified container Id.
-    /// </summary>
-    /// <param name="id">The container Id.</param>
-    public JsonArrayAttribute(string id)
-      : base(id)
-    {
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Instructs the <see cref="JsonSerializer"/> how to serialize the collection.
+  /// </summary>
+  [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
+  public sealed class JsonArrayAttribute : JsonContainerAttribute
+  {
+    private bool _allowNullItems;
+
+    /// <summary>
+    /// Gets or sets a value indicating whether null items are allowed in the collection.
+    /// </summary>
+    /// <value><c>true</c> if null items are allowed in the collection; otherwise, <c>false</c>.</value>
+    public bool AllowNullItems
+    {
+      get { return _allowNullItems; }
+      set { _allowNullItems = value; }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonArrayAttribute"/> class.
+    /// </summary>
+    public JsonArrayAttribute()
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonObjectAttribute"/> class with a flag indicating whether the array can contain null items
+    /// </summary>
+    /// <param name="allowNullItems">A flag indicating whether the array can contain null items.</param>
+    public JsonArrayAttribute(bool allowNullItems)
+    {
+      _allowNullItems = allowNullItems;
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonArrayAttribute"/> class with the specified container Id.
+    /// </summary>
+    /// <param name="id">The container Id.</param>
+    public JsonArrayAttribute(string id)
+      : base(id)
+    {
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConstructorAttribute.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConstructorAttribute.cs
new file mode 100644
index 0000000..3ea20c9
--- /dev/null
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConstructorAttribute.cs
@@ -0,0 +1,37 @@
+#region License
+// 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.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Instructs the <see cref="JsonSerializer"/> to use the specified constructor when deserializing that object.
+  /// </summary>
+  [AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false)]
+  public sealed class JsonConstructorAttribute : Attribute
+  {
+  }
+}
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonContainerAttribute.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonContainerAttribute.cs
index a83c828..ce2674e 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonContainerAttribute.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonContainerAttribute.cs
@@ -1,87 +1,125 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Newtonsoft.Json
-{
-  /// <summary>
-  /// Instructs the <see cref="JsonSerializer"/> how to serialize the object.
-  /// </summary>
-  [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
-  public abstract class JsonContainerAttribute : Attribute
-  {
-    /// <summary>
-    /// Gets or sets the id.
-    /// </summary>
-    /// <value>The id.</value>
-    public string Id { get; set; }
-    /// <summary>
-    /// Gets or sets the title.
-    /// </summary>
-    /// <value>The title.</value>
-    public string Title { get; set; }
-    /// <summary>
-    /// Gets or sets the description.
-    /// </summary>
-    /// <value>The description.</value>
-    public string Description { get; set; }
-
-    // yuck. can't set nullable properties on an attribute in C#
-    // have to use this approach to get an unset default state
-    internal bool? _isReference;
-
-    /// <summary>
-    /// Gets or sets a value that indicates whether to preserve object reference data.
-    /// </summary>
-    /// <value>
-    /// 	<c>true</c> to keep object reference; otherwise, <c>false</c>. The default is <c>false</c>.
-    /// </value>
-    public bool IsReference
-    {
-      get { return _isReference ?? default(bool); }
-      set { _isReference = value; }
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonContainerAttribute"/> class.
-    /// </summary>
-    protected JsonContainerAttribute()
-    {
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonContainerAttribute"/> class with the specified container Id.
-    /// </summary>
-    /// <param name="id">The container Id.</param>
-    protected JsonContainerAttribute(string id)
-    {
-      Id = id;
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Instructs the <see cref="JsonSerializer"/> how to serialize the object.
+  /// </summary>
+  [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
+  public abstract class JsonContainerAttribute : Attribute
+  {
+    /// <summary>
+    /// Gets or sets the id.
+    /// </summary>
+    /// <value>The id.</value>
+    public string Id { get; set; }
+    /// <summary>
+    /// Gets or sets the title.
+    /// </summary>
+    /// <value>The title.</value>
+    public string Title { get; set; }
+    /// <summary>
+    /// Gets or sets the description.
+    /// </summary>
+    /// <value>The description.</value>
+    public string Description { get; set; }
+
+    /// <summary>
+    /// Gets the collection's items converter.
+    /// </summary>
+    /// <value>The collection's items converter.</value>
+    public Type ItemConverterType { get; set; }
+
+    // yuck. can't set nullable properties on an attribute in C#
+    // have to use this approach to get an unset default state
+    internal bool? _isReference;
+    internal bool? _itemIsReference;
+    internal ReferenceLoopHandling? _itemReferenceLoopHandling;
+    internal TypeNameHandling? _itemTypeNameHandling;
+
+    /// <summary>
+    /// Gets or sets a value that indicates whether to preserve object references.
+    /// </summary>
+    /// <value>
+    /// 	<c>true</c> to keep object reference; otherwise, <c>false</c>. The default is <c>false</c>.
+    /// </value>
+    public bool IsReference
+    {
+      get { return _isReference ?? default(bool); }
+      set { _isReference = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets a value that indicates whether to preserve collection's items references.
+    /// </summary>
+    /// <value>
+    /// 	<c>true</c> to keep collection's items object references; otherwise, <c>false</c>. The default is <c>false</c>.
+    /// </value>
+    public bool ItemIsReference
+    {
+      get { return _itemIsReference ?? default(bool); }
+      set { _itemIsReference = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets the reference loop handling used when serializing the collection's items.
+    /// </summary>
+    /// <value>The reference loop handling.</value>
+    public ReferenceLoopHandling ItemReferenceLoopHandling
+    {
+      get { return _itemReferenceLoopHandling ?? default(ReferenceLoopHandling); }
+      set { _itemReferenceLoopHandling = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets the type name handling used when serializing the collection's items.
+    /// </summary>
+    /// <value>The type name handling.</value>
+    public TypeNameHandling ItemTypeNameHandling
+    {
+      get { return _itemTypeNameHandling ?? default(TypeNameHandling); }
+      set { _itemTypeNameHandling = value; }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonContainerAttribute"/> class.
+    /// </summary>
+    protected JsonContainerAttribute()
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonContainerAttribute"/> class with the specified container Id.
+    /// </summary>
+    /// <param name="id">The container Id.</param>
+    protected JsonContainerAttribute(string id)
+    {
+      Id = id;
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConvert.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConvert.cs
index c824cad..5d3aa92 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConvert.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConvert.cs
@@ -1,848 +1,1201 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.IO;
-using System.Globalization;
-using Newtonsoft.Json.Utilities;
-using System.Xml;
-using Newtonsoft.Json.Converters;
-using System.Text;
-#if !NET20 && !SILVERLIGHT
-using System.Xml.Linq;
-#endif
-
-namespace Newtonsoft.Json
-{
-  /// <summary>
-  /// Provides methods for converting between common language runtime types and JSON types.
-  /// </summary>
-  public static class JsonConvert
-  {
-    /// <summary>
-    /// Represents JavaScript's boolean value true as a string. This field is read-only.
-    /// </summary>
-    public static readonly string True = "true";
-
-    /// <summary>
-    /// Represents JavaScript's boolean value false as a string. This field is read-only.
-    /// </summary>
-    public static readonly string False = "false";
-
-    /// <summary>
-    /// Represents JavaScript's null as a string. This field is read-only.
-    /// </summary>
-    public static readonly string Null = "null";
-
-    /// <summary>
-    /// Represents JavaScript's undefined as a string. This field is read-only.
-    /// </summary>
-    public static readonly string Undefined = "undefined";
-
-    /// <summary>
-    /// Represents JavaScript's positive infinity as a string. This field is read-only.
-    /// </summary>
-    public static readonly string PositiveInfinity = "Infinity";
-
-    /// <summary>
-    /// Represents JavaScript's negative infinity as a string. This field is read-only.
-    /// </summary>
-    public static readonly string NegativeInfinity = "-Infinity";
-
-    /// <summary>
-    /// Represents JavaScript's NaN as a string. This field is read-only.
-    /// </summary>
-    public static readonly string NaN = "NaN";
-
-    internal static readonly long InitialJavaScriptDateTicks = 621355968000000000;
-
-    /// <summary>
-    /// Converts the <see cref="DateTime"/> to its JSON string representation.
-    /// </summary>
-    /// <param name="value">The value to convert.</param>
-    /// <returns>A JSON string representation of the <see cref="DateTime"/>.</returns>
-    public static string ToString(DateTime value)
-    {
-      using (StringWriter writer = StringUtils.CreateStringWriter(64))
-      {
-        WriteDateTimeString(writer, value, GetUtcOffset(value), value.Kind);
-        return writer.ToString();
-      }
-    }
-
-#if !PocketPC && !NET20
-    /// <summary>
-    /// Converts the <see cref="DateTimeOffset"/> to its JSON string representation.
-    /// </summary>
-    /// <param name="value">The value to convert.</param>
-    /// <returns>A JSON string representation of the <see cref="DateTimeOffset"/>.</returns>
-    public static string ToString(DateTimeOffset value)
-    {
-      using (StringWriter writer = StringUtils.CreateStringWriter(64))
-      {
-        WriteDateTimeString(writer, value.UtcDateTime, value.Offset, DateTimeKind.Local);
-        return writer.ToString();
-      }
-    }
-#endif
-
-    private static TimeSpan GetUtcOffset(DateTime dateTime)
-    {
-#if SILVERLIGHT
-      return TimeZoneInfo.Local.GetUtcOffset(dateTime);
-#else
-      return TimeZone.CurrentTimeZone.GetUtcOffset(dateTime);
-#endif
-    }
-
-    internal static void WriteDateTimeString(TextWriter writer, DateTime value)
-    {
-      WriteDateTimeString(writer, value, GetUtcOffset(value), value.Kind);
-    }
-
-    internal static void WriteDateTimeString(TextWriter writer, DateTime value, TimeSpan offset, DateTimeKind kind)
-    {
-      long javaScriptTicks = ConvertDateTimeToJavaScriptTicks(value, offset);
-
-      writer.Write(@"""\/Date(");
-      writer.Write(javaScriptTicks);
-      
-      switch (kind)
-      {
-        case DateTimeKind.Local:
-        case DateTimeKind.Unspecified:
-          writer.Write((offset.Ticks >= 0L) ? "+" : "-");
-
-          int absHours = Math.Abs(offset.Hours);
-          if (absHours < 10)
-            writer.Write(0);
-          writer.Write(absHours);
-          int absMinutes = Math.Abs(offset.Minutes);
-          if (absMinutes < 10)
-            writer.Write(0);
-          writer.Write(absMinutes);
-          break;
-      }
-
-      writer.Write(@")\/""");
-    }
-
-    private static long ToUniversalTicks(DateTime dateTime)
-    {
-      if (dateTime.Kind == DateTimeKind.Utc)
-        return dateTime.Ticks;
-
-      return ToUniversalTicks(dateTime, GetUtcOffset(dateTime));
-    }
-
-    private static long ToUniversalTicks(DateTime dateTime, TimeSpan offset)
-    {
-      if (dateTime.Kind == DateTimeKind.Utc)
-        return dateTime.Ticks;
-
-      long ticks = dateTime.Ticks - offset.Ticks;
-      if (ticks > 3155378975999999999L)
-        return 3155378975999999999L;
-
-      if (ticks < 0L)
-        return 0L;
-
-      return ticks;
-    }
-
-    internal static long ConvertDateTimeToJavaScriptTicks(DateTime dateTime, TimeSpan offset)
-    {
-      long universialTicks = ToUniversalTicks(dateTime, offset);
-
-      return UniversialTicksToJavaScriptTicks(universialTicks);
-    }
-
-    internal static long ConvertDateTimeToJavaScriptTicks(DateTime dateTime)
-    {
-      return ConvertDateTimeToJavaScriptTicks(dateTime, true);
-    }
-
-    internal static long ConvertDateTimeToJavaScriptTicks(DateTime dateTime, bool convertToUtc)
-    {
-      long ticks = (convertToUtc) ? ToUniversalTicks(dateTime) : dateTime.Ticks;
-
-      return UniversialTicksToJavaScriptTicks(ticks);
-    }
-
-    private static long UniversialTicksToJavaScriptTicks(long universialTicks)
-    {
-      long javaScriptTicks = (universialTicks - InitialJavaScriptDateTicks) / 10000;
-
-      return javaScriptTicks;
-    }
-
-    internal static DateTime ConvertJavaScriptTicksToDateTime(long javaScriptTicks)
-    {
-      DateTime dateTime = new DateTime((javaScriptTicks * 10000) + InitialJavaScriptDateTicks, DateTimeKind.Utc);
-
-      return dateTime;
-    }
-
-    /// <summary>
-    /// Converts the <see cref="Boolean"/> to its JSON string representation.
-    /// </summary>
-    /// <param name="value">The value to convert.</param>
-    /// <returns>A JSON string representation of the <see cref="Boolean"/>.</returns>
-    public static string ToString(bool value)
-    {
-      return (value) ? True : False;
-    }
-
-    /// <summary>
-    /// Converts the <see cref="Char"/> to its JSON string representation.
-    /// </summary>
-    /// <param name="value">The value to convert.</param>
-    /// <returns>A JSON string representation of the <see cref="Char"/>.</returns>
-    public static string ToString(char value)
-    {
-      return ToString(char.ToString(value));
-    }
-
-    /// <summary>
-    /// Converts the <see cref="Enum"/> to its JSON string representation.
-    /// </summary>
-    /// <param name="value">The value to convert.</param>
-    /// <returns>A JSON string representation of the <see cref="Enum"/>.</returns>
-    public static string ToString(Enum value)
-    {
-      return value.ToString("D");
-    }
-
-    /// <summary>
-    /// Converts the <see cref="Int32"/> to its JSON string representation.
-    /// </summary>
-    /// <param name="value">The value to convert.</param>
-    /// <returns>A JSON string representation of the <see cref="Int32"/>.</returns>
-    public static string ToString(int value)
-    {
-      return value.ToString(null, CultureInfo.InvariantCulture);
-    }
-
-    /// <summary>
-    /// Converts the <see cref="Int16"/> to its JSON string representation.
-    /// </summary>
-    /// <param name="value">The value to convert.</param>
-    /// <returns>A JSON string representation of the <see cref="Int16"/>.</returns>
-    public static string ToString(short value)
-    {
-      return value.ToString(null, CultureInfo.InvariantCulture);
-    }
-
-    /// <summary>
-    /// Converts the <see cref="UInt16"/> to its JSON string representation.
-    /// </summary>
-    /// <param name="value">The value to convert.</param>
-    /// <returns>A JSON string representation of the <see cref="UInt16"/>.</returns>
-    [CLSCompliant(false)]
-    public static string ToString(ushort value)
-    {
-      return value.ToString(null, CultureInfo.InvariantCulture);
-    }
-
-    /// <summary>
-    /// Converts the <see cref="UInt32"/> to its JSON string representation.
-    /// </summary>
-    /// <param name="value">The value to convert.</param>
-    /// <returns>A JSON string representation of the <see cref="UInt32"/>.</returns>
-    [CLSCompliant(false)]
-    public static string ToString(uint value)
-    {
-      return value.ToString(null, CultureInfo.InvariantCulture);
-    }
-
-    /// <summary>
-    /// Converts the <see cref="Int64"/>  to its JSON string representation.
-    /// </summary>
-    /// <param name="value">The value to convert.</param>
-    /// <returns>A JSON string representation of the <see cref="Int64"/>.</returns>
-    public static string ToString(long value)
-    {
-      return value.ToString(null, CultureInfo.InvariantCulture);
-    }
-
-    /// <summary>
-    /// Converts the <see cref="UInt64"/> to its JSON string representation.
-    /// </summary>
-    /// <param name="value">The value to convert.</param>
-    /// <returns>A JSON string representation of the <see cref="UInt64"/>.</returns>
-    [CLSCompliant(false)]
-    public static string ToString(ulong value)
-    {
-      return value.ToString(null, CultureInfo.InvariantCulture);
-    }
-
-    /// <summary>
-    /// Converts the <see cref="Single"/> to its JSON string representation.
-    /// </summary>
-    /// <param name="value">The value to convert.</param>
-    /// <returns>A JSON string representation of the <see cref="Single"/>.</returns>
-    public static string ToString(float value)
-    {
-      return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture));
-    }
-
-    /// <summary>
-    /// Converts the <see cref="Double"/> to its JSON string representation.
-    /// </summary>
-    /// <param name="value">The value to convert.</param>
-    /// <returns>A JSON string representation of the <see cref="Double"/>.</returns>
-    public static string ToString(double value)
-    {
-      return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture));
-    }
-
-    private static string EnsureDecimalPlace(double value, string text)
-    {
-      if (double.IsNaN(value) || double.IsInfinity(value) || text.IndexOf('.') != -1 || text.IndexOf('E') != -1)
-        return text;
-
-      return text + ".0";
-    }
-
-    private static string EnsureDecimalPlace(string text)
-    {
-      if (text.IndexOf('.') != -1)
-        return text;
-
-      return text + ".0";
-    }
-
-    /// <summary>
-    /// Converts the <see cref="Byte"/> to its JSON string representation.
-    /// </summary>
-    /// <param name="value">The value to convert.</param>
-    /// <returns>A JSON string representation of the <see cref="Byte"/>.</returns>
-    public static string ToString(byte value)
-    {
-      return value.ToString(null, CultureInfo.InvariantCulture);
-    }
-
-    /// <summary>
-    /// Converts the <see cref="SByte"/> to its JSON string representation.
-    /// </summary>
-    /// <param name="value">The value to convert.</param>
-    /// <returns>A JSON string representation of the <see cref="SByte"/>.</returns>
-    [CLSCompliant(false)]
-    public static string ToString(sbyte value)
-    {
-      return value.ToString(null, CultureInfo.InvariantCulture);
-    }
-
-    /// <summary>
-    /// Converts the <see cref="Decimal"/> to its JSON string representation.
-    /// </summary>
-    /// <param name="value">The value to convert.</param>
-    /// <returns>A JSON string representation of the <see cref="SByte"/>.</returns>
-    public static string ToString(decimal value)
-    {
-      return EnsureDecimalPlace(value.ToString(null, CultureInfo.InvariantCulture));
-    }
-
-    /// <summary>
-    /// Converts the <see cref="Guid"/> to its JSON string representation.
-    /// </summary>
-    /// <param name="value">The value to convert.</param>
-    /// <returns>A JSON string representation of the <see cref="Guid"/>.</returns>
-    public static string ToString(Guid value)
-    {
-      return '"' + value.ToString("D", CultureInfo.InvariantCulture) + '"';
-    }
-
-    /// <summary>
-    /// Converts the <see cref="String"/> to its JSON string representation.
-    /// </summary>
-    /// <param name="value">The value to convert.</param>
-    /// <returns>A JSON string representation of the <see cref="String"/>.</returns>
-    public static string ToString(string value)
-    {
-      return ToString(value, '"');
-    }
-
-    /// <summary>
-    /// Converts the <see cref="String"/> to its JSON string representation.
-    /// </summary>
-    /// <param name="value">The value to convert.</param>
-    /// <param name="delimter">The string delimiter character.</param>
-    /// <returns>A JSON string representation of the <see cref="String"/>.</returns>
-    public static string ToString(string value, char delimter)
-    {
-      return JavaScriptUtils.ToEscapedJavaScriptString(value, delimter, true);
-    }
-
-    /// <summary>
-    /// Converts the <see cref="Object"/> to its JSON string representation.
-    /// </summary>
-    /// <param name="value">The value to convert.</param>
-    /// <returns>A JSON string representation of the <see cref="Object"/>.</returns>
-    public static string ToString(object value)
-    {
-      if (value == null)
-        return Null;
-
-      IConvertible convertible = value as IConvertible;
-
-      if (convertible != null)
-      {
-        switch (convertible.GetTypeCode())
-        {
-          case TypeCode.String:
-            return ToString(convertible.ToString(CultureInfo.InvariantCulture));
-          case TypeCode.Char:
-            return ToString(convertible.ToChar(CultureInfo.InvariantCulture));
-          case TypeCode.Boolean:
-            return ToString(convertible.ToBoolean(CultureInfo.InvariantCulture));
-          case TypeCode.SByte:
-            return ToString(convertible.ToSByte(CultureInfo.InvariantCulture));
-          case TypeCode.Int16:
-            return ToString(convertible.ToInt16(CultureInfo.InvariantCulture));
-          case TypeCode.UInt16:
-            return ToString(convertible.ToUInt16(CultureInfo.InvariantCulture));
-          case TypeCode.Int32:
-            return ToString(convertible.ToInt32(CultureInfo.InvariantCulture));
-          case TypeCode.Byte:
-            return ToString(convertible.ToByte(CultureInfo.InvariantCulture));
-          case TypeCode.UInt32:
-            return ToString(convertible.ToUInt32(CultureInfo.InvariantCulture));
-          case TypeCode.Int64:
-            return ToString(convertible.ToInt64(CultureInfo.InvariantCulture));
-          case TypeCode.UInt64:
-            return ToString(convertible.ToUInt64(CultureInfo.InvariantCulture));
-          case TypeCode.Single:
-            return ToString(convertible.ToSingle(CultureInfo.InvariantCulture));
-          case TypeCode.Double:
-            return ToString(convertible.ToDouble(CultureInfo.InvariantCulture));
-          case TypeCode.DateTime:
-            return ToString(convertible.ToDateTime(CultureInfo.InvariantCulture));
-          case TypeCode.Decimal:
-            return ToString(convertible.ToDecimal(CultureInfo.InvariantCulture));
-          case TypeCode.DBNull:
-            return Null;
-        }
-      }
-#if !PocketPC && !NET20
-      else if (value is DateTimeOffset)
-      {
-        return ToString((DateTimeOffset)value);
-      }
-#endif
-
-      throw new ArgumentException("Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType()));
-    }
-
-    private static bool IsJsonPrimitiveTypeCode(TypeCode typeCode)
-    {
-      switch (typeCode)
-      {
-        case TypeCode.String:
-        case TypeCode.Char:
-        case TypeCode.Boolean:
-        case TypeCode.SByte:
-        case TypeCode.Int16:
-        case TypeCode.UInt16:
-        case TypeCode.Int32:
-        case TypeCode.Byte:
-        case TypeCode.UInt32:
-        case TypeCode.Int64:
-        case TypeCode.UInt64:
-        case TypeCode.Single:
-        case TypeCode.Double:
-        case TypeCode.DateTime:
-        case TypeCode.Decimal:
-        case TypeCode.DBNull:
-          return true;
-        default:
-          return false;
-      }
-    }
-
-    internal static bool IsJsonPrimitiveType(Type type)
-    {
-      if (ReflectionUtils.IsNullableType(type))
-        type = Nullable.GetUnderlyingType(type);
-
-#if !PocketPC && !NET20
-     if (type == typeof(DateTimeOffset))
-        return true;
-#endif
-      if (type == typeof(byte[]))
-        return true;
-
-      return IsJsonPrimitiveTypeCode(Type.GetTypeCode(type));
-    }
-
-    internal static bool IsJsonPrimitive(object value)
-    {
-      if (value == null)
-        return true;
-
-      IConvertible convertible = value as IConvertible;
-
-      if (convertible != null)
-        return IsJsonPrimitiveTypeCode(convertible.GetTypeCode());
-
-#if !PocketPC && !NET20
-      if (value is DateTimeOffset)
-        return true;
-#endif
-
-      if (value is byte[])
-        return true;
-
-      return false;
-    }
-
-    /// <summary>
-    /// Serializes the specified object to a JSON string.
-    /// </summary>
-    /// <param name="value">The object to serialize.</param>
-    /// <returns>A JSON string representation of the object.</returns>
-    public static string SerializeObject(object value)
-    {
-      return SerializeObject(value, Formatting.None, (JsonSerializerSettings)null);
-    }
-
-    /// <summary>
-    /// Serializes the specified object to a JSON string.
-    /// </summary>
-    /// <param name="value">The object to serialize.</param>
-    /// <param name="formatting">Indicates how the output is formatted.</param>
-    /// <returns>
-    /// A JSON string representation of the object.
-    /// </returns>
-    public static string SerializeObject(object value, Formatting formatting)
-    {
-      return SerializeObject(value, formatting, (JsonSerializerSettings)null);
-    }
-
-    /// <summary>
-    /// Serializes the specified object to a JSON string using a collection of <see cref="JsonConverter"/>.
-    /// </summary>
-    /// <param name="value">The object to serialize.</param>
-    /// <param name="converters">A collection converters used while serializing.</param>
-    /// <returns>A JSON string representation of the object.</returns>
-    public static string SerializeObject(object value, params JsonConverter[] converters)
-    {
-      return SerializeObject(value, Formatting.None, converters);
-    }
-
-    /// <summary>
-    /// Serializes the specified object to a JSON string using a collection of <see cref="JsonConverter"/>.
-    /// </summary>
-    /// <param name="value">The object to serialize.</param>
-    /// <param name="formatting">Indicates how the output is formatted.</param>
-    /// <param name="converters">A collection converters used while serializing.</param>
-    /// <returns>A JSON string representation of the object.</returns>
-    public static string SerializeObject(object value, Formatting formatting, params JsonConverter[] converters)
-    {
-      JsonSerializerSettings settings = (converters != null && converters.Length > 0)
-        ? new JsonSerializerSettings { Converters = converters }
-        : null;
-
-      return SerializeObject(value, formatting, settings);
-    }
-
-    /// <summary>
-    /// Serializes the specified object to a JSON string using a collection of <see cref="JsonConverter"/>.
-    /// </summary>
-    /// <param name="value">The object to serialize.</param>
-    /// <param name="formatting">Indicates how the output is formatted.</param>
-    /// <param name="settings">The <see cref="JsonSerializerSettings"/> used to serialize the object.
-    /// If this is null, default serialization settings will be is used.</param>
-    /// <returns>
-    /// A JSON string representation of the object.
-    /// </returns>
-    public static string SerializeObject(object value, Formatting formatting, JsonSerializerSettings settings)
-    {
-      JsonSerializer jsonSerializer = JsonSerializer.Create(settings);
-
-      StringBuilder sb = new StringBuilder(128);
-      StringWriter sw = new StringWriter(sb, CultureInfo.InvariantCulture);
-      using (JsonTextWriter jsonWriter = new JsonTextWriter(sw))
-      {
-        jsonWriter.Formatting = formatting;
-
-        jsonSerializer.Serialize(jsonWriter, value);
-      }
-
-      return sw.ToString();
-    }
-
-    /// <summary>
-    /// Deserializes the specified object to a Json object.
-    /// </summary>
-    /// <param name="value">The object to deserialize.</param>
-    /// <returns>The deserialized object from the Json string.</returns>
-    public static object DeserializeObject(string value)
-    {
-      return DeserializeObject(value, null, (JsonSerializerSettings)null);
-    }
-
-    /// <summary>
-    /// Deserializes the specified object to a Json object.
-    /// </summary>
-    /// <param name="value">The object to deserialize.</param>
-    /// <param name="type">The <see cref="Type"/> of object being deserialized.</param>
-    /// <returns>The deserialized object from the Json string.</returns>
-    public static object DeserializeObject(string value, Type type)
-    {
-      return DeserializeObject(value, type, (JsonSerializerSettings)null);
-    }
-
-    /// <summary>
-    /// Deserializes the specified object to a Json object.
-    /// </summary>
-    /// <typeparam name="T">The type of the object to deserialize.</typeparam>
-    /// <param name="value">The object to deserialize.</param>
-    /// <returns>The deserialized object from the Json string.</returns>
-    public static T DeserializeObject<T>(string value)
-    {
-      return DeserializeObject<T>(value, (JsonSerializerSettings)null);
-    }
-
-    /// <summary>
-    /// Deserializes the specified JSON to the given anonymous type.
-    /// </summary>
-    /// <typeparam name="T">
-    /// The anonymous type to deserialize to. This can't be specified
-    /// traditionally and must be infered from the anonymous type passed
-    /// as a parameter.
-    /// </typeparam>
-    /// <param name="value">The object to deserialize.</param>
-    /// <param name="anonymousTypeObject">The anonymous type object.</param>
-    /// <returns>The deserialized anonymous type from the JSON string.</returns>
-    public static T DeserializeAnonymousType<T>(string value, T anonymousTypeObject)
-    {
-      return DeserializeObject<T>(value);
-    }
-
-    /// <summary>
-    /// Deserializes the JSON string to the specified type.
-    /// </summary>
-    /// <typeparam name="T">The type of the object to deserialize.</typeparam>
-    /// <param name="value">The object to deserialize.</param>
-    /// <param name="converters">Converters to use while deserializing.</param>
-    /// <returns>The deserialized object from the JSON string.</returns>
-    public static T DeserializeObject<T>(string value, params JsonConverter[] converters)
-    {
-      return (T)DeserializeObject(value, typeof(T), converters);
-    }
-
-    /// <summary>
-    /// Deserializes the JSON string to the specified type.
-    /// </summary>
-    /// <typeparam name="T">The type of the object to deserialize.</typeparam>
-    /// <param name="value">The object to deserialize.</param>
-    /// <param name="settings">
-    /// The <see cref="JsonSerializerSettings"/> used to deserialize the object.
-    /// If this is null, default serialization settings will be is used.
-    /// </param>
-    /// <returns>The deserialized object from the JSON string.</returns>
-    public static T DeserializeObject<T>(string value, JsonSerializerSettings settings)
-    {
-      return (T)DeserializeObject(value, typeof(T), settings);
-    }
-
-    /// <summary>
-    /// Deserializes the JSON string to the specified type.
-    /// </summary>
-    /// <param name="value">The object to deserialize.</param>
-    /// <param name="type">The type of the object to deserialize.</param>
-    /// <param name="converters">Converters to use while deserializing.</param>
-    /// <returns>The deserialized object from the JSON string.</returns>
-    public static object DeserializeObject(string value, Type type, params JsonConverter[] converters)
-    {
-      JsonSerializerSettings settings = (converters != null && converters.Length > 0)
-        ? new JsonSerializerSettings { Converters = converters }
-        : null;
-
-      return DeserializeObject(value, type, settings);
-    }
-
-    /// <summary>
-    /// Deserializes the JSON string to the specified type.
-    /// </summary>
-    /// <param name="value">The JSON to deserialize.</param>
-    /// <param name="type">The type of the object to deserialize.</param>
-    /// <param name="settings">
-    /// The <see cref="JsonSerializerSettings"/> used to deserialize the object.
-    /// If this is null, default serialization settings will be is used.
-    /// </param>
-    /// <returns>The deserialized object from the JSON string.</returns>
-    public static object DeserializeObject(string value, Type type, JsonSerializerSettings settings)
-    {
-      StringReader sr = new StringReader(value);
-      JsonSerializer jsonSerializer = JsonSerializer.Create(settings);
-
-      object deserializedValue;
-
-      using (JsonReader jsonReader = new JsonTextReader(sr))
-      {
-        deserializedValue = jsonSerializer.Deserialize(jsonReader, type);
-
-        if (jsonReader.Read() && jsonReader.TokenType != JsonToken.Comment)
-          throw new JsonSerializationException("Additional text found in JSON string after finishing deserializing object.");
-      }
-
-      return deserializedValue;
-    }
-
-    /// <summary>
-    /// Populates the object with values from the JSON string.
-    /// </summary>
-    /// <param name="value">The JSON to populate values from.</param>
-    /// <param name="target">The target object to populate values onto.</param>
-    public static void PopulateObject(string value, object target)
-    {
-      PopulateObject(value, target, null);
-    }
-
-
-    /// <summary>
-    /// Populates the object with values from the JSON string.
-    /// </summary>
-    /// <param name="value">The JSON to populate values from.</param>
-    /// <param name="target">The target object to populate values onto.</param>
-    /// <param name="settings">
-    /// The <see cref="JsonSerializerSettings"/> used to deserialize the object.
-    /// If this is null, default serialization settings will be is used.
-    /// </param>
-    public static void PopulateObject(string value, object target, JsonSerializerSettings settings)
-    {
-      StringReader sr = new StringReader(value);
-      JsonSerializer jsonSerializer = JsonSerializer.Create(settings);
-
-      using (JsonReader jsonReader = new JsonTextReader(sr))
-      {
-        jsonSerializer.Populate(jsonReader, target);
-
-        if (jsonReader.Read() && jsonReader.TokenType != JsonToken.Comment)
-          throw new JsonSerializationException("Additional text found in JSON string after finishing deserializing object.");
-      }
-    }
-
-#if !NET20 && !SILVERLIGHT
-    /// <summary>
-    /// Serializes the <see cref="XNode"/> to a JSON string.
-    /// </summary>
-    /// <param name="node">The node to convert to JSON.</param>
-    /// <returns>A JSON string of the XNode.</returns>
-    public static string SerializeXNode(XObject node)
-    {
-      return SerializeXNode(node, Formatting.None);
-    }
-
-    /// <summary>
-    /// Serializes the <see cref="XNode"/> to a JSON string.
-    /// </summary>
-    /// <param name="node">The node to convert to JSON.</param>
-    /// <param name="formatting">Indicates how the output is formatted.</param>
-    /// <returns>A JSON string of the XNode.</returns>
-    public static string SerializeXNode(XObject node, Formatting formatting)
-    {
-      XmlNodeConverter converter = new XmlNodeConverter();
-
-      return SerializeObject(node, formatting, converter);
-    }
-
-    /// <summary>
-    /// Deserializes the <see cref="XNode"/> from a JSON string.
-    /// </summary>
-    /// <param name="value">The JSON string.</param>
-    /// <returns>The deserialized XNode</returns>
-    public static XDocument DeserializeXNode(string value)
-    {
-      return DeserializeXNode(value, null);
-    }
-
-    /// <summary>
-    /// Deserializes the <see cref="XNode"/> from a JSON string nested in a root elment.
-    /// </summary>
-    /// <param name="value">The JSON string.</param>
-    /// <param name="deserializeRootElementName">The name of the root element to append when deserializing.</param>
-    /// <returns>The deserialized XNode</returns>
-    public static XDocument DeserializeXNode(string value, string deserializeRootElementName)
-    {
-      XmlNodeConverter converter = new XmlNodeConverter();
-      converter.DeserializeRootElementName = deserializeRootElementName;
-
-      return (XDocument)DeserializeObject(value, typeof(XDocument), converter);
-    }
-#endif
-
-#if !SILVERLIGHT
-    /// <summary>
-    /// Serializes the XML node to a JSON string.
-    /// </summary>
-    /// <param name="node">The node to serialize.</param>
-    /// <returns>A JSON string of the XmlNode.</returns>
-    public static string SerializeXmlNode(XmlNode node)
-    {
-      return SerializeXmlNode(node, Formatting.None);
-    }
-
-    /// <summary>
-    /// Serializes the XML node to a JSON string.
-    /// </summary>
-    /// <param name="node">The node to serialize.</param>
-    /// <param name="formatting">Indicates how the output is formatted.</param>
-    /// <returns>A JSON string of the XmlNode.</returns>
-    public static string SerializeXmlNode(XmlNode node, Formatting formatting)
-    {
-      XmlNodeConverter converter = new XmlNodeConverter();
-
-      return SerializeObject(node, formatting, converter);
-    }
-
-    /// <summary>
-    /// Deserializes the XmlNode from a JSON string.
-    /// </summary>
-    /// <param name="value">The JSON string.</param>
-    /// <returns>The deserialized XmlNode</returns>
-    public static XmlDocument DeserializeXmlNode(string value)
-    {
-      return DeserializeXmlNode(value, null);
-    }
-
-    /// <summary>
-    /// Deserializes the XmlNode from a JSON string nested in a root elment.
-    /// </summary>
-    /// <param name="value">The JSON string.</param>
-    /// <param name="deserializeRootElementName">The name of the root element to append when deserializing.</param>
-    /// <returns>The deserialized XmlNode</returns>
-    public static XmlDocument DeserializeXmlNode(string value, string deserializeRootElementName)
-    {
-      XmlNodeConverter converter = new XmlNodeConverter();
-      converter.DeserializeRootElementName = deserializeRootElementName;
-
-      return (XmlDocument)DeserializeObject(value, typeof(XmlDocument), converter);
-    }
-#endif
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.IO;
+using System.Globalization;
+#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE)
+using System.Threading.Tasks;
+#endif
+using Newtonsoft.Json.Utilities;
+using System.Xml;
+using Newtonsoft.Json.Converters;
+using System.Text;
+#if !NET20 && (!SILVERLIGHT || WINDOWS_PHONE) && !PORTABLE
+using System.Xml.Linq;
+#endif
+#if NETFX_CORE
+using IConvertible = Newtonsoft.Json.Utilities.Convertible;
+#endif
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Provides methods for converting between common language runtime types and JSON types.
+  /// </summary>
+  /// <example>
+  ///   <code lang="cs" source="..\Src\Newtonsoft.Json.Tests\Documentation\SerializationTests.cs" region="SerializeObject" title="Serializing and Deserializing JSON with JsonConvert" />
+  /// </example>
+  public static class JsonConvert
+  {
+    /// <summary>
+    /// Represents JavaScript's boolean value true as a string. This field is read-only.
+    /// </summary>
+    public static readonly string True = "true";
+
+    /// <summary>
+    /// Represents JavaScript's boolean value false as a string. This field is read-only.
+    /// </summary>
+    public static readonly string False = "false";
+
+    /// <summary>
+    /// Represents JavaScript's null as a string. This field is read-only.
+    /// </summary>
+    public static readonly string Null = "null";
+
+    /// <summary>
+    /// Represents JavaScript's undefined as a string. This field is read-only.
+    /// </summary>
+    public static readonly string Undefined = "undefined";
+
+    /// <summary>
+    /// Represents JavaScript's positive infinity as a string. This field is read-only.
+    /// </summary>
+    public static readonly string PositiveInfinity = "Infinity";
+
+    /// <summary>
+    /// Represents JavaScript's negative infinity as a string. This field is read-only.
+    /// </summary>
+    public static readonly string NegativeInfinity = "-Infinity";
+
+    /// <summary>
+    /// Represents JavaScript's NaN as a string. This field is read-only.
+    /// </summary>
+    public static readonly string NaN = "NaN";
+
+    internal static readonly long InitialJavaScriptDateTicks = 621355968000000000;
+
+    /// <summary>
+    /// Converts the <see cref="DateTime"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="DateTime"/>.</returns>
+    public static string ToString(DateTime value)
+    {
+      return ToString(value, DateFormatHandling.IsoDateFormat, DateTimeZoneHandling.RoundtripKind);
+    }
+
+    /// <summary>
+    /// Converts the <see cref="DateTime"/> to its JSON string representation using the <see cref="DateFormatHandling"/> specified.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <param name="format">The format the date will be converted to.</param>
+    /// <param name="timeZoneHandling">The time zone handling when the date is converted to a string.</param>
+    /// <returns>A JSON string representation of the <see cref="DateTime"/>.</returns>
+    public static string ToString(DateTime value, DateFormatHandling format, DateTimeZoneHandling timeZoneHandling)
+    {
+      DateTime updatedDateTime = EnsureDateTime(value, timeZoneHandling);
+
+      using (StringWriter writer = StringUtils.CreateStringWriter(64))
+      {
+        WriteDateTimeString(writer, updatedDateTime, updatedDateTime.GetUtcOffset(), updatedDateTime.Kind, format);
+        return writer.ToString();
+      }
+    }
+
+    internal static DateTime EnsureDateTime(DateTime value, DateTimeZoneHandling timeZone)
+    {
+      switch (timeZone)
+      {
+        case DateTimeZoneHandling.Local:
+          value = SwitchToLocalTime(value);
+          break;
+        case DateTimeZoneHandling.Utc:
+          value = SwitchToUtcTime(value);
+          break;
+        case DateTimeZoneHandling.Unspecified:
+          value = new DateTime(value.Ticks, DateTimeKind.Unspecified);
+          break;
+        case DateTimeZoneHandling.RoundtripKind:
+          break;
+        default:
+          throw new ArgumentException("Invalid date time handling value.");
+      }
+
+      return value;
+    }
+
+#if !PocketPC && !NET20
+    /// <summary>
+    /// Converts the <see cref="DateTimeOffset"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="DateTimeOffset"/>.</returns>
+    public static string ToString(DateTimeOffset value)
+    {
+      return ToString(value, DateFormatHandling.IsoDateFormat);
+    }
+
+    /// <summary>
+    /// Converts the <see cref="DateTimeOffset"/> to its JSON string representation using the <see cref="DateFormatHandling"/> specified.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <param name="format">The format the date will be converted to.</param>
+    /// <returns>A JSON string representation of the <see cref="DateTimeOffset"/>.</returns>
+    public static string ToString(DateTimeOffset value, DateFormatHandling format)
+    {
+      using (StringWriter writer = StringUtils.CreateStringWriter(64))
+      {
+        WriteDateTimeString(writer, (format == DateFormatHandling.IsoDateFormat) ? value.DateTime : value.UtcDateTime, value.Offset, DateTimeKind.Local, format);
+        return writer.ToString();
+      }
+    }
+#endif
+
+    internal static void WriteDateTimeString(TextWriter writer, DateTime value, DateFormatHandling format)
+    {
+      WriteDateTimeString(writer, value, value.GetUtcOffset(), value.Kind, format);
+    }
+
+    internal static void WriteDateTimeString(TextWriter writer, DateTime value, TimeSpan offset, DateTimeKind kind, DateFormatHandling format)
+    {
+      if (format == DateFormatHandling.MicrosoftDateFormat)
+      {
+        long javaScriptTicks = ConvertDateTimeToJavaScriptTicks(value, offset);
+
+        writer.Write(@"""\/Date(");
+        writer.Write(javaScriptTicks);
+
+        switch (kind)
+        {
+          case DateTimeKind.Unspecified:
+            if (value != DateTime.MaxValue && value != DateTime.MinValue)
+              WriteDateTimeOffset(writer, offset, format);
+            break;
+          case DateTimeKind.Local:
+            WriteDateTimeOffset(writer, offset, format);
+            break;
+        }
+
+        writer.Write(@")\/""");
+      }
+      else
+      {
+        writer.Write(@"""");
+        writer.Write(value.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFF", CultureInfo.InvariantCulture));
+
+        switch (kind)
+        {
+          case DateTimeKind.Local:
+            WriteDateTimeOffset(writer, offset, format);
+            break;
+          case DateTimeKind.Utc:
+            writer.Write("Z");
+            break;
+        }
+
+
+        writer.Write(@"""");
+      }
+    }
+
+    internal static void WriteDateTimeOffset(TextWriter writer, TimeSpan offset, DateFormatHandling format)
+    {
+      writer.Write((offset.Ticks >= 0L) ? "+" : "-");
+
+      int absHours = Math.Abs(offset.Hours);
+      if (absHours < 10)
+        writer.Write(0);
+      writer.Write(absHours);
+
+      if (format == DateFormatHandling.IsoDateFormat)
+        writer.Write(':');
+
+      int absMinutes = Math.Abs(offset.Minutes);
+      if (absMinutes < 10)
+        writer.Write(0);
+      writer.Write(absMinutes);
+    }
+
+    private static long ToUniversalTicks(DateTime dateTime)
+    {
+      if (dateTime.Kind == DateTimeKind.Utc)
+        return dateTime.Ticks;
+
+      return ToUniversalTicks(dateTime, dateTime.GetUtcOffset());
+    }
+
+    private static long ToUniversalTicks(DateTime dateTime, TimeSpan offset)
+    {
+      // special case min and max value
+      // they never have a timezone appended to avoid issues
+      if (dateTime.Kind == DateTimeKind.Utc || dateTime == DateTime.MaxValue || dateTime == DateTime.MinValue)
+        return dateTime.Ticks;
+
+      long ticks = dateTime.Ticks - offset.Ticks;
+      if (ticks > 3155378975999999999L)
+        return 3155378975999999999L;
+
+      if (ticks < 0L)
+        return 0L;
+
+      return ticks;
+    }
+
+    internal static long ConvertDateTimeToJavaScriptTicks(DateTime dateTime, TimeSpan offset)
+    {
+      long universialTicks = ToUniversalTicks(dateTime, offset);
+
+      return UniversialTicksToJavaScriptTicks(universialTicks);
+    }
+
+    internal static long ConvertDateTimeToJavaScriptTicks(DateTime dateTime)
+    {
+      return ConvertDateTimeToJavaScriptTicks(dateTime, true);
+    }
+
+    internal static long ConvertDateTimeToJavaScriptTicks(DateTime dateTime, bool convertToUtc)
+    {
+      long ticks = (convertToUtc) ? ToUniversalTicks(dateTime) : dateTime.Ticks;
+
+      return UniversialTicksToJavaScriptTicks(ticks);
+    }
+
+    private static long UniversialTicksToJavaScriptTicks(long universialTicks)
+    {
+      long javaScriptTicks = (universialTicks - InitialJavaScriptDateTicks)/10000;
+
+      return javaScriptTicks;
+    }
+
+    internal static DateTime ConvertJavaScriptTicksToDateTime(long javaScriptTicks)
+    {
+      DateTime dateTime = new DateTime((javaScriptTicks*10000) + InitialJavaScriptDateTicks, DateTimeKind.Utc);
+
+      return dateTime;
+    }
+
+    private static DateTime SwitchToLocalTime(DateTime value)
+    {
+      switch (value.Kind)
+      {
+        case DateTimeKind.Unspecified:
+          return new DateTime(value.Ticks, DateTimeKind.Local);
+
+        case DateTimeKind.Utc:
+          return value.ToLocalTime();
+
+        case DateTimeKind.Local:
+          return value;
+      }
+      return value;
+    }
+
+    private static DateTime SwitchToUtcTime(DateTime value)
+    {
+      switch (value.Kind)
+      {
+        case DateTimeKind.Unspecified:
+          return new DateTime(value.Ticks, DateTimeKind.Utc);
+
+        case DateTimeKind.Utc:
+          return value;
+
+        case DateTimeKind.Local:
+          return value.ToUniversalTime();
+      }
+      return value;
+    }
+
+    /// <summary>
+    /// Converts the <see cref="Boolean"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="Boolean"/>.</returns>
+    public static string ToString(bool value)
+    {
+      return (value) ? True : False;
+    }
+
+    /// <summary>
+    /// Converts the <see cref="Char"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="Char"/>.</returns>
+    public static string ToString(char value)
+    {
+      return ToString(char.ToString(value));
+    }
+
+    /// <summary>
+    /// Converts the <see cref="Enum"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="Enum"/>.</returns>
+    public static string ToString(Enum value)
+    {
+      return value.ToString("D");
+    }
+
+    /// <summary>
+    /// Converts the <see cref="Int32"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="Int32"/>.</returns>
+    public static string ToString(int value)
+    {
+      return value.ToString(null, CultureInfo.InvariantCulture);
+    }
+
+    /// <summary>
+    /// Converts the <see cref="Int16"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="Int16"/>.</returns>
+    public static string ToString(short value)
+    {
+      return value.ToString(null, CultureInfo.InvariantCulture);
+    }
+
+    /// <summary>
+    /// Converts the <see cref="UInt16"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="UInt16"/>.</returns>
+    [CLSCompliant(false)]
+    public static string ToString(ushort value)
+    {
+      return value.ToString(null, CultureInfo.InvariantCulture);
+    }
+
+    /// <summary>
+    /// Converts the <see cref="UInt32"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="UInt32"/>.</returns>
+    [CLSCompliant(false)]
+    public static string ToString(uint value)
+    {
+      return value.ToString(null, CultureInfo.InvariantCulture);
+    }
+
+    /// <summary>
+    /// Converts the <see cref="Int64"/>  to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="Int64"/>.</returns>
+    public static string ToString(long value)
+    {
+      return value.ToString(null, CultureInfo.InvariantCulture);
+    }
+
+    /// <summary>
+    /// Converts the <see cref="UInt64"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="UInt64"/>.</returns>
+    [CLSCompliant(false)]
+    public static string ToString(ulong value)
+    {
+      return value.ToString(null, CultureInfo.InvariantCulture);
+    }
+
+    /// <summary>
+    /// Converts the <see cref="Single"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="Single"/>.</returns>
+    public static string ToString(float value)
+    {
+      return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture));
+    }
+
+    /// <summary>
+    /// Converts the <see cref="Double"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="Double"/>.</returns>
+    public static string ToString(double value)
+    {
+      return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture));
+    }
+
+    private static string EnsureDecimalPlace(double value, string text)
+    {
+      if (double.IsNaN(value) || double.IsInfinity(value) || text.IndexOf('.') != -1 || text.IndexOf('E') != -1 || text.IndexOf('e') != -1)
+        return text;
+
+      return text + ".0";
+    }
+
+    private static string EnsureDecimalPlace(string text)
+    {
+      if (text.IndexOf('.') != -1)
+        return text;
+
+      return text + ".0";
+    }
+
+    /// <summary>
+    /// Converts the <see cref="Byte"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="Byte"/>.</returns>
+    public static string ToString(byte value)
+    {
+      return value.ToString(null, CultureInfo.InvariantCulture);
+    }
+
+    /// <summary>
+    /// Converts the <see cref="SByte"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="SByte"/>.</returns>
+    [CLSCompliant(false)]
+    public static string ToString(sbyte value)
+    {
+      return value.ToString(null, CultureInfo.InvariantCulture);
+    }
+
+    /// <summary>
+    /// Converts the <see cref="Decimal"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="SByte"/>.</returns>
+    public static string ToString(decimal value)
+    {
+      return EnsureDecimalPlace(value.ToString(null, CultureInfo.InvariantCulture));
+    }
+
+    /// <summary>
+    /// Converts the <see cref="Guid"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="Guid"/>.</returns>
+    public static string ToString(Guid value)
+    {
+      string text = null;
+
+#if !(NETFX_CORE || PORTABLE)
+      text = value.ToString("D", CultureInfo.InvariantCulture);
+#else
+      text = value.ToString("D");
+#endif
+
+      return '"' + text + '"';
+    }
+
+    /// <summary>
+    /// Converts the <see cref="TimeSpan"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="TimeSpan"/>.</returns>
+    public static string ToString(TimeSpan value)
+    {
+      return '"' + value.ToString() + '"';
+    }
+
+    /// <summary>
+    /// Converts the <see cref="Uri"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="Uri"/>.</returns>
+    public static string ToString(Uri value)
+    {
+      if (value == null)
+        return Null;
+
+      return ToString(value.ToString());
+    }
+
+    /// <summary>
+    /// Converts the <see cref="String"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="String"/>.</returns>
+    public static string ToString(string value)
+    {
+      return ToString(value, '"');
+    }
+
+    /// <summary>
+    /// Converts the <see cref="String"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <param name="delimter">The string delimiter character.</param>
+    /// <returns>A JSON string representation of the <see cref="String"/>.</returns>
+    public static string ToString(string value, char delimter)
+    {
+      return JavaScriptUtils.ToEscapedJavaScriptString(value, delimter, true);
+    }
+
+    /// <summary>
+    /// Converts the <see cref="Object"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="Object"/>.</returns>
+    public static string ToString(object value)
+    {
+      if (value == null)
+        return Null;
+
+      IConvertible convertible = ConvertUtils.ToConvertible(value);
+
+      if (convertible != null)
+      {
+        switch (convertible.GetTypeCode())
+        {
+          case TypeCode.String:
+            return ToString(convertible.ToString(CultureInfo.InvariantCulture));
+          case TypeCode.Char:
+            return ToString(convertible.ToChar(CultureInfo.InvariantCulture));
+          case TypeCode.Boolean:
+            return ToString(convertible.ToBoolean(CultureInfo.InvariantCulture));
+          case TypeCode.SByte:
+            return ToString(convertible.ToSByte(CultureInfo.InvariantCulture));
+          case TypeCode.Int16:
+            return ToString(convertible.ToInt16(CultureInfo.InvariantCulture));
+          case TypeCode.UInt16:
+            return ToString(convertible.ToUInt16(CultureInfo.InvariantCulture));
+          case TypeCode.Int32:
+            return ToString(convertible.ToInt32(CultureInfo.InvariantCulture));
+          case TypeCode.Byte:
+            return ToString(convertible.ToByte(CultureInfo.InvariantCulture));
+          case TypeCode.UInt32:
+            return ToString(convertible.ToUInt32(CultureInfo.InvariantCulture));
+          case TypeCode.Int64:
+            return ToString(convertible.ToInt64(CultureInfo.InvariantCulture));
+          case TypeCode.UInt64:
+            return ToString(convertible.ToUInt64(CultureInfo.InvariantCulture));
+          case TypeCode.Single:
+            return ToString(convertible.ToSingle(CultureInfo.InvariantCulture));
+          case TypeCode.Double:
+            return ToString(convertible.ToDouble(CultureInfo.InvariantCulture));
+          case TypeCode.DateTime:
+            return ToString(convertible.ToDateTime(CultureInfo.InvariantCulture));
+          case TypeCode.Decimal:
+            return ToString(convertible.ToDecimal(CultureInfo.InvariantCulture));
+#if !(NETFX_CORE || PORTABLE)
+          case TypeCode.DBNull:
+            return Null;
+#endif
+        }
+      }
+#if !PocketPC && !NET20
+      else if (value is DateTimeOffset)
+      {
+        return ToString((DateTimeOffset) value);
+      }
+#endif
+      else if (value is Guid)
+      {
+        return ToString((Guid) value);
+      }
+      else if (value is Uri)
+      {
+        return ToString((Uri) value);
+      }
+      else if (value is TimeSpan)
+      {
+        return ToString((TimeSpan) value);
+      }
+
+      throw new ArgumentException("Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType()));
+    }
+
+    private static bool IsJsonPrimitiveTypeCode(TypeCode typeCode)
+    {
+      switch (typeCode)
+      {
+        case TypeCode.String:
+        case TypeCode.Char:
+        case TypeCode.Boolean:
+        case TypeCode.SByte:
+        case TypeCode.Int16:
+        case TypeCode.UInt16:
+        case TypeCode.Int32:
+        case TypeCode.Byte:
+        case TypeCode.UInt32:
+        case TypeCode.Int64:
+        case TypeCode.UInt64:
+        case TypeCode.Single:
+        case TypeCode.Double:
+        case TypeCode.DateTime:
+        case TypeCode.Decimal:
+#if !(NETFX_CORE || PORTABLE)
+        case TypeCode.DBNull:
+#endif
+          return true;
+        default:
+          return false;
+      }
+    }
+
+    internal static bool IsJsonPrimitiveType(Type type)
+    {
+      if (ReflectionUtils.IsNullableType(type))
+        type = Nullable.GetUnderlyingType(type);
+
+#if !PocketPC && !NET20
+      if (type == typeof (DateTimeOffset))
+        return true;
+#endif
+      if (type == typeof (byte[]))
+        return true;
+      if (type == typeof (Uri))
+        return true;
+      if (type == typeof (TimeSpan))
+        return true;
+      if (type == typeof (Guid))
+        return true;
+
+      return IsJsonPrimitiveTypeCode(ConvertUtils.GetTypeCode(type));
+    }
+
+    #region Serialize
+    /// <summary>
+    /// Serializes the specified object to a JSON string.
+    /// </summary>
+    /// <param name="value">The object to serialize.</param>
+    /// <returns>A JSON string representation of the object.</returns>
+    public static string SerializeObject(object value)
+    {
+      return SerializeObject(value, Formatting.None, (JsonSerializerSettings) null);
+    }
+
+    /// <summary>
+    /// Serializes the specified object to a JSON string.
+    /// </summary>
+    /// <param name="value">The object to serialize.</param>
+    /// <param name="formatting">Indicates how the output is formatted.</param>
+    /// <returns>
+    /// A JSON string representation of the object.
+    /// </returns>
+    public static string SerializeObject(object value, Formatting formatting)
+    {
+      return SerializeObject(value, formatting, (JsonSerializerSettings) null);
+    }
+
+    /// <summary>
+    /// Serializes the specified object to a JSON string using a collection of <see cref="JsonConverter"/>.
+    /// </summary>
+    /// <param name="value">The object to serialize.</param>
+    /// <param name="converters">A collection converters used while serializing.</param>
+    /// <returns>A JSON string representation of the object.</returns>
+    public static string SerializeObject(object value, params JsonConverter[] converters)
+    {
+      return SerializeObject(value, Formatting.None, converters);
+    }
+
+    /// <summary>
+    /// Serializes the specified object to a JSON string using a collection of <see cref="JsonConverter"/>.
+    /// </summary>
+    /// <param name="value">The object to serialize.</param>
+    /// <param name="formatting">Indicates how the output is formatted.</param>
+    /// <param name="converters">A collection converters used while serializing.</param>
+    /// <returns>A JSON string representation of the object.</returns>
+    public static string SerializeObject(object value, Formatting formatting, params JsonConverter[] converters)
+    {
+      JsonSerializerSettings settings = (converters != null && converters.Length > 0)
+                                          ? new JsonSerializerSettings {Converters = converters}
+                                          : null;
+
+      return SerializeObject(value, formatting, settings);
+    }
+
+    /// <summary>
+    /// Serializes the specified object to a JSON string using a collection of <see cref="JsonConverter"/>.
+    /// </summary>
+    /// <param name="value">The object to serialize.</param>
+    /// <param name="settings">The <see cref="JsonSerializerSettings"/> used to serialize the object.
+    /// If this is null, default serialization settings will be is used.</param>
+    /// <returns>
+    /// A JSON string representation of the object.
+    /// </returns>
+    public static string SerializeObject(object value, JsonSerializerSettings settings)
+    {
+      return SerializeObject(value, Formatting.None, settings);
+    }
+
+    /// <summary>
+    /// Serializes the specified object to a JSON string using a collection of <see cref="JsonConverter"/>.
+    /// </summary>
+    /// <param name="value">The object to serialize.</param>
+    /// <param name="formatting">Indicates how the output is formatted.</param>
+    /// <param name="settings">The <see cref="JsonSerializerSettings"/> used to serialize the object.
+    /// If this is null, default serialization settings will be is used.</param>
+    /// <returns>
+    /// A JSON string representation of the object.
+    /// </returns>
+    public static string SerializeObject(object value, Formatting formatting, JsonSerializerSettings settings)
+    {
+      JsonSerializer jsonSerializer = JsonSerializer.Create(settings);
+
+      StringBuilder sb = new StringBuilder(256);
+      StringWriter sw = new StringWriter(sb, CultureInfo.InvariantCulture);
+      using (JsonTextWriter jsonWriter = new JsonTextWriter(sw))
+      {
+        jsonWriter.Formatting = formatting;
+
+        jsonSerializer.Serialize(jsonWriter, value);
+      }
+
+      return sw.ToString();
+    }
+
+#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE)
+    /// <summary>
+    /// Asynchronously serializes the specified object to a JSON string using a collection of <see cref="JsonConverter"/>.
+    /// </summary>
+    /// <param name="value">The object to serialize.</param>
+    /// <returns>
+    /// A task that represents the asynchronous serialize operation. The value of the <c>TResult</c> parameter contains a JSON string representation of the object.
+    /// </returns>
+    public static Task<string> SerializeObjectAsync(object value)
+    {
+      return SerializeObjectAsync(value, Formatting.None, null);
+    }
+
+    /// <summary>
+    /// Asynchronously serializes the specified object to a JSON string using a collection of <see cref="JsonConverter"/>.
+    /// </summary>
+    /// <param name="value">The object to serialize.</param>
+    /// <param name="formatting">Indicates how the output is formatted.</param>
+    /// <returns>
+    /// A task that represents the asynchronous serialize operation. The value of the <c>TResult</c> parameter contains a JSON string representation of the object.
+    /// </returns>
+    public static Task<string> SerializeObjectAsync(object value, Formatting formatting)
+    {
+      return SerializeObjectAsync(value, formatting, null);
+    }
+
+    /// <summary>
+    /// Asynchronously serializes the specified object to a JSON string using a collection of <see cref="JsonConverter"/>.
+    /// </summary>
+    /// <param name="value">The object to serialize.</param>
+    /// <param name="formatting">Indicates how the output is formatted.</param>
+    /// <param name="settings">The <see cref="JsonSerializerSettings"/> used to serialize the object.
+    /// If this is null, default serialization settings will be is used.</param>
+    /// <returns>
+    /// A task that represents the asynchronous serialize operation. The value of the <c>TResult</c> parameter contains a JSON string representation of the object.
+    /// </returns>
+    public static Task<string> SerializeObjectAsync(object value, Formatting formatting, JsonSerializerSettings settings)
+    {
+      return Task.Factory.StartNew(() => SerializeObject(value, formatting, settings));
+    }
+#endif
+    #endregion
+
+    #region Deserialize
+    /// <summary>
+    /// Deserializes the JSON to a .NET object.
+    /// </summary>
+    /// <param name="value">The JSON to deserialize.</param>
+    /// <returns>The deserialized object from the Json string.</returns>
+    public static object DeserializeObject(string value)
+    {
+      return DeserializeObject(value, null, (JsonSerializerSettings) null);
+    }
+
+    /// <summary>
+    /// Deserializes the JSON to a .NET object.
+    /// </summary>
+    /// <param name="value">The JSON to deserialize.</param>
+    /// <param name="settings">
+    /// The <see cref="JsonSerializerSettings"/> used to deserialize the object.
+    /// If this is null, default serialization settings will be is used.
+    /// </param>
+    /// <returns>The deserialized object from the JSON string.</returns>
+    public static object DeserializeObject(string value, JsonSerializerSettings settings)
+    {
+      return DeserializeObject(value, null, settings);
+    }
+
+    /// <summary>
+    /// Deserializes the JSON to the specified .NET type.
+    /// </summary>
+    /// <param name="value">The JSON to deserialize.</param>
+    /// <param name="type">The <see cref="Type"/> of object being deserialized.</param>
+    /// <returns>The deserialized object from the Json string.</returns>
+    public static object DeserializeObject(string value, Type type)
+    {
+      return DeserializeObject(value, type, (JsonSerializerSettings) null);
+    }
+
+    /// <summary>
+    /// Deserializes the JSON to the specified .NET type.
+    /// </summary>
+    /// <typeparam name="T">The type of the object to deserialize to.</typeparam>
+    /// <param name="value">The JSON to deserialize.</param>
+    /// <returns>The deserialized object from the Json string.</returns>
+    public static T DeserializeObject<T>(string value)
+    {
+      return DeserializeObject<T>(value, (JsonSerializerSettings) null);
+    }
+
+    /// <summary>
+    /// Deserializes the JSON to the given anonymous type.
+    /// </summary>
+    /// <typeparam name="T">
+    /// The anonymous type to deserialize to. This can't be specified
+    /// traditionally and must be infered from the anonymous type passed
+    /// as a parameter.
+    /// </typeparam>
+    /// <param name="value">The JSON to deserialize.</param>
+    /// <param name="anonymousTypeObject">The anonymous type object.</param>
+    /// <returns>The deserialized anonymous type from the JSON string.</returns>
+    public static T DeserializeAnonymousType<T>(string value, T anonymousTypeObject)
+    {
+      return DeserializeObject<T>(value);
+    }
+
+    /// <summary>
+    /// Deserializes the JSON to the specified .NET type.
+    /// </summary>
+    /// <typeparam name="T">The type of the object to deserialize to.</typeparam>
+    /// <param name="value">The JSON to deserialize.</param>
+    /// <param name="converters">Converters to use while deserializing.</param>
+    /// <returns>The deserialized object from the JSON string.</returns>
+    public static T DeserializeObject<T>(string value, params JsonConverter[] converters)
+    {
+      return (T) DeserializeObject(value, typeof (T), converters);
+    }
+
+    /// <summary>
+    /// Deserializes the JSON to the specified .NET type.
+    /// </summary>
+    /// <typeparam name="T">The type of the object to deserialize to.</typeparam>
+    /// <param name="value">The object to deserialize.</param>
+    /// <param name="settings">
+    /// The <see cref="JsonSerializerSettings"/> used to deserialize the object.
+    /// If this is null, default serialization settings will be is used.
+    /// </param>
+    /// <returns>The deserialized object from the JSON string.</returns>
+    public static T DeserializeObject<T>(string value, JsonSerializerSettings settings)
+    {
+      return (T) DeserializeObject(value, typeof (T), settings);
+    }
+
+    /// <summary>
+    /// Deserializes the JSON to the specified .NET type.
+    /// </summary>
+    /// <param name="value">The JSON to deserialize.</param>
+    /// <param name="type">The type of the object to deserialize.</param>
+    /// <param name="converters">Converters to use while deserializing.</param>
+    /// <returns>The deserialized object from the JSON string.</returns>
+    public static object DeserializeObject(string value, Type type, params JsonConverter[] converters)
+    {
+      JsonSerializerSettings settings = (converters != null && converters.Length > 0)
+                                          ? new JsonSerializerSettings {Converters = converters}
+                                          : null;
+
+      return DeserializeObject(value, type, settings);
+    }
+
+    /// <summary>
+    /// Deserializes the JSON to the specified .NET type.
+    /// </summary>
+    /// <param name="value">The JSON to deserialize.</param>
+    /// <param name="type">The type of the object to deserialize to.</param>
+    /// <param name="settings">
+    /// The <see cref="JsonSerializerSettings"/> used to deserialize the object.
+    /// If this is null, default serialization settings will be is used.
+    /// </param>
+    /// <returns>The deserialized object from the JSON string.</returns>
+    public static object DeserializeObject(string value, Type type, JsonSerializerSettings settings)
+    {
+      ValidationUtils.ArgumentNotNull(value, "value");
+
+      StringReader sr = new StringReader(value);
+      JsonSerializer jsonSerializer = JsonSerializer.Create(settings);
+
+      // by default DeserializeObject should check for additional content
+      if (!jsonSerializer.IsCheckAdditionalContentSet())
+        jsonSerializer.CheckAdditionalContent = true;
+
+      return jsonSerializer.Deserialize(new JsonTextReader(sr), type);
+    }
+
+#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE)
+    /// <summary>
+    /// Asynchronously deserializes the JSON to the specified .NET type.
+    /// </summary>
+    /// <typeparam name="T">The type of the object to deserialize to.</typeparam>
+    /// <param name="value">The JSON to deserialize.</param>
+    /// <returns>
+    /// A task that represents the asynchronous deserialize operation. The value of the <c>TResult</c> parameter contains the deserialized object from the JSON string.
+    /// </returns>
+    public static Task<T> DeserializeObjectAsync<T>(string value)
+    {
+      return DeserializeObjectAsync<T>(value, null);
+    }
+
+    /// <summary>
+    /// Asynchronously deserializes the JSON to the specified .NET type.
+    /// </summary>
+    /// <typeparam name="T">The type of the object to deserialize to.</typeparam>
+    /// <param name="value">The JSON to deserialize.</param>
+    /// <param name="settings">
+    /// The <see cref="JsonSerializerSettings"/> used to deserialize the object.
+    /// If this is null, default serialization settings will be is used.
+    /// </param>
+    /// <returns>
+    /// A task that represents the asynchronous deserialize operation. The value of the <c>TResult</c> parameter contains the deserialized object from the JSON string.
+    /// </returns>
+    public static Task<T> DeserializeObjectAsync<T>(string value, JsonSerializerSettings settings)
+    {
+      return Task.Factory.StartNew(() => DeserializeObject<T>(value, settings));
+    }
+
+    /// <summary>
+    /// Asynchronously deserializes the JSON to the specified .NET type.
+    /// </summary>
+    /// <param name="value">The JSON to deserialize.</param>
+    /// <returns>
+    /// A task that represents the asynchronous deserialize operation. The value of the <c>TResult</c> parameter contains the deserialized object from the JSON string.
+    /// </returns>
+    public static Task<object> DeserializeObjectAsync(string value)
+    {
+      return DeserializeObjectAsync(value, null, null);
+    }
+
+    /// <summary>
+    /// Asynchronously deserializes the JSON to the specified .NET type.
+    /// </summary>
+    /// <param name="value">The JSON to deserialize.</param>
+    /// <param name="type">The type of the object to deserialize to.</param>
+    /// <param name="settings">
+    /// The <see cref="JsonSerializerSettings"/> used to deserialize the object.
+    /// If this is null, default serialization settings will be is used.
+    /// </param>
+    /// <returns>
+    /// A task that represents the asynchronous deserialize operation. The value of the <c>TResult</c> parameter contains the deserialized object from the JSON string.
+    /// </returns>
+    public static Task<object> DeserializeObjectAsync(string value, Type type, JsonSerializerSettings settings)
+    {
+      return Task.Factory.StartNew(() => DeserializeObject(value, type, settings));
+    }
+#endif
+    #endregion
+
+    /// <summary>
+    /// Populates the object with values from the JSON string.
+    /// </summary>
+    /// <param name="value">The JSON to populate values from.</param>
+    /// <param name="target">The target object to populate values onto.</param>
+    public static void PopulateObject(string value, object target)
+    {
+      PopulateObject(value, target, null);
+    }
+
+    /// <summary>
+    /// Populates the object with values from the JSON string.
+    /// </summary>
+    /// <param name="value">The JSON to populate values from.</param>
+    /// <param name="target">The target object to populate values onto.</param>
+    /// <param name="settings">
+    /// The <see cref="JsonSerializerSettings"/> used to deserialize the object.
+    /// If this is null, default serialization settings will be is used.
+    /// </param>
+    public static void PopulateObject(string value, object target, JsonSerializerSettings settings)
+    {
+      StringReader sr = new StringReader(value);
+      JsonSerializer jsonSerializer = JsonSerializer.Create(settings);
+
+      using (JsonReader jsonReader = new JsonTextReader(sr))
+      {
+        jsonSerializer.Populate(jsonReader, target);
+
+        if (jsonReader.Read() && jsonReader.TokenType != JsonToken.Comment)
+          throw new JsonSerializationException("Additional text found in JSON string after finishing deserializing object.");
+      }
+    }
+
+#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE)
+    /// <summary>
+    /// Asynchronously populates the object with values from the JSON string.
+    /// </summary>
+    /// <param name="value">The JSON to populate values from.</param>
+    /// <param name="target">The target object to populate values onto.</param>
+    /// <param name="settings">
+    /// The <see cref="JsonSerializerSettings"/> used to deserialize the object.
+    /// If this is null, default serialization settings will be is used.
+    /// </param>
+    /// <returns>
+    /// A task that represents the asynchronous populate operation.
+    /// </returns>
+    public static Task PopulateObjectAsync(string value, object target, JsonSerializerSettings settings)
+    {
+      return Task.Factory.StartNew(() => PopulateObject(value, target, settings));
+    }
+#endif
+
+#if !(SILVERLIGHT || PORTABLE || NETFX_CORE)
+    /// <summary>
+    /// Serializes the XML node to a JSON string.
+    /// </summary>
+    /// <param name="node">The node to serialize.</param>
+    /// <returns>A JSON string of the XmlNode.</returns>
+    public static string SerializeXmlNode(XmlNode node)
+    {
+      return SerializeXmlNode(node, Formatting.None);
+    }
+
+    /// <summary>
+    /// Serializes the XML node to a JSON string.
+    /// </summary>
+    /// <param name="node">The node to serialize.</param>
+    /// <param name="formatting">Indicates how the output is formatted.</param>
+    /// <returns>A JSON string of the XmlNode.</returns>
+    public static string SerializeXmlNode(XmlNode node, Formatting formatting)
+    {
+      XmlNodeConverter converter = new XmlNodeConverter();
+
+      return SerializeObject(node, formatting, converter);
+    }
+
+    /// <summary>
+    /// Serializes the XML node to a JSON string.
+    /// </summary>
+    /// <param name="node">The node to serialize.</param>
+    /// <param name="formatting">Indicates how the output is formatted.</param>
+    /// <param name="omitRootObject">Omits writing the root object.</param>
+    /// <returns>A JSON string of the XmlNode.</returns>
+    public static string SerializeXmlNode(XmlNode node, Formatting formatting, bool omitRootObject)
+    {
+      XmlNodeConverter converter = new XmlNodeConverter {OmitRootObject = omitRootObject};
+
+      return SerializeObject(node, formatting, converter);
+    }
+
+    /// <summary>
+    /// Deserializes the XmlNode from a JSON string.
+    /// </summary>
+    /// <param name="value">The JSON string.</param>
+    /// <returns>The deserialized XmlNode</returns>
+    public static XmlDocument DeserializeXmlNode(string value)
+    {
+      return DeserializeXmlNode(value, null);
+    }
+
+    /// <summary>
+    /// Deserializes the XmlNode from a JSON string nested in a root elment.
+    /// </summary>
+    /// <param name="value">The JSON string.</param>
+    /// <param name="deserializeRootElementName">The name of the root element to append when deserializing.</param>
+    /// <returns>The deserialized XmlNode</returns>
+    public static XmlDocument DeserializeXmlNode(string value, string deserializeRootElementName)
+    {
+      return DeserializeXmlNode(value, deserializeRootElementName, false);
+    }
+
+    /// <summary>
+    /// Deserializes the XmlNode from a JSON string nested in a root elment.
+    /// </summary>
+    /// <param name="value">The JSON string.</param>
+    /// <param name="deserializeRootElementName">The name of the root element to append when deserializing.</param>
+    /// <param name="writeArrayAttribute">
+    /// A flag to indicate whether to write the Json.NET array attribute.
+    /// This attribute helps preserve arrays when converting the written XML back to JSON.
+    /// </param>
+    /// <returns>The deserialized XmlNode</returns>
+    public static XmlDocument DeserializeXmlNode(string value, string deserializeRootElementName, bool writeArrayAttribute)
+    {
+      XmlNodeConverter converter = new XmlNodeConverter();
+      converter.DeserializeRootElementName = deserializeRootElementName;
+      converter.WriteArrayAttribute = writeArrayAttribute;
+
+      return (XmlDocument) DeserializeObject(value, typeof (XmlDocument), converter);
+    }
+#endif
+
+#if !NET20 && (!(SILVERLIGHT || PORTABLE) || WINDOWS_PHONE)
+    /// <summary>
+    /// Serializes the <see cref="XNode"/> to a JSON string.
+    /// </summary>
+    /// <param name="node">The node to convert to JSON.</param>
+    /// <returns>A JSON string of the XNode.</returns>
+    public static string SerializeXNode(XObject node)
+    {
+      return SerializeXNode(node, Formatting.None);
+    }
+
+    /// <summary>
+    /// Serializes the <see cref="XNode"/> to a JSON string.
+    /// </summary>
+    /// <param name="node">The node to convert to JSON.</param>
+    /// <param name="formatting">Indicates how the output is formatted.</param>
+    /// <returns>A JSON string of the XNode.</returns>
+    public static string SerializeXNode(XObject node, Formatting formatting)
+    {
+      return SerializeXNode(node, formatting, false);
+    }
+
+    /// <summary>
+    /// Serializes the <see cref="XNode"/> to a JSON string.
+    /// </summary>
+    /// <param name="node">The node to serialize.</param>
+    /// <param name="formatting">Indicates how the output is formatted.</param>
+    /// <param name="omitRootObject">Omits writing the root object.</param>
+    /// <returns>A JSON string of the XNode.</returns>
+    public static string SerializeXNode(XObject node, Formatting formatting, bool omitRootObject)
+    {
+      XmlNodeConverter converter = new XmlNodeConverter {OmitRootObject = omitRootObject};
+
+      return SerializeObject(node, formatting, converter);
+    }
+
+    /// <summary>
+    /// Deserializes the <see cref="XNode"/> from a JSON string.
+    /// </summary>
+    /// <param name="value">The JSON string.</param>
+    /// <returns>The deserialized XNode</returns>
+    public static XDocument DeserializeXNode(string value)
+    {
+      return DeserializeXNode(value, null);
+    }
+
+    /// <summary>
+    /// Deserializes the <see cref="XNode"/> from a JSON string nested in a root elment.
+    /// </summary>
+    /// <param name="value">The JSON string.</param>
+    /// <param name="deserializeRootElementName">The name of the root element to append when deserializing.</param>
+    /// <returns>The deserialized XNode</returns>
+    public static XDocument DeserializeXNode(string value, string deserializeRootElementName)
+    {
+      return DeserializeXNode(value, deserializeRootElementName, false);
+    }
+
+    /// <summary>
+    /// Deserializes the <see cref="XNode"/> from a JSON string nested in a root elment.
+    /// </summary>
+    /// <param name="value">The JSON string.</param>
+    /// <param name="deserializeRootElementName">The name of the root element to append when deserializing.</param>
+    /// <param name="writeArrayAttribute">
+    /// A flag to indicate whether to write the Json.NET array attribute.
+    /// This attribute helps preserve arrays when converting the written XML back to JSON.
+    /// </param>
+    /// <returns>The deserialized XNode</returns>
+    public static XDocument DeserializeXNode(string value, string deserializeRootElementName, bool writeArrayAttribute)
+    {
+      XmlNodeConverter converter = new XmlNodeConverter();
+      converter.DeserializeRootElementName = deserializeRootElementName;
+      converter.WriteArrayAttribute = writeArrayAttribute;
+
+      return (XDocument) DeserializeObject(value, typeof (XDocument), converter);
+    }
+#endif
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConverter.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConverter.cs
index 1597a44..dd619f2 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConverter.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConverter.cs
@@ -1,93 +1,93 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using Newtonsoft.Json.Utilities;
-using Newtonsoft.Json.Schema;
-
-namespace Newtonsoft.Json
-{
-  /// <summary>
-  /// Converts an object to and from JSON.
-  /// </summary>
-  public abstract class JsonConverter
-  {
-    /// <summary>
-    /// Writes the JSON representation of the object.
-    /// </summary>
-    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
-    /// <param name="value">The value.</param>
-    /// <param name="serializer">The calling serializer.</param>
-    public abstract void WriteJson(JsonWriter writer, object value, JsonSerializer serializer);
-
-    /// <summary>
-    /// Reads the JSON representation of the object.
-    /// </summary>
-    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
-    /// <param name="objectType">Type of the object.</param>
-    /// <param name="existingValue">The existing value of object being read.</param>
-    /// <param name="serializer">The calling serializer.</param>
-    /// <returns>The object value.</returns>
-    public abstract object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer);
-
-    /// <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 abstract bool CanConvert(Type objectType);
-
-    /// <summary>
-    /// Gets the <see cref="JsonSchema"/> of the JSON produced by the JsonConverter.
-    /// </summary>
-    /// <returns>The <see cref="JsonSchema"/> of the JSON produced by the JsonConverter.</returns>
-    public virtual JsonSchema GetSchema()
-    {
-      return null;
-    }
-
-    /// <summary>
-    /// Gets a value indicating whether this <see cref="JsonConverter"/> can read JSON.
-    /// </summary>
-    /// <value><c>true</c> if this <see cref="JsonConverter"/> can read JSON; otherwise, <c>false</c>.</value>
-    public virtual bool CanRead
-    {
-       get { return true; }
-    }
-
-    /// <summary>
-    /// Gets a value indicating whether this <see cref="JsonConverter"/> can write JSON.
-    /// </summary>
-    /// <value><c>true</c> if this <see cref="JsonConverter"/> can write JSON; otherwise, <c>false</c>.</value>
-    public virtual bool CanWrite
-    {
-      get { return true; }
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Newtonsoft.Json.Utilities;
+using Newtonsoft.Json.Schema;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Converts an object to and from JSON.
+  /// </summary>
+  public abstract class JsonConverter
+  {
+    /// <summary>
+    /// Writes the JSON representation of the object.
+    /// </summary>
+    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
+    /// <param name="value">The value.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    public abstract void WriteJson(JsonWriter writer, object value, JsonSerializer serializer);
+
+    /// <summary>
+    /// Reads the JSON representation of the object.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
+    /// <param name="objectType">Type of the object.</param>
+    /// <param name="existingValue">The existing value of object being read.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    /// <returns>The object value.</returns>
+    public abstract object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer);
+
+    /// <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 abstract bool CanConvert(Type objectType);
+
+    /// <summary>
+    /// Gets the <see cref="JsonSchema"/> of the JSON produced by the JsonConverter.
+    /// </summary>
+    /// <returns>The <see cref="JsonSchema"/> of the JSON produced by the JsonConverter.</returns>
+    public virtual JsonSchema GetSchema()
+    {
+      return null;
+    }
+
+    /// <summary>
+    /// Gets a value indicating whether this <see cref="JsonConverter"/> can read JSON.
+    /// </summary>
+    /// <value><c>true</c> if this <see cref="JsonConverter"/> can read JSON; otherwise, <c>false</c>.</value>
+    public virtual bool CanRead
+    {
+       get { return true; }
+    }
+
+    /// <summary>
+    /// Gets a value indicating whether this <see cref="JsonConverter"/> can write JSON.
+    /// </summary>
+    /// <value><c>true</c> if this <see cref="JsonConverter"/> can write JSON; otherwise, <c>false</c>.</value>
+    public virtual bool CanWrite
+    {
+      get { return true; }
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConverterAttribute.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConverterAttribute.cs
index e28fd79..3fd46bd 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConverterAttribute.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConverterAttribute.cs
@@ -1,51 +1,73 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Newtonsoft.Json.Utilities;
-using System.Globalization;
-
-namespace Newtonsoft.Json
-{
-  /// <summary>
-  /// Instructs the <see cref="JsonSerializer"/> to use the specified <see cref="JsonConverter"/> when serializing the member or class.
-  /// </summary>
-  [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface | AttributeTargets.Enum, AllowMultiple = false)]
-  public sealed class JsonConverterAttribute : Attribute
-  {
-    private readonly Type _converterType;
-
-    /// <summary>
-    /// Gets the type of the converter.
-    /// </summary>
-    /// <value>The type of the converter.</value>
-    public Type ConverterType
-    {
-      get { return _converterType; }
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonConverterAttribute"/> class.
-    /// </summary>
-    /// <param name="converterType">Type of the converter.</param>
-    public JsonConverterAttribute(Type converterType)
-    {
-      if (converterType == null)
-        throw new ArgumentNullException("converterType");
-
-      _converterType = converterType;
-    }
-
-    internal static JsonConverter CreateJsonConverterInstance(Type converterType)
-    {
-      try
-      {
-        return (JsonConverter)Activator.CreateInstance(converterType);
-      }
-      catch (Exception ex)
-      {
-        throw new Exception("Error creating {0}".FormatWith(CultureInfo.InvariantCulture, converterType), ex);
-      }
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using Newtonsoft.Json.Utilities;
+using System.Globalization;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Instructs the <see cref="JsonSerializer"/> to use the specified <see cref="JsonConverter"/> when serializing the member or class.
+  /// </summary>
+  [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface | AttributeTargets.Enum | AttributeTargets.Parameter, AllowMultiple = false)]
+  public sealed class JsonConverterAttribute : Attribute
+  {
+    private readonly Type _converterType;
+
+    /// <summary>
+    /// Gets the type of the converter.
+    /// </summary>
+    /// <value>The type of the converter.</value>
+    public Type ConverterType
+    {
+      get { return _converterType; }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonConverterAttribute"/> class.
+    /// </summary>
+    /// <param name="converterType">Type of the converter.</param>
+    public JsonConverterAttribute(Type converterType)
+    {
+      if (converterType == null)
+        throw new ArgumentNullException("converterType");
+
+      _converterType = converterType;
+    }
+
+    internal static JsonConverter CreateJsonConverterInstance(Type converterType)
+    {
+      try
+      {
+        return (JsonConverter)Activator.CreateInstance(converterType);
+      }
+      catch (Exception ex)
+      {
+        throw new JsonException("Error creating {0}".FormatWith(CultureInfo.InvariantCulture, converterType), ex);
+      }
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConverterCollection.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConverterCollection.cs
index a2a2bea..50f70c5 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConverterCollection.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConverterCollection.cs
@@ -1,39 +1,39 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Collections.ObjectModel;
-
-namespace Newtonsoft.Json
-{
-  /// <summary>
-  /// Represents a collection of <see cref="JsonConverter"/>.
-  /// </summary>
-  public class JsonConverterCollection : Collection<JsonConverter>
-  {
-  }
-}
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Collections.ObjectModel;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Represents a collection of <see cref="JsonConverter"/>.
+  /// </summary>
+  public class JsonConverterCollection : Collection<JsonConverter>
+  {
+  }
+}
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonDictionaryAttribute.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonDictionaryAttribute.cs
new file mode 100644
index 0000000..6ef4011
--- /dev/null
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonDictionaryAttribute.cs
@@ -0,0 +1,52 @@
+#region License
+// 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.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Instructs the <see cref="JsonSerializer"/> how to serialize the collection.
+  /// </summary>
+  [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
+  public sealed class JsonDictionaryAttribute : JsonContainerAttribute
+  {
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonDictionaryAttribute"/> class.
+    /// </summary>
+    public JsonDictionaryAttribute()
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonDictionaryAttribute"/> class with the specified container Id.
+    /// </summary>
+    /// <param name="id">The container Id.</param>
+    public JsonDictionaryAttribute(string id)
+      : base(id)
+    {
+    }
+  }
+}
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonException.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonException.cs
new file mode 100644
index 0000000..2f0691e
--- /dev/null
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonException.cs
@@ -0,0 +1,108 @@
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Runtime.Serialization;
+using System.Text;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// The exception thrown when an error occurs during Json serialization or deserialization.
+  /// </summary>
+#if !(SILVERLIGHT || WINDOWS_PHONE || NETFX_CORE || PORTABLE)
+  [Serializable]
+#endif
+  public class JsonException : Exception
+  {
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonException"/> class.
+    /// </summary>
+    public JsonException()
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonException"/> class
+    /// with a specified error message.
+    /// </summary>
+    /// <param name="message">The error message that explains the reason for the exception.</param>
+    public JsonException(string message)
+      : base(message)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonException"/> class
+    /// with a specified error message and a reference to the inner exception that is the cause of this exception.
+    /// </summary>
+    /// <param name="message">The error message that explains the reason for the exception.</param>
+    /// <param name="innerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
+    public JsonException(string message, Exception innerException)
+      : base(message, innerException)
+    {
+    }
+
+#if !(WINDOWS_PHONE || SILVERLIGHT || NETFX_CORE || PORTABLE)
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonException"/> class.
+    /// </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 null. </exception>
+    /// <exception cref="T:System.Runtime.Serialization.SerializationException">The class name is null or <see cref="P:System.Exception.HResult"/> is zero (0). </exception>
+    public JsonException(SerializationInfo info, StreamingContext context)
+      : base(info, context)
+    {
+    }
+#endif
+
+    internal static string FormatExceptionMessage(IJsonLineInfo lineInfo, string path, string message)
+    {
+      // don't add a fullstop and space when message ends with a new line
+      if (!message.EndsWith(Environment.NewLine))
+      {
+        message = message.Trim();
+
+        if (!message.EndsWith("."))
+          message += ".";
+
+        message += " ";
+      }
+
+      message += "Path '{0}'".FormatWith(CultureInfo.InvariantCulture, path);
+
+      if (lineInfo != null && lineInfo.HasLineInfo())
+        message += ", line {0}, position {1}".FormatWith(CultureInfo.InvariantCulture, lineInfo.LineNumber, lineInfo.LinePosition);
+
+      message += ".";
+
+      return message;
+    }
+  }
+}
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonIgnoreAttribute.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonIgnoreAttribute.cs
index f736c8c..e7511a0 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonIgnoreAttribute.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonIgnoreAttribute.cs
@@ -1,39 +1,39 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace Newtonsoft.Json
-{
-  /// <summary>
-  /// Instructs the <see cref="JsonSerializer"/> not to serialize the public field or public read/write property value.
-  /// </summary>
-  [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
-  public sealed class JsonIgnoreAttribute : Attribute
-  {
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Instructs the <see cref="JsonSerializer"/> not to serialize the public field or public read/write property value.
+  /// </summary>
+  [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
+  public sealed class JsonIgnoreAttribute : Attribute
+  {
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonObjectAttribute.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonObjectAttribute.cs
index 6035009..862db6b 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonObjectAttribute.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonObjectAttribute.cs
@@ -1,73 +1,89 @@
-#region License
-// 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.
-#endregion
-
-using System;
-
-namespace Newtonsoft.Json
-{
-  /// <summary>
-  /// Instructs the <see cref="JsonSerializer"/> how to serialize the object.
-  /// </summary>
-  [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false)]
-  public sealed class JsonObjectAttribute : JsonContainerAttribute
-  {
-    private MemberSerialization _memberSerialization = MemberSerialization.OptOut;
-
-    /// <summary>
-    /// Gets or sets the member serialization.
-    /// </summary>
-    /// <value>The member serialization.</value>
-    public MemberSerialization MemberSerialization
-    {
-      get { return _memberSerialization; }
-      set { _memberSerialization = value; }
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonObjectAttribute"/> class.
-    /// </summary>
-    public JsonObjectAttribute()
-    {
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonObjectAttribute"/> class with the specified member serialization.
-    /// </summary>
-    /// <param name="memberSerialization">The member serialization.</param>
-    public JsonObjectAttribute(MemberSerialization memberSerialization)
-    {
-      MemberSerialization = memberSerialization;
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonObjectAttribute"/> class with the specified container Id.
-    /// </summary>
-    /// <param name="id">The container Id.</param>
-    public JsonObjectAttribute(string id)
-      : base(id)
-    {
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Instructs the <see cref="JsonSerializer"/> how to serialize the object.
+  /// </summary>
+  [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false)]
+  public sealed class JsonObjectAttribute : JsonContainerAttribute
+  {
+    private MemberSerialization _memberSerialization = MemberSerialization.OptOut;
+
+    // yuck. can't set nullable properties on an attribute in C#
+    // have to use this approach to get an unset default state
+    internal Required? _itemRequired;
+
+    /// <summary>
+    /// Gets or sets the member serialization.
+    /// </summary>
+    /// <value>The member serialization.</value>
+    public MemberSerialization MemberSerialization
+    {
+      get { return _memberSerialization; }
+      set { _memberSerialization = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets a value that indicates whether the object's properties are required.
+    /// </summary>
+    /// <value>
+    /// 	A value indicating whether the object's properties are required.
+    /// </value>
+    public Required ItemRequired
+    {
+      get { return _itemRequired ?? default(Required); }
+      set { _itemRequired = value; }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonObjectAttribute"/> class.
+    /// </summary>
+    public JsonObjectAttribute()
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonObjectAttribute"/> class with the specified member serialization.
+    /// </summary>
+    /// <param name="memberSerialization">The member serialization.</param>
+    public JsonObjectAttribute(MemberSerialization memberSerialization)
+    {
+      MemberSerialization = memberSerialization;
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonObjectAttribute"/> class with the specified container Id.
+    /// </summary>
+    /// <param name="id">The container Id.</param>
+    public JsonObjectAttribute(string id)
+      : base(id)
+    {
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonPosition.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonPosition.cs
new file mode 100644
index 0000000..8f48c8e
--- /dev/null
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonPosition.cs
@@ -0,0 +1,95 @@
+#region License
+// 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.
+#endregion
+
+using System.Collections.Generic;
+using System.Text;
+
+namespace Newtonsoft.Json
+{
+  internal enum JsonContainerType
+  {
+    None,
+    Object,
+    Array,
+    Constructor
+  }
+
+  internal struct JsonPosition
+  {
+    internal JsonContainerType Type;
+    internal int? Position;
+    internal string PropertyName;
+
+    internal void WriteTo(StringBuilder sb)
+    {
+      switch (Type)
+      {
+        case JsonContainerType.Object:
+          if (PropertyName != null)
+          {
+            if (sb.Length > 0)
+              sb.Append(".");
+            sb.Append(PropertyName);
+          }
+          break;
+        case JsonContainerType.Array:
+        case JsonContainerType.Constructor:
+          if (Position != null)
+          {
+            sb.Append("[");
+            sb.Append(Position);
+            sb.Append("]");
+          }
+          break;
+      }
+    }
+
+    internal bool InsideContainer()
+    {
+      switch (Type)
+      {
+        case JsonContainerType.Object:
+          return (PropertyName != null);
+        case JsonContainerType.Array:
+        case JsonContainerType.Constructor:
+          return (Position != null);
+      }
+
+      return false;
+    }
+
+    internal static string BuildPath(IEnumerable<JsonPosition> positions)
+    {
+      StringBuilder sb = new StringBuilder();
+
+      foreach (JsonPosition state in positions)
+      {
+        state.WriteTo(sb);
+      }
+
+      return sb.ToString();
+    }
+  }
+}
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonPropertyAttribute.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonPropertyAttribute.cs
index 5df13e6..8d197c0 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonPropertyAttribute.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonPropertyAttribute.cs
@@ -1,110 +1,190 @@
-using System;
-
-namespace Newtonsoft.Json
-{
-  /// <summary>
-  /// Instructs the <see cref="JsonSerializer"/> to always serialize the member with the specified name.
-  /// </summary>
-  [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
-  public sealed class JsonPropertyAttribute : Attribute
-  {
-    // yuck. can't set nullable properties on an attribute in C#
-    // have to use this approach to get an unset default state
-    internal NullValueHandling? _nullValueHandling;
-    internal DefaultValueHandling? _defaultValueHandling;
-    internal ReferenceLoopHandling? _referenceLoopHandling;
-    internal ObjectCreationHandling? _objectCreationHandling;
-    internal TypeNameHandling? _typeNameHandling;
-    internal bool? _isReference;
-
-    /// <summary>
-    /// Gets or sets the null value handling used when serializing this property.
-    /// </summary>
-    /// <value>The null value handling.</value>
-    public NullValueHandling NullValueHandling
-    {
-      get { return _nullValueHandling ?? default(NullValueHandling); }
-      set { _nullValueHandling = value; }
-    }
-
-    /// <summary>
-    /// Gets or sets the default value handling used when serializing this property.
-    /// </summary>
-    /// <value>The default value handling.</value>
-    public DefaultValueHandling DefaultValueHandling
-    {
-      get { return _defaultValueHandling ?? default(DefaultValueHandling); }
-      set { _defaultValueHandling = value; }
-    }
-
-    /// <summary>
-    /// Gets or sets the reference loop handling used when serializing this property.
-    /// </summary>
-    /// <value>The reference loop handling.</value>
-    public ReferenceLoopHandling ReferenceLoopHandling
-    {
-      get { return _referenceLoopHandling ?? default(ReferenceLoopHandling); }
-      set { _referenceLoopHandling = value; }
-    }
-
-    /// <summary>
-    /// Gets or sets the object creation handling used when deserializing this property.
-    /// </summary>
-    /// <value>The object creation handling.</value>
-    public ObjectCreationHandling ObjectCreationHandling
-    {
-      get { return _objectCreationHandling ?? default(ObjectCreationHandling); }
-      set { _objectCreationHandling = value; }
-    }
-
-    /// <summary>
-    /// Gets or sets the type name handling used when serializing this property.
-    /// </summary>
-    /// <value>The type name handling.</value>
-    public TypeNameHandling TypeNameHandling
-    {
-      get { return _typeNameHandling ?? default(TypeNameHandling); }
-      set { _typeNameHandling = value; }
-    }
-
-    /// <summary>
-    /// Gets or sets whether this property's value is serialized as a reference.
-    /// </summary>
-    /// <value>Whether this property's value is serialized as a reference.</value>
-    public bool IsReference
-    {
-      get { return _isReference ?? default(bool); }
-      set { _isReference = value; }
-    }
-
-    /// <summary>
-    /// Gets or sets the name of the property.
-    /// </summary>
-    /// <value>The name of the property.</value>
-    public string PropertyName { get; set; }
-
-    /// <summary>
-    /// Gets or sets a value indicating whether this property is required.
-    /// </summary>
-    /// <value>
-    /// 	A value indicating whether this property is required.
-    /// </value>
-    public Required Required { get; set; }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonPropertyAttribute"/> class.
-    /// </summary>
-    public JsonPropertyAttribute()
-    {
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonPropertyAttribute"/> class with the specified name.
-    /// </summary>
-    /// <param name="propertyName">Name of the property.</param>
-    public JsonPropertyAttribute(string propertyName)
-    {
-      PropertyName = propertyName;
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Instructs the <see cref="JsonSerializer"/> to always serialize the member with the specified name.
+  /// </summary>
+  [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false)]
+  public sealed class JsonPropertyAttribute : Attribute
+  {
+    // yuck. can't set nullable properties on an attribute in C#
+    // have to use this approach to get an unset default state
+    internal NullValueHandling? _nullValueHandling;
+    internal DefaultValueHandling? _defaultValueHandling;
+    internal ReferenceLoopHandling? _referenceLoopHandling;
+    internal ObjectCreationHandling? _objectCreationHandling;
+    internal TypeNameHandling? _typeNameHandling;
+    internal bool? _isReference;
+    internal int? _order;
+    internal Required? _required;
+    internal bool? _itemIsReference;
+    internal ReferenceLoopHandling? _itemReferenceLoopHandling;
+    internal TypeNameHandling? _itemTypeNameHandling;
+
+    /// <summary>
+    /// Gets or sets the converter used when serializing the property's collection items.
+    /// </summary>
+    /// <value>The collection's items converter.</value>
+    public Type ItemConverterType { get; set; }
+
+    /// <summary>
+    /// Gets or sets the null value handling used when serializing this property.
+    /// </summary>
+    /// <value>The null value handling.</value>
+    public NullValueHandling NullValueHandling
+    {
+      get { return _nullValueHandling ?? default(NullValueHandling); }
+      set { _nullValueHandling = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets the default value handling used when serializing this property.
+    /// </summary>
+    /// <value>The default value handling.</value>
+    public DefaultValueHandling DefaultValueHandling
+    {
+      get { return _defaultValueHandling ?? default(DefaultValueHandling); }
+      set { _defaultValueHandling = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets the reference loop handling used when serializing this property.
+    /// </summary>
+    /// <value>The reference loop handling.</value>
+    public ReferenceLoopHandling ReferenceLoopHandling
+    {
+      get { return _referenceLoopHandling ?? default(ReferenceLoopHandling); }
+      set { _referenceLoopHandling = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets the object creation handling used when deserializing this property.
+    /// </summary>
+    /// <value>The object creation handling.</value>
+    public ObjectCreationHandling ObjectCreationHandling
+    {
+      get { return _objectCreationHandling ?? default(ObjectCreationHandling); }
+      set { _objectCreationHandling = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets the type name handling used when serializing this property.
+    /// </summary>
+    /// <value>The type name handling.</value>
+    public TypeNameHandling TypeNameHandling
+    {
+      get { return _typeNameHandling ?? default(TypeNameHandling); }
+      set { _typeNameHandling = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets whether this property's value is serialized as a reference.
+    /// </summary>
+    /// <value>Whether this property's value is serialized as a reference.</value>
+    public bool IsReference
+    {
+      get { return _isReference ?? default(bool); }
+      set { _isReference = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets the order of serialization and deserialization of a member.
+    /// </summary>
+    /// <value>The numeric order of serialization or deserialization.</value>
+    public int Order
+    {
+      get { return _order ?? default(int); }
+      set { _order = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets a value indicating whether this property is required.
+    /// </summary>
+    /// <value>
+    /// 	A value indicating whether this property is required.
+    /// </value>
+    public Required Required
+    {
+      get { return _required ?? Required.Default; }
+      set { _required = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets the name of the property.
+    /// </summary>
+    /// <value>The name of the property.</value>
+    public string PropertyName { get; set; }
+
+    /// <summary>
+    /// Gets or sets the the reference loop handling used when serializing the property's collection items.
+    /// </summary>
+    /// <value>The collection's items reference loop handling.</value>
+    public ReferenceLoopHandling ItemReferenceLoopHandling
+    {
+      get { return _itemReferenceLoopHandling ?? default(ReferenceLoopHandling); }
+      set { _itemReferenceLoopHandling = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets the the type name handling used when serializing the property's collection items.
+    /// </summary>
+    /// <value>The collection's items type name handling.</value>
+    public TypeNameHandling ItemTypeNameHandling
+    {
+      get { return _itemTypeNameHandling ?? default(TypeNameHandling); }
+      set { _itemTypeNameHandling = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets whether this property's collection items are serialized as a reference.
+    /// </summary>
+    /// <value>Whether this property's collection items are serialized as a reference.</value>
+    public bool ItemIsReference
+    {
+      get { return _itemIsReference ?? default(bool); }
+      set { _itemIsReference = value; }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonPropertyAttribute"/> class.
+    /// </summary>
+    public JsonPropertyAttribute()
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonPropertyAttribute"/> class with the specified name.
+    /// </summary>
+    /// <param name="propertyName">Name of the property.</param>
+    public JsonPropertyAttribute(string propertyName)
+    {
+      PropertyName = propertyName;
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonReader.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonReader.cs
index d516578..1e1fae4 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonReader.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonReader.cs
@@ -1,430 +1,884 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Globalization;
-using Newtonsoft.Json.Linq;
-using Newtonsoft.Json.Utilities;
-
-namespace Newtonsoft.Json
-{
-  /// <summary>
-  /// Represents a reader that provides fast, non-cached, forward-only access to serialized Json data.
-  /// </summary>
-  public abstract class JsonReader : IDisposable
-  {
-    /// <summary>
-    /// Specifies the state of the reader.
-    /// </summary>
-    protected enum State
-    {
-      /// <summary>
-      /// The Read method has not been called.
-      /// </summary>
-      Start,
-      /// <summary>
-      /// The end of the file has been reached successfully.
-      /// </summary>
-      Complete,
-      /// <summary>
-      /// Reader is at a property.
-      /// </summary>
-      Property,
-      /// <summary>
-      /// Reader is at the start of an object.
-      /// </summary>
-      ObjectStart,
-      /// <summary>
-      /// Reader is in an object.
-      /// </summary>
-      Object,
-      /// <summary>
-      /// Reader is at the start of an array.
-      /// </summary>
-      ArrayStart,
-      /// <summary>
-      /// Reader is in an array.
-      /// </summary>
-      Array,
-      /// <summary>
-      /// The Close method has been called.
-      /// </summary>
-      Closed,
-      /// <summary>
-      /// Reader has just read a value.
-      /// </summary>
-      PostValue,
-      /// <summary>
-      /// Reader is at the start of a constructor.
-      /// </summary>
-      ConstructorStart,
-      /// <summary>
-      /// Reader in a constructor.
-      /// </summary>
-      Constructor,
-      /// <summary>
-      /// An error occurred that prevents the read operation from continuing.
-      /// </summary>
-      Error,
-      /// <summary>
-      /// The end of the file has been reached successfully.
-      /// </summary>
-      Finished
-    }
-
-    // current Token data
-    private JsonToken _token;
-    private object _value;
-    private Type _valueType;
-    private char _quoteChar;
-    private State _currentState;
-    private JTokenType _currentTypeContext;
-
-    /// <summary>
-    /// Gets the current reader state.
-    /// </summary>
-    /// <value>The current reader state.</value>
-    protected State CurrentState
-    {
-      get { return _currentState; }
-    }
-
-    private int _top;
-
-    private readonly List<JTokenType> _stack;
-
-    /// <summary>
-    /// Gets the quotation mark character used to enclose the value of a string.
-    /// </summary>
-    public virtual char QuoteChar
-    {
-      get { return _quoteChar; }
-      protected internal set { _quoteChar = value; }
-    }
-
-    /// <summary>
-    /// Gets the type of the current Json token. 
-    /// </summary>
-    public virtual JsonToken TokenType
-    {
-      get { return _token; }
-    }
-
-    /// <summary>
-    /// Gets the text value of the current Json token.
-    /// </summary>
-    public virtual object Value
-    {
-      get { return _value; }
-    }
-
-    /// <summary>
-    /// Gets The Common Language Runtime (CLR) type for the current Json token.
-    /// </summary>
-    public virtual Type ValueType
-    {
-      get { return _valueType; }
-    }
-
-    /// <summary>
-    /// Gets the depth of the current token in the JSON document.
-    /// </summary>
-    /// <value>The depth of the current token in the JSON document.</value>
-    public virtual int Depth
-    {
-      get
-      {
-        int depth = _top - 1;
-        if (IsStartToken(TokenType))
-          return depth - 1;
-        else
-          return depth;
-      }
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonReader"/> class with the specified <see cref="TextReader"/>.
-    /// </summary>
-    protected JsonReader()
-    {
-      _currentState = State.Start;
-      _stack = new List<JTokenType>();
-      Push(JTokenType.None);
-    }
-
-    private void Push(JTokenType value)
-    {
-      _stack.Add(value);
-      _top++;
-      _currentTypeContext = value;
-    }
-
-    private JTokenType Pop()
-    {
-      JTokenType value = Peek();
-      _stack.RemoveAt(_stack.Count - 1);
-      _top--;
-      _currentTypeContext = _stack[_top - 1];
-
-      return value;
-    }
-
-    private JTokenType Peek()
-    {
-      return _currentTypeContext;
-    }
-
-    /// <summary>
-    /// Reads the next JSON token from the stream.
-    /// </summary>
-    /// <returns>true if the next token was read successfully; false if there are no more tokens to read.</returns>
-    public abstract bool Read();
-
-    /// <summary>
-    /// Reads the next JSON token from the stream as a <see cref="T:Byte[]"/>.
-    /// </summary>
-    /// <returns>A <see cref="T:Byte[]"/> or a null reference if the next JSON token is null.</returns>
-    public abstract byte[] ReadAsBytes();
-
-    /// <summary>
-    /// Skips the children of the current token.
-    /// </summary>
-    public void Skip()
-    {
-      if (IsStartToken(TokenType))
-      {
-        int depth = Depth;
-
-        while (Read() && (depth < Depth))
-        {
-        }
-      }
-    }
-
-    /// <summary>
-    /// Sets the current token.
-    /// </summary>
-    /// <param name="newToken">The new token.</param>
-    protected void SetToken(JsonToken newToken)
-    {
-      SetToken(newToken, null);
-    }
-
-    /// <summary>
-    /// Sets the current token and value.
-    /// </summary>
-    /// <param name="newToken">The new token.</param>
-    /// <param name="value">The value.</param>
-    protected virtual void SetToken(JsonToken newToken, object value)
-    {
-      _token = newToken;
-
-      switch (newToken)
-      {
-        case JsonToken.StartObject:
-          _currentState = State.ObjectStart;
-          Push(JTokenType.Object);
-          break;
-        case JsonToken.StartArray:
-          _currentState = State.ArrayStart;
-          Push(JTokenType.Array);
-          break;
-        case JsonToken.StartConstructor:
-          _currentState = State.ConstructorStart;
-          Push(JTokenType.Constructor);
-          break;
-        case JsonToken.EndObject:
-          ValidateEnd(JsonToken.EndObject);
-          _currentState = State.PostValue;
-          break;
-        case JsonToken.EndArray:
-          ValidateEnd(JsonToken.EndArray);
-          _currentState = State.PostValue;
-          break;
-        case JsonToken.EndConstructor:
-          ValidateEnd(JsonToken.EndConstructor);
-          _currentState = State.PostValue;
-          break;
-        case JsonToken.PropertyName:
-          _currentState = State.Property;
-          Push(JTokenType.Property);
-          break;
-        case JsonToken.Undefined:
-        case JsonToken.Integer:
-        case JsonToken.Float:
-        case JsonToken.Boolean:
-        case JsonToken.Null:
-        case JsonToken.Date:
-        case JsonToken.String:
-        case JsonToken.Raw:
-        case JsonToken.Bytes:
-          _currentState = State.PostValue;
-          break;
-      }
-
-      JTokenType current = Peek();
-      if (current == JTokenType.Property && _currentState == State.PostValue)
-        Pop();
-
-      if (value != null)
-      {
-        _value = value;
-        _valueType = value.GetType();
-      }
-      else
-      {
-        _value = null;
-        _valueType = null;
-      }
-    }
-
-    private void ValidateEnd(JsonToken endToken)
-    {
-      JTokenType currentObject = Pop();
-
-      if (GetTypeForCloseToken(endToken) != currentObject)
-        throw new JsonReaderException("JsonToken {0} is not valid for closing JsonType {1}.".FormatWith(CultureInfo.InvariantCulture, endToken, currentObject));
-    }
-
-    /// <summary>
-    /// Sets the state based on current token type.
-    /// </summary>
-    protected void SetStateBasedOnCurrent()
-    {
-      JTokenType currentObject = Peek();
-
-      switch (currentObject)
-      {
-        case JTokenType.Object:
-          _currentState = State.Object;
-          break;
-        case JTokenType.Array:
-          _currentState = State.Array;
-          break;
-        case JTokenType.Constructor:
-          _currentState = State.Constructor;
-          break;
-        case JTokenType.None:
-          _currentState = State.Finished;
-          break;
-        default:
-          throw new JsonReaderException("While setting the reader state back to current object an unexpected JsonType was encountered: " + currentObject);
-      }
-    }
-
-    internal static bool IsPrimitiveToken(JsonToken token)
-    {
-      switch (token)
-      {
-        case JsonToken.Integer:
-        case JsonToken.Float:
-        case JsonToken.String:
-        case JsonToken.Boolean:
-        case JsonToken.Undefined:
-        case JsonToken.Null:
-        case JsonToken.Date:
-        case JsonToken.Bytes:
-          return true;
-        default:
-          return false;
-      }
-    }
-
-    internal static bool IsStartToken(JsonToken token)
-    {
-      switch (token)
-      {
-        case JsonToken.StartObject:
-        case JsonToken.StartArray:
-        case JsonToken.StartConstructor:
-        case JsonToken.PropertyName:
-          return true;
-        case JsonToken.None:
-        case JsonToken.Comment:
-        case JsonToken.Integer:
-        case JsonToken.Float:
-        case JsonToken.String:
-        case JsonToken.Boolean:
-        case JsonToken.Null:
-        case JsonToken.Undefined:
-        case JsonToken.EndObject:
-        case JsonToken.EndArray:
-        case JsonToken.EndConstructor:
-        case JsonToken.Date:
-        case JsonToken.Raw:
-        case JsonToken.Bytes:
-          return false;
-        default:
-          throw MiscellaneousUtils.CreateArgumentOutOfRangeException("token", token, "Unexpected JsonToken value.");
-      }
-    }
-
-    private JTokenType GetTypeForCloseToken(JsonToken token)
-    {
-      switch (token)
-      {
-        case JsonToken.EndObject:
-          return JTokenType.Object;
-        case JsonToken.EndArray:
-          return JTokenType.Array;
-        case JsonToken.EndConstructor:
-          return JTokenType.Constructor;
-        default:
-          throw new JsonReaderException("Not a valid close JsonToken: " + token);
-      }
-    }
-
-    /// <summary>
-    /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
-    /// </summary>
-    void IDisposable.Dispose()
-    {
-      Dispose(true);
-    }
-
-    /// <summary>
-    /// Releases unmanaged and - optionally - managed resources
-    /// </summary>
-    /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
-    protected virtual void Dispose(bool disposing)
-    {
-      if (_currentState != State.Closed && disposing)
-        Close();
-    }
-
-    /// <summary>
-    /// Changes the <see cref="State"/> to Closed. 
-    /// </summary>
-    public virtual void Close()
-    {
-      _currentState = State.Closed;
-      _token = JsonToken.None;
-      _value = null;
-      _valueType = null;
-    }
-  }
-}
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Globalization;
+using Newtonsoft.Json.Utilities;
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#else
+using System.Linq;
+#endif
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Represents a reader that provides fast, non-cached, forward-only access to serialized Json data.
+  /// </summary>
+  public abstract class JsonReader : IDisposable
+  {
+    /// <summary>
+    /// Specifies the state of the reader.
+    /// </summary>
+    protected internal enum State
+    {
+      /// <summary>
+      /// The Read method has not been called.
+      /// </summary>
+      Start,
+      /// <summary>
+      /// The end of the file has been reached successfully.
+      /// </summary>
+      Complete,
+      /// <summary>
+      /// Reader is at a property.
+      /// </summary>
+      Property,
+      /// <summary>
+      /// Reader is at the start of an object.
+      /// </summary>
+      ObjectStart,
+      /// <summary>
+      /// Reader is in an object.
+      /// </summary>
+      Object,
+      /// <summary>
+      /// Reader is at the start of an array.
+      /// </summary>
+      ArrayStart,
+      /// <summary>
+      /// Reader is in an array.
+      /// </summary>
+      Array,
+      /// <summary>
+      /// The Close method has been called.
+      /// </summary>
+      Closed,
+      /// <summary>
+      /// Reader has just read a value.
+      /// </summary>
+      PostValue,
+      /// <summary>
+      /// Reader is at the start of a constructor.
+      /// </summary>
+      ConstructorStart,
+      /// <summary>
+      /// Reader in a constructor.
+      /// </summary>
+      Constructor,
+      /// <summary>
+      /// An error occurred that prevents the read operation from continuing.
+      /// </summary>
+      Error,
+      /// <summary>
+      /// The end of the file has been reached successfully.
+      /// </summary>
+      Finished
+    }
+
+    // current Token data
+    private JsonToken _tokenType;
+    private object _value;
+    private char _quoteChar;
+    internal State _currentState;
+    internal ReadType _readType;
+    private JsonPosition _currentPosition;
+    private CultureInfo _culture;
+    private DateTimeZoneHandling _dateTimeZoneHandling;
+    private int? _maxDepth;
+    private bool _hasExceededMaxDepth;
+    internal DateParseHandling _dateParseHandling;
+    private readonly List<JsonPosition> _stack;
+
+    /// <summary>
+    /// Gets the current reader state.
+    /// </summary>
+    /// <value>The current reader state.</value>
+    protected State CurrentState
+    {
+      get { return _currentState; }
+    }
+
+    /// <summary>
+    /// Gets or sets a value indicating whether the underlying stream or
+    /// <see cref="TextReader"/> should be closed when the reader is closed.
+    /// </summary>
+    /// <value>
+    /// true to close the underlying stream or <see cref="TextReader"/> when
+    /// the reader is closed; otherwise false. The default is true.
+    /// </value>
+    public bool CloseInput { get; set; }
+
+    /// <summary>
+    /// Gets the quotation mark character used to enclose the value of a string.
+    /// </summary>
+    public virtual char QuoteChar
+    {
+      get { return _quoteChar; }
+      protected internal set { _quoteChar = value; }
+    }
+
+    /// <summary>
+    /// Get or set how <see cref="DateTime"/> time zones are handling when reading JSON.
+    /// </summary>
+    public DateTimeZoneHandling DateTimeZoneHandling
+    {
+      get { return _dateTimeZoneHandling; }
+      set { _dateTimeZoneHandling = value; }
+    }
+
+    /// <summary>
+    /// Get or set how date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed when reading JSON.
+    /// </summary>
+    public DateParseHandling DateParseHandling
+    {
+      get { return _dateParseHandling; }
+      set { _dateParseHandling = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets the maximum depth allowed when reading JSON. Reading past this depth will throw a <see cref="JsonReaderException"/>.
+    /// </summary>
+    public int? MaxDepth
+    {
+      get { return _maxDepth; }
+      set
+      {
+        if (value <= 0)
+          throw new ArgumentException("Value must be positive.", "value");
+
+        _maxDepth = value;
+      }
+    }
+
+    /// <summary>
+    /// Gets the type of the current JSON token. 
+    /// </summary>
+    public virtual JsonToken TokenType
+    {
+      get { return _tokenType; }
+    }
+
+    /// <summary>
+    /// Gets the text value of the current JSON token.
+    /// </summary>
+    public virtual object Value
+    {
+      get { return _value; }
+    }
+
+    /// <summary>
+    /// Gets The Common Language Runtime (CLR) type for the current JSON token.
+    /// </summary>
+    public virtual Type ValueType
+    {
+      get { return (_value != null) ? _value.GetType() : null; }
+    }
+
+    /// <summary>
+    /// Gets the depth of the current token in the JSON document.
+    /// </summary>
+    /// <value>The depth of the current token in the JSON document.</value>
+    public virtual int Depth
+    {
+      get
+      {
+        int depth = _stack.Count;
+        if (IsStartToken(TokenType) || _currentPosition.Type == JsonContainerType.None)
+          return depth;
+        else
+          return depth + 1;
+      }
+    }
+
+    /// <summary>
+    /// Gets the path of the current JSON token. 
+    /// </summary>
+    public virtual string Path
+    {
+      get
+      {
+        if (_currentPosition.Type == JsonContainerType.None)
+          return string.Empty;
+
+        return JsonPosition.BuildPath(_stack.Concat(new[] { _currentPosition }));
+      }
+    }
+
+    /// <summary>
+    /// Gets or sets the culture used when reading JSON. Defaults to <see cref="CultureInfo.InvariantCulture"/>.
+    /// </summary>
+    public CultureInfo Culture
+    {
+      get { return _culture ?? CultureInfo.InvariantCulture; }
+      set { _culture = value; }
+    }
+
+    internal JsonPosition GetPosition(int depth)
+    {
+      if (depth < _stack.Count)
+        return _stack[depth];
+
+      return _currentPosition;
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonReader"/> class with the specified <see cref="TextReader"/>.
+    /// </summary>
+    protected JsonReader()
+    {
+      _currentState = State.Start;
+      _stack = new List<JsonPosition>(4);
+      _dateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind;
+      _dateParseHandling = DateParseHandling.DateTime;
+
+      CloseInput = true;
+    }
+
+    private void Push(JsonContainerType value)
+    {
+      UpdateScopeWithFinishedValue();
+
+      if (_currentPosition.Type == JsonContainerType.None)
+      {
+        _currentPosition.Type = value;
+      }
+      else
+      {
+        _stack.Add(_currentPosition);
+        JsonPosition state = new JsonPosition
+        {
+          Type = value
+        };
+        _currentPosition = state;
+
+        // this is a little hacky because Depth increases when first property/value is written but only testing here is faster/simpler
+        if (_maxDepth != null && Depth + 1 > _maxDepth && !_hasExceededMaxDepth)
+        {
+          _hasExceededMaxDepth = true;
+          throw JsonReaderException.Create(this, "The reader's MaxDepth of {0} has been exceeded.".FormatWith(CultureInfo.InvariantCulture, _maxDepth));
+        }
+      }
+    }
+
+    private JsonContainerType Pop()
+    {
+      JsonPosition oldPosition;
+      if (_stack.Count > 0)
+      {
+        oldPosition = _currentPosition;
+        _currentPosition = _stack[_stack.Count - 1];
+        _stack.RemoveAt(_stack.Count - 1);
+      }
+      else
+      {
+        oldPosition = _currentPosition;
+        _currentPosition = new JsonPosition();
+      }
+
+      if (_maxDepth != null && Depth <= _maxDepth)
+        _hasExceededMaxDepth = false;
+
+      return oldPosition.Type;
+    }
+
+    private JsonContainerType Peek()
+    {
+      return _currentPosition.Type;
+    }
+
+    /// <summary>
+    /// Reads the next JSON token from the stream.
+    /// </summary>
+    /// <returns>true if the next token was read successfully; false if there are no more tokens to read.</returns>
+    public abstract bool Read();
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="Nullable{Int32}"/>.
+    /// </summary>
+    /// <returns>A <see cref="Nullable{Int32}"/>. This method will return <c>null</c> at the end of an array.</returns>
+    public abstract int? ReadAsInt32();
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="String"/>.
+    /// </summary>
+    /// <returns>A <see cref="String"/>. This method will return <c>null</c> at the end of an array.</returns>
+    public abstract string ReadAsString();
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="T:Byte[]"/>.
+    /// </summary>
+    /// <returns>A <see cref="T:Byte[]"/> or a null reference if the next JSON token is null. This method will return <c>null</c> at the end of an array.</returns>
+    public abstract byte[] ReadAsBytes();
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="Nullable{Decimal}"/>.
+    /// </summary>
+    /// <returns>A <see cref="Nullable{Decimal}"/>. This method will return <c>null</c> at the end of an array.</returns>
+    public abstract decimal? ReadAsDecimal();
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="Nullable{DateTime}"/>.
+    /// </summary>
+    /// <returns>A <see cref="String"/>. This method will return <c>null</c> at the end of an array.</returns>
+    public abstract DateTime? ReadAsDateTime();
+
+#if !NET20
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="Nullable{DateTimeOffset}"/>.
+    /// </summary>
+    /// <returns>A <see cref="Nullable{DateTimeOffset}"/>. This method will return <c>null</c> at the end of an array.</returns>
+    public abstract DateTimeOffset? ReadAsDateTimeOffset();
+#endif
+
+    internal virtual bool ReadInternal()
+    {
+      throw new NotImplementedException();
+    }
+
+#if !NET20
+    internal DateTimeOffset? ReadAsDateTimeOffsetInternal()
+    {
+      _readType = ReadType.ReadAsDateTimeOffset;
+
+      do
+      {
+        if (!ReadInternal())
+        {
+          SetToken(JsonToken.None);
+          return null;
+        }
+      } while (TokenType == JsonToken.Comment);
+
+      if (TokenType == JsonToken.Date)
+      {
+        if (Value is DateTime)
+          SetToken(JsonToken.Date, new DateTimeOffset((DateTime)Value));
+
+        return (DateTimeOffset)Value;
+      }
+
+      if (TokenType == JsonToken.Null)
+        return null;
+
+      DateTimeOffset dt;
+      if (TokenType == JsonToken.String)
+      {
+        if (DateTimeOffset.TryParse((string)Value, Culture, DateTimeStyles.RoundtripKind, out dt))
+        {
+          SetToken(JsonToken.Date, dt);
+          return dt;
+        }
+        else
+        {
+          throw JsonReaderException.Create(this, "Could not convert string to DateTimeOffset: {0}.".FormatWith(CultureInfo.InvariantCulture, Value));
+        }
+      }
+
+      if (TokenType == JsonToken.EndArray)
+        return null;
+
+      throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
+    }
+#endif
+
+    internal byte[] ReadAsBytesInternal()
+    {
+      _readType = ReadType.ReadAsBytes;
+
+      do
+      {
+        if (!ReadInternal())
+        {
+          SetToken(JsonToken.None);
+          return null;
+        }
+      } while (TokenType == JsonToken.Comment);
+
+      if (IsWrappedInTypeObject())
+      {
+        byte[] data = ReadAsBytes();
+        ReadInternal();
+        SetToken(JsonToken.Bytes, data);
+        return data;
+      }
+
+      // attempt to convert possible base 64 string to bytes
+      if (TokenType == JsonToken.String)
+      {
+        string s = (string)Value;
+        byte[] data = (s.Length == 0) ? new byte[0] : Convert.FromBase64String(s);
+        SetToken(JsonToken.Bytes, data);
+      }
+
+      if (TokenType == JsonToken.Null)
+        return null;
+
+      if (TokenType == JsonToken.Bytes)
+        return (byte[])Value;
+
+      if (TokenType == JsonToken.StartArray)
+      {
+        List<byte> data = new List<byte>();
+
+        while (ReadInternal())
+        {
+          switch (TokenType)
+          {
+            case JsonToken.Integer:
+              data.Add(Convert.ToByte(Value, CultureInfo.InvariantCulture));
+              break;
+            case JsonToken.EndArray:
+              byte[] d = data.ToArray();
+              SetToken(JsonToken.Bytes, d);
+              return d;
+            case JsonToken.Comment:
+              // skip
+              break;
+            default:
+              throw JsonReaderException.Create(this, "Unexpected token when reading bytes: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
+          }
+        }
+
+        throw JsonReaderException.Create(this, "Unexpected end when reading bytes.");
+      }
+
+      if (TokenType == JsonToken.EndArray)
+        return null;
+
+      throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
+    }
+
+    internal decimal? ReadAsDecimalInternal()
+    {
+      _readType = ReadType.ReadAsDecimal;
+
+      do
+      {
+        if (!ReadInternal())
+        {
+          SetToken(JsonToken.None);
+          return null;
+        }
+      } while (TokenType == JsonToken.Comment);
+
+      if (TokenType == JsonToken.Integer || TokenType == JsonToken.Float)
+      {
+        if (!(Value is decimal))
+          SetToken(JsonToken.Float, Convert.ToDecimal(Value, CultureInfo.InvariantCulture));
+
+        return (decimal)Value;
+      }
+
+      if (TokenType == JsonToken.Null)
+        return null;
+
+      decimal d;
+      if (TokenType == JsonToken.String)
+      {
+        if (decimal.TryParse((string)Value, NumberStyles.Number, Culture, out d))
+        {
+          SetToken(JsonToken.Float, d);
+          return d;
+        }
+        else
+        {
+          throw JsonReaderException.Create(this, "Could not convert string to decimal: {0}.".FormatWith(CultureInfo.InvariantCulture, Value));
+        }
+      }
+
+      if (TokenType == JsonToken.EndArray)
+        return null;
+
+      throw JsonReaderException.Create(this, "Error reading decimal. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
+    }
+
+    internal int? ReadAsInt32Internal()
+    {
+      _readType = ReadType.ReadAsInt32;
+
+      do
+      {
+        if (!ReadInternal())
+        {
+          SetToken(JsonToken.None);
+          return null;
+        }
+      } while (TokenType == JsonToken.Comment);
+
+      if (TokenType == JsonToken.Integer || TokenType == JsonToken.Float)
+      {
+        if (!(Value is int))
+          SetToken(JsonToken.Integer, Convert.ToInt32(Value, CultureInfo.InvariantCulture));
+
+        return (int)Value;
+      }
+
+      if (TokenType == JsonToken.Null)
+        return null;
+
+      int i;
+      if (TokenType == JsonToken.String)
+      {
+        if (int.TryParse((string)Value, NumberStyles.Integer, Culture, out i))
+        {
+          SetToken(JsonToken.Integer, i);
+          return i;
+        }
+        else
+        {
+          throw JsonReaderException.Create(this, "Could not convert string to integer: {0}.".FormatWith(CultureInfo.InvariantCulture, Value));
+        }
+      }
+
+      if (TokenType == JsonToken.EndArray)
+        return null;
+
+      throw JsonReaderException.Create(this, "Error reading integer. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
+    }
+
+    internal string ReadAsStringInternal()
+    {
+      _readType = ReadType.ReadAsString;
+
+      do
+      {
+        if (!ReadInternal())
+        {
+          SetToken(JsonToken.None);
+          return null;
+        }
+      } while (TokenType == JsonToken.Comment);
+
+      if (TokenType == JsonToken.String)
+        return (string)Value;
+
+      if (TokenType == JsonToken.Null)
+        return null;
+
+      if (IsPrimitiveToken(TokenType))
+      {
+        if (Value != null)
+        {
+          string s;
+          if (ConvertUtils.IsConvertible(Value))
+            s = ConvertUtils.ToConvertible(Value).ToString(Culture);
+          else if (Value is IFormattable)
+            s = ((IFormattable)Value).ToString(null, Culture);
+          else
+            s = Value.ToString();
+
+          SetToken(JsonToken.String, s);
+          return s;
+        }
+      }
+
+      if (TokenType == JsonToken.EndArray)
+        return null;
+
+      throw JsonReaderException.Create(this, "Error reading string. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
+    }
+
+    internal DateTime? ReadAsDateTimeInternal()
+    {
+      _readType = ReadType.ReadAsDateTime;
+
+      do
+      {
+        if (!ReadInternal())
+        {
+          SetToken(JsonToken.None);
+          return null;
+        }
+      } while (TokenType == JsonToken.Comment);
+
+      if (TokenType == JsonToken.Date)
+        return (DateTime)Value;
+
+      if (TokenType == JsonToken.Null)
+        return null;
+
+      DateTime dt;
+      if (TokenType == JsonToken.String)
+      {
+        string s = (string)Value;
+        if (string.IsNullOrEmpty(s))
+        {
+          SetToken(JsonToken.Null);
+          return null;
+        }
+
+        if (DateTime.TryParse(s, Culture, DateTimeStyles.RoundtripKind, out dt))
+        {
+          dt = JsonConvert.EnsureDateTime(dt, DateTimeZoneHandling);
+          SetToken(JsonToken.Date, dt);
+          return dt;
+        }
+        else
+        {
+          throw JsonReaderException.Create(this, "Could not convert string to DateTime: {0}.".FormatWith(CultureInfo.InvariantCulture, Value));
+        }
+      }
+
+      if (TokenType == JsonToken.EndArray)
+        return null;
+
+      throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
+    }
+
+    private bool IsWrappedInTypeObject()
+    {
+      _readType = ReadType.Read;
+
+      if (TokenType == JsonToken.StartObject)
+      {
+        if (!ReadInternal())
+          throw JsonReaderException.Create(this, "Unexpected end when reading bytes.");
+
+        if (Value.ToString() == "$type")
+        {
+          ReadInternal();
+          if (Value != null && Value.ToString().StartsWith("System.Byte[]"))
+          {
+            ReadInternal();
+            if (Value.ToString() == "$value")
+            {
+              return true;
+            }
+          }
+        }
+
+        throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, JsonToken.StartObject));
+      }
+
+      return false;
+    }
+
+    /// <summary>
+    /// Skips the children of the current token.
+    /// </summary>
+    public void Skip()
+    {
+      if (TokenType == JsonToken.PropertyName)
+        Read();
+
+      if (IsStartToken(TokenType))
+      {
+        int depth = Depth;
+
+        while (Read() && (depth < Depth))
+        {
+        }
+      }
+    }
+
+    /// <summary>
+    /// Sets the current token.
+    /// </summary>
+    /// <param name="newToken">The new token.</param>
+    protected void SetToken(JsonToken newToken)
+    {
+      SetToken(newToken, null);
+    }
+
+    /// <summary>
+    /// Sets the current token and value.
+    /// </summary>
+    /// <param name="newToken">The new token.</param>
+    /// <param name="value">The value.</param>
+    protected void SetToken(JsonToken newToken, object value)
+    {
+      _tokenType = newToken;
+      _value = value;
+
+      switch (newToken)
+      {
+        case JsonToken.StartObject:
+          _currentState = State.ObjectStart;
+          Push(JsonContainerType.Object);
+          break;
+        case JsonToken.StartArray:
+          _currentState = State.ArrayStart;
+          Push(JsonContainerType.Array);
+          break;
+        case JsonToken.StartConstructor:
+          _currentState = State.ConstructorStart;
+          Push(JsonContainerType.Constructor);
+          break;
+        case JsonToken.EndObject:
+          ValidateEnd(JsonToken.EndObject);
+          break;
+        case JsonToken.EndArray:
+          ValidateEnd(JsonToken.EndArray);
+          break;
+        case JsonToken.EndConstructor:
+          ValidateEnd(JsonToken.EndConstructor);
+          break;
+        case JsonToken.PropertyName:
+          _currentState = State.Property;
+
+          _currentPosition.PropertyName = (string) value;
+          break;
+        case JsonToken.Undefined:
+        case JsonToken.Integer:
+        case JsonToken.Float:
+        case JsonToken.Boolean:
+        case JsonToken.Null:
+        case JsonToken.Date:
+        case JsonToken.String:
+        case JsonToken.Raw:
+        case JsonToken.Bytes:
+          _currentState = (Peek() != JsonContainerType.None) ? State.PostValue : State.Finished;
+
+          UpdateScopeWithFinishedValue();
+          break;
+      }
+    }
+
+    private void UpdateScopeWithFinishedValue()
+    {
+      if (_currentPosition.Type == JsonContainerType.Array
+        || _currentPosition.Type == JsonContainerType.Constructor)
+      {
+        if (_currentPosition.Position == null)
+          _currentPosition.Position = 0;
+        else
+          _currentPosition.Position++;
+      }
+    }
+
+    private void ValidateEnd(JsonToken endToken)
+    {
+      JsonContainerType currentObject = Pop();
+
+      if (GetTypeForCloseToken(endToken) != currentObject)
+        throw JsonReaderException.Create(this, "JsonToken {0} is not valid for closing JsonType {1}.".FormatWith(CultureInfo.InvariantCulture, endToken, currentObject));
+
+      _currentState = (Peek() != JsonContainerType.None) ? State.PostValue : State.Finished;
+    }
+
+    /// <summary>
+    /// Sets the state based on current token type.
+    /// </summary>
+    protected void SetStateBasedOnCurrent()
+    {
+      JsonContainerType currentObject = Peek();
+
+      switch (currentObject)
+      {
+        case JsonContainerType.Object:
+          _currentState = State.Object;
+          break;
+        case JsonContainerType.Array:
+          _currentState = State.Array;
+          break;
+        case JsonContainerType.Constructor:
+          _currentState = State.Constructor;
+          break;
+        case JsonContainerType.None:
+          _currentState = State.Finished;
+          break;
+        default:
+          throw JsonReaderException.Create(this, "While setting the reader state back to current object an unexpected JsonType was encountered: {0}".FormatWith(CultureInfo.InvariantCulture, currentObject));
+      }
+    }
+
+    internal static bool IsPrimitiveToken(JsonToken token)
+    {
+      switch (token)
+      {
+        case JsonToken.Integer:
+        case JsonToken.Float:
+        case JsonToken.String:
+        case JsonToken.Boolean:
+        case JsonToken.Undefined:
+        case JsonToken.Null:
+        case JsonToken.Date:
+        case JsonToken.Bytes:
+          return true;
+        default:
+          return false;
+      }
+    }
+
+    internal static bool IsStartToken(JsonToken token)
+    {
+      switch (token)
+      {
+        case JsonToken.StartObject:
+        case JsonToken.StartArray:
+        case JsonToken.StartConstructor:
+          return true;
+        default:
+          return false;
+      }
+    }
+
+    private JsonContainerType GetTypeForCloseToken(JsonToken token)
+    {
+      switch (token)
+      {
+        case JsonToken.EndObject:
+          return JsonContainerType.Object;
+        case JsonToken.EndArray:
+          return JsonContainerType.Array;
+        case JsonToken.EndConstructor:
+          return JsonContainerType.Constructor;
+        default:
+          throw JsonReaderException.Create(this, "Not a valid close JsonToken: {0}".FormatWith(CultureInfo.InvariantCulture, token));
+      }
+    }
+
+    /// <summary>
+    /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+    /// </summary>
+    void IDisposable.Dispose()
+    {
+      Dispose(true);
+    }
+
+    /// <summary>
+    /// Releases unmanaged and - optionally - managed resources
+    /// </summary>
+    /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
+    protected virtual void Dispose(bool disposing)
+    {
+      if (_currentState != State.Closed && disposing)
+        Close();
+    }
+
+    /// <summary>
+    /// Changes the <see cref="State"/> to Closed. 
+    /// </summary>
+    public virtual void Close()
+    {
+      _currentState = State.Closed;
+      _tokenType = JsonToken.None;
+      _value = null;
+    }
+  }
+}
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonReaderException.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonReaderException.cs
index 78ac891..ca6d3c7 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonReaderException.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonReaderException.cs
@@ -1,83 +1,139 @@
-#region License
-// 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.
-#endregion
-
-using System;
-
-namespace Newtonsoft.Json
-{
-  /// <summary>
-  /// The exception thrown when an error occurs while reading Json text.
-  /// </summary>
-  public class JsonReaderException : Exception
-  {
-    /// <summary>
-    /// Gets the line number indicating where the error occurred.
-    /// </summary>
-    /// <value>The line number indicating where the error occurred.</value>
-    public int LineNumber { get; private set; }
-
-
-    /// <summary>
-    /// Gets the line position indicating where the error occurred.
-    /// </summary>
-    /// <value>The line position indicating where the error occurred.</value>
-    public int LinePosition { get; private set; }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonReaderException"/> class.
-    /// </summary>
-    public JsonReaderException()
-    {
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonReaderException"/> class
-    /// with a specified error message.
-    /// </summary>
-    /// <param name="message">The error message that explains the reason for the exception.</param>
-    public JsonReaderException(string message)
-      : base(message)
-    {
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonReaderException"/> class
-    /// with a specified error message and a reference to the inner exception that is the cause of this exception.
-    /// </summary>
-    /// <param name="message">The error message that explains the reason for the exception.</param>
-    /// <param name="innerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
-    public JsonReaderException(string message, Exception innerException)
-      : base(message, innerException)
-    {
-    }
-
-    internal JsonReaderException(string message, Exception innerException, int lineNumber, int linePosition)
-      : base(message, innerException)
-    {
-      LineNumber = lineNumber;
-      LinePosition = linePosition;
-    }
-  }
-}
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Globalization;
+using System.Runtime.Serialization;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// The exception thrown when an error occurs while reading Json text.
+  /// </summary>
+#if !(SILVERLIGHT || WINDOWS_PHONE || NETFX_CORE || PORTABLE)
+  [Serializable]
+#endif
+  public class JsonReaderException : JsonException
+  {
+    /// <summary>
+    /// Gets the line number indicating where the error occurred.
+    /// </summary>
+    /// <value>The line number indicating where the error occurred.</value>
+    public int LineNumber { get; private set; }
+
+    /// <summary>
+    /// Gets the line position indicating where the error occurred.
+    /// </summary>
+    /// <value>The line position indicating where the error occurred.</value>
+    public int LinePosition { get; private set; }
+
+    /// <summary>
+    /// Gets the path to the JSON where the error occurred.
+    /// </summary>
+    /// <value>The path to the JSON where the error occurred.</value>
+    public string Path { get; private set; }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonReaderException"/> class.
+    /// </summary>
+    public JsonReaderException()
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonReaderException"/> class
+    /// with a specified error message.
+    /// </summary>
+    /// <param name="message">The error message that explains the reason for the exception.</param>
+    public JsonReaderException(string message)
+      : base(message)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonReaderException"/> class
+    /// with a specified error message and a reference to the inner exception that is the cause of this exception.
+    /// </summary>
+    /// <param name="message">The error message that explains the reason for the exception.</param>
+    /// <param name="innerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
+    public JsonReaderException(string message, Exception innerException)
+      : base(message, innerException)
+    {
+    }
+
+#if !(WINDOWS_PHONE || SILVERLIGHT || NETFX_CORE || PORTABLE)
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonReaderException"/> class.
+    /// </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 null. </exception>
+    /// <exception cref="T:System.Runtime.Serialization.SerializationException">The class name is null or <see cref="P:System.Exception.HResult"/> is zero (0). </exception>
+    public JsonReaderException(SerializationInfo info, StreamingContext context)
+      : base(info, context)
+    {
+    }
+#endif
+
+    internal JsonReaderException(string message, Exception innerException, string path, int lineNumber, int linePosition)
+      : base(message, innerException)
+    {
+      Path = path;
+      LineNumber = lineNumber;
+      LinePosition = linePosition;
+    }
+
+    internal static JsonReaderException Create(JsonReader reader, string message)
+    {
+      return Create(reader, message, null);
+    }
+
+    internal static JsonReaderException Create(JsonReader reader, string message, Exception ex)
+    {
+      return Create(reader as IJsonLineInfo, reader.Path, message, ex);
+    }
+
+    internal static JsonReaderException Create(IJsonLineInfo lineInfo, string path, string message, Exception ex)
+    {
+      message = FormatExceptionMessage(lineInfo, path, message);
+
+      int lineNumber;
+      int linePosition;
+      if (lineInfo != null && lineInfo.HasLineInfo())
+      {
+        lineNumber = lineInfo.LineNumber;
+        linePosition = lineInfo.LinePosition;
+      }
+      else
+      {
+        lineNumber = 0;
+        linePosition = 0;
+      }
+
+      return new JsonReaderException(message, ex, path, lineNumber, linePosition);
+    }
+  }
+}
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonSerializationException.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonSerializationException.cs
index bec2635..0ec50c7 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonSerializationException.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonSerializationException.cs
@@ -1,65 +1,100 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace Newtonsoft.Json
-{
-  /// <summary>
-  /// The exception thrown when an error occurs during Json serialization or deserialization.
-  /// </summary>
-  public class JsonSerializationException : Exception
-  {
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonSerializationException"/> class.
-    /// </summary>
-    public JsonSerializationException()
-    {
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonSerializationException"/> class
-    /// with a specified error message.
-    /// </summary>
-    /// <param name="message">The error message that explains the reason for the exception.</param>
-    public JsonSerializationException(string message)
-      : base(message)
-    {
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonSerializationException"/> class
-    /// with a specified error message and a reference to the inner exception that is the cause of this exception.
-    /// </summary>
-    /// <param name="message">The error message that explains the reason for the exception.</param>
-    /// <param name="innerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
-    public JsonSerializationException(string message, Exception innerException)
-      : base(message, innerException)
-    {
-    }
-  }
-}
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Text;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// The exception thrown when an error occurs during Json serialization or deserialization.
+  /// </summary>
+#if !(SILVERLIGHT || WINDOWS_PHONE || NETFX_CORE || PORTABLE)
+  [Serializable]
+#endif
+  public class JsonSerializationException : JsonException
+  {
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonSerializationException"/> class.
+    /// </summary>
+    public JsonSerializationException()
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonSerializationException"/> class
+    /// with a specified error message.
+    /// </summary>
+    /// <param name="message">The error message that explains the reason for the exception.</param>
+    public JsonSerializationException(string message)
+      : base(message)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonSerializationException"/> class
+    /// with a specified error message and a reference to the inner exception that is the cause of this exception.
+    /// </summary>
+    /// <param name="message">The error message that explains the reason for the exception.</param>
+    /// <param name="innerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
+    public JsonSerializationException(string message, Exception innerException)
+      : base(message, innerException)
+    {
+    }
+
+#if !(WINDOWS_PHONE || SILVERLIGHT || NETFX_CORE || PORTABLE)
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonSerializationException"/> class.
+    /// </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 null. </exception>
+    /// <exception cref="T:System.Runtime.Serialization.SerializationException">The class name is null or <see cref="P:System.Exception.HResult"/> is zero (0). </exception>
+    public JsonSerializationException(SerializationInfo info, StreamingContext context)
+      : base(info, context)
+    {
+    }
+#endif
+
+    internal static JsonSerializationException Create(JsonReader reader, string message)
+    {
+      return Create(reader, message, null);
+    }
+
+    internal static JsonSerializationException Create(JsonReader reader, string message, Exception ex)
+    {
+      return Create(reader as IJsonLineInfo, reader.Path, message, ex);
+    }
+
+    internal static JsonSerializationException Create(IJsonLineInfo lineInfo, string path, string message, Exception ex)
+    {
+      message = FormatExceptionMessage(lineInfo, path, message);
+
+      return new JsonSerializationException(message, ex);
+    }
+  }
+}
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonSerializer.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonSerializer.cs
index e711c9f..f76e96b 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonSerializer.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonSerializer.cs
@@ -1,484 +1,651 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Runtime.Serialization.Formatters;
-using Newtonsoft.Json.Converters;
-using Newtonsoft.Json.Serialization;
-using Newtonsoft.Json.Utilities;
-using System.Runtime.Serialization;
-using ErrorEventArgs=Newtonsoft.Json.Serialization.ErrorEventArgs;
-
-namespace Newtonsoft.Json
-{
-  /// <summary>
-  /// Serializes and deserializes objects into and from the JSON format.
-  /// The <see cref="JsonSerializer"/> enables you to control how objects are encoded into JSON.
-  /// </summary>
-  public class JsonSerializer
-  {
-    #region Properties
-    private TypeNameHandling _typeNameHandling;
-    private FormatterAssemblyStyle _typeNameAssemblyFormat;
-    private PreserveReferencesHandling _preserveReferencesHandling;
-    private ReferenceLoopHandling _referenceLoopHandling;
-    private MissingMemberHandling _missingMemberHandling;
-    private ObjectCreationHandling _objectCreationHandling;
-    private NullValueHandling _nullValueHandling;
-    private DefaultValueHandling _defaultValueHandling;
-    private ConstructorHandling _constructorHandling;
-    private JsonConverterCollection _converters;
-    private IContractResolver _contractResolver;
-    private IReferenceResolver _referenceResolver;
-    private SerializationBinder _binder;
-    private StreamingContext _context;
-
-    /// <summary>
-    /// Occurs when the <see cref="JsonSerializer"/> errors during serialization and deserialization.
-    /// </summary>
-    public virtual event EventHandler<ErrorEventArgs> Error;
-
-    /// <summary>
-    /// Gets or sets the <see cref="IReferenceResolver"/> used by the serializer when resolving references.
-    /// </summary>
-    public virtual IReferenceResolver ReferenceResolver
-    {
-      get
-      {
-        if (_referenceResolver == null)
-          _referenceResolver = new DefaultReferenceResolver();
-
-        return _referenceResolver;
-      }
-      set
-      {
-        if (value == null)
-          throw new ArgumentNullException("value", "Reference resolver cannot be null.");
-
-        _referenceResolver = value;
-      }
-    }
-
-    /// <summary>
-    /// Gets or sets the <see cref="SerializationBinder"/> used by the serializer when resolving type names.
-    /// </summary>
-    public virtual SerializationBinder Binder
-    {
-      get
-      {
-        return _binder;
-      }
-      set
-      {
-        if (value == null)
-          throw new ArgumentNullException("value", "Serialization binder cannot be null.");
-
-        _binder = value;
-      }
-    }
-
-    /// <summary>
-    /// Gets or sets how type name writing and reading is handled by the serializer.
-    /// </summary>
-    public virtual TypeNameHandling TypeNameHandling
-    {
-      get { return _typeNameHandling; }
-      set
-      {
-        if (value < TypeNameHandling.None || value > TypeNameHandling.Auto)
-          throw new ArgumentOutOfRangeException("value");
-
-        _typeNameHandling = value;
-      }
-    }
-
-    /// <summary>
-    /// Gets or sets how a type name assembly is written and resolved by the serializer.
-    /// </summary>
-    /// <value>The type name assembly format.</value>
-    public virtual FormatterAssemblyStyle TypeNameAssemblyFormat
-    {
-      get { return _typeNameAssemblyFormat; }
-      set
-      {
-        if (value < FormatterAssemblyStyle.Simple || value > FormatterAssemblyStyle.Full)
-          throw new ArgumentOutOfRangeException("value");
-
-        _typeNameAssemblyFormat = value;
-      }
-    }
-
-    /// <summary>
-    /// Gets or sets how object references are preserved by the serializer.
-    /// </summary>
-    public virtual PreserveReferencesHandling PreserveReferencesHandling
-    {
-      get { return _preserveReferencesHandling; }
-      set
-      {
-        if (value < PreserveReferencesHandling.None || value > PreserveReferencesHandling.All)
-          throw new ArgumentOutOfRangeException("value");
-
-        _preserveReferencesHandling = value;
-      }
-    }
-
-    /// <summary>
-    /// Get or set how reference loops (e.g. a class referencing itself) is handled.
-    /// </summary>
-    public virtual ReferenceLoopHandling ReferenceLoopHandling
-    {
-      get { return _referenceLoopHandling; }
-      set
-      {
-        if (value < ReferenceLoopHandling.Error || value > ReferenceLoopHandling.Serialize)
-          throw new ArgumentOutOfRangeException("value");
-
-        _referenceLoopHandling = value;
-      }
-    }
-
-    /// <summary>
-    /// Get or set how missing members (e.g. JSON contains a property that isn't a member on the object) are handled during deserialization.
-    /// </summary>
-    public virtual MissingMemberHandling MissingMemberHandling
-    {
-      get { return _missingMemberHandling; }
-      set
-      {
-        if (value < MissingMemberHandling.Ignore || value > MissingMemberHandling.Error)
-          throw new ArgumentOutOfRangeException("value");
-
-        _missingMemberHandling = value;
-      }
-    }
-
-    /// <summary>
-    /// Get or set how null values are handled during serialization and deserialization.
-    /// </summary>
-    public virtual NullValueHandling NullValueHandling
-    {
-      get { return _nullValueHandling; }
-      set
-      {
-        if (value < NullValueHandling.Include || value > NullValueHandling.Ignore)
-          throw new ArgumentOutOfRangeException("value");
-
-        _nullValueHandling = value;
-      }
-    }
-
-    /// <summary>
-    /// Get or set how null default are handled during serialization and deserialization.
-    /// </summary>
-    public virtual DefaultValueHandling DefaultValueHandling
-    {
-      get { return _defaultValueHandling; }
-      set
-      {
-        if (value < DefaultValueHandling.Include || value > DefaultValueHandling.Ignore)
-          throw new ArgumentOutOfRangeException("value");
-
-        _defaultValueHandling = value;
-      }
-    }
-
-    /// <summary>
-    /// Gets or sets how objects are created during deserialization.
-    /// </summary>
-    /// <value>The object creation handling.</value>
-    public virtual ObjectCreationHandling ObjectCreationHandling
-    {
-      get { return _objectCreationHandling; }
-      set
-      {
-        if (value < ObjectCreationHandling.Auto || value > ObjectCreationHandling.Replace)
-          throw new ArgumentOutOfRangeException("value");
-
-        _objectCreationHandling = value;
-      }
-    }
-
-    /// <summary>
-    /// Gets or sets how constructors are used during deserialization.
-    /// </summary>
-    /// <value>The constructor handling.</value>
-    public virtual ConstructorHandling ConstructorHandling
-    {
-      get { return _constructorHandling; }
-      set
-      {
-        if (value < ConstructorHandling.Default || value > ConstructorHandling.AllowNonPublicDefaultConstructor)
-          throw new ArgumentOutOfRangeException("value");
-
-        _constructorHandling = value;
-      }
-    }
-
-    /// <summary>
-    /// Gets a collection <see cref="JsonConverter"/> that will be used during serialization.
-    /// </summary>
-    /// <value>Collection <see cref="JsonConverter"/> that will be used during serialization.</value>
-    public virtual JsonConverterCollection Converters
-    {
-      get
-      {
-        if (_converters == null)
-          _converters = new JsonConverterCollection();
-
-        return _converters;
-      }
-    }
-
-    /// <summary>
-    /// Gets or sets the contract resolver used by the serializer when
-    /// serializing .NET objects to JSON and vice versa.
-    /// </summary>
-    public virtual IContractResolver ContractResolver
-    {
-      get
-      {
-        if (_contractResolver == null)
-          _contractResolver = DefaultContractResolver.Instance;
-
-        return _contractResolver;
-      }
-      set { _contractResolver = value; }
-    }
-
-    /// <summary>
-    /// Gets or sets the <see cref="StreamingContext"/> used by the serializer when invoking serialization callback methods.
-    /// </summary>
-    /// <value>The context.</value>
-    public virtual StreamingContext Context
-    {
-      get { return _context; }
-      set { _context = value; }
-    }
-    #endregion
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonSerializer"/> class.
-    /// </summary>
-    public JsonSerializer()
-    {
-      _referenceLoopHandling = JsonSerializerSettings.DefaultReferenceLoopHandling;
-      _missingMemberHandling = JsonSerializerSettings.DefaultMissingMemberHandling;
-      _nullValueHandling = JsonSerializerSettings.DefaultNullValueHandling;
-      _defaultValueHandling = JsonSerializerSettings.DefaultDefaultValueHandling;
-      _objectCreationHandling = JsonSerializerSettings.DefaultObjectCreationHandling;
-      _preserveReferencesHandling = JsonSerializerSettings.DefaultPreserveReferencesHandling;
-      _constructorHandling = JsonSerializerSettings.DefaultConstructorHandling;
-      _typeNameHandling = JsonSerializerSettings.DefaultTypeNameHandling;
-      _context = JsonSerializerSettings.DefaultContext;
-
-      _binder = DefaultSerializationBinder.Instance;
-    }
-
-    /// <summary>
-    /// Creates a new <see cref="JsonSerializer"/> instance using the specified <see cref="JsonSerializerSettings"/>.
-    /// </summary>
-    /// <param name="settings">The settings to be applied to the <see cref="JsonSerializer"/>.</param>
-    /// <returns>A new <see cref="JsonSerializer"/> instance using the specified <see cref="JsonSerializerSettings"/>.</returns>
-    public static JsonSerializer Create(JsonSerializerSettings settings)
-    {
-      JsonSerializer jsonSerializer = new JsonSerializer();
-
-      if (settings != null)
-      {
-        if (!CollectionUtils.IsNullOrEmpty(settings.Converters))
-          jsonSerializer.Converters.AddRange(settings.Converters);
-
-        jsonSerializer.TypeNameHandling = settings.TypeNameHandling;
-        jsonSerializer.TypeNameAssemblyFormat = settings.TypeNameAssemblyFormat;
-        jsonSerializer.PreserveReferencesHandling = settings.PreserveReferencesHandling;
-        jsonSerializer.ReferenceLoopHandling = settings.ReferenceLoopHandling;
-        jsonSerializer.MissingMemberHandling = settings.MissingMemberHandling;
-        jsonSerializer.ObjectCreationHandling = settings.ObjectCreationHandling;
-        jsonSerializer.NullValueHandling = settings.NullValueHandling;
-        jsonSerializer.DefaultValueHandling = settings.DefaultValueHandling;
-        jsonSerializer.ConstructorHandling = settings.ConstructorHandling;
-        jsonSerializer.Context = settings.Context;
-
-        if (settings.Error != null)
-          jsonSerializer.Error += settings.Error;
-
-        if (settings.ContractResolver != null)
-          jsonSerializer.ContractResolver = settings.ContractResolver;
-        if (settings.ReferenceResolver != null)
-          jsonSerializer.ReferenceResolver = settings.ReferenceResolver;
-        if (settings.Binder != null)
-          jsonSerializer.Binder = settings.Binder;
-      }
-
-      return jsonSerializer;
-    }
-
-    /// <summary>
-    /// Populates the JSON values onto the target object.
-    /// </summary>
-    /// <param name="reader">The <see cref="TextReader"/> that contains the JSON structure to reader values from.</param>
-    /// <param name="target">The target object to populate values onto.</param>
-    public void Populate(TextReader reader, object target)
-    {
-      Populate(new JsonTextReader(reader), target);
-    }
-
-    /// <summary>
-    /// Populates the JSON values onto the target object.
-    /// </summary>
-    /// <param name="reader">The <see cref="JsonReader"/> that contains the JSON structure to reader values from.</param>
-    /// <param name="target">The target object to populate values onto.</param>
-    public void Populate(JsonReader reader, object target)
-    {
-      PopulateInternal(reader, target);
-    }
-
-    internal virtual void PopulateInternal(JsonReader reader, object target)
-    {
-      ValidationUtils.ArgumentNotNull(reader, "reader");
-      ValidationUtils.ArgumentNotNull(target, "target");
-
-      JsonSerializerInternalReader serializerReader = new JsonSerializerInternalReader(this);
-      serializerReader.Populate(reader, target);
-    }
-
-    /// <summary>
-    /// Deserializes the Json structure contained by the specified <see cref="JsonReader"/>.
-    /// </summary>
-    /// <param name="reader">The <see cref="JsonReader"/> that contains the JSON structure to deserialize.</param>
-    /// <returns>The <see cref="Object"/> being deserialized.</returns>
-    public object Deserialize(JsonReader reader)
-    {
-      return Deserialize(reader, null);
-    }
-
-    /// <summary>
-    /// Deserializes the Json structure contained by the specified <see cref="StringReader"/>
-    /// into an instance of the specified type.
-    /// </summary>
-    /// <param name="reader">The <see cref="TextReader"/> containing the object.</param>
-    /// <param name="objectType">The <see cref="Type"/> of object being deserialized.</param>
-    /// <returns>The instance of <paramref name="objectType"/> being deserialized.</returns>
-    public object Deserialize(TextReader reader, Type objectType)
-    {
-      return Deserialize(new JsonTextReader(reader), objectType);
-    }
-
-    /// <summary>
-    /// Deserializes the Json structure contained by the specified <see cref="JsonReader"/>
-    /// into an instance of the specified type.
-    /// </summary>
-    /// <param name="reader">The <see cref="JsonReader"/> containing the object.</param>
-    /// <typeparam name="T">The type of the object to deserialize.</typeparam>
-    /// <returns>The instance of <typeparamref name="T"/> being deserialized.</returns>
-    public T Deserialize<T>(JsonReader reader)
-    {
-      return (T)Deserialize(reader, typeof(T));
-    }
-
-    /// <summary>
-    /// Deserializes the Json structure contained by the specified <see cref="JsonReader"/>
-    /// into an instance of the specified type.
-    /// </summary>
-    /// <param name="reader">The <see cref="JsonReader"/> containing the object.</param>
-    /// <param name="objectType">The <see cref="Type"/> of object being deserialized.</param>
-    /// <returns>The instance of <paramref name="objectType"/> being deserialized.</returns>
-    public object Deserialize(JsonReader reader, Type objectType)
-    {
-      return DeserializeInternal(reader, objectType);
-    }
-
-    internal virtual object DeserializeInternal(JsonReader reader, Type objectType)
-    {
-      ValidationUtils.ArgumentNotNull(reader, "reader");
-
-      JsonSerializerInternalReader serializerReader = new JsonSerializerInternalReader(this);
-      return serializerReader.Deserialize(reader, objectType);
-    }
-
-    /// <summary>
-    /// Serializes the specified <see cref="Object"/> and writes the Json structure
-    /// to a <c>Stream</c> using the specified <see cref="TextWriter"/>. 
-    /// </summary>
-    /// <param name="textWriter">The <see cref="TextWriter"/> used to write the Json structure.</param>
-    /// <param name="value">The <see cref="Object"/> to serialize.</param>
-    public void Serialize(TextWriter textWriter, object value)
-    {
-      Serialize(new JsonTextWriter(textWriter), value);
-    }
-
-    /// <summary>
-    /// Serializes the specified <see cref="Object"/> and writes the Json structure
-    /// to a <c>Stream</c> using the specified <see cref="JsonWriter"/>. 
-    /// </summary>
-    /// <param name="jsonWriter">The <see cref="JsonWriter"/> used to write the Json structure.</param>
-    /// <param name="value">The <see cref="Object"/> to serialize.</param>
-    public void Serialize(JsonWriter jsonWriter, object value)
-    {
-      SerializeInternal(jsonWriter, value);
-    }
-
-    internal virtual void SerializeInternal(JsonWriter jsonWriter, object value)
-    {
-      ValidationUtils.ArgumentNotNull(jsonWriter, "jsonWriter");
-
-      JsonSerializerInternalWriter serializerWriter = new JsonSerializerInternalWriter(this);
-      serializerWriter.Serialize(jsonWriter, value);
-    }
-
-    internal JsonConverter GetMatchingConverter(Type type)
-    {
-      return GetMatchingConverter(_converters, type);
-    }
-
-    internal static JsonConverter GetMatchingConverter(IList<JsonConverter> converters, Type objectType)
-    {
-      ValidationUtils.ArgumentNotNull(objectType, "objectType");
-
-      if (converters != null)
-      {
-        for (int i = 0; i < converters.Count; i++)
-        {
-          JsonConverter converter = converters[i];
-
-          if (converter.CanConvert(objectType))
-            return converter;
-        }
-      }
-
-      return null;
-    }
-
-    internal void OnError(ErrorEventArgs e)
-    {
-      EventHandler<ErrorEventArgs> error = Error;
-      if (error != null)
-        error(this, e);
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Runtime.Serialization.Formatters;
+using Newtonsoft.Json.Converters;
+using Newtonsoft.Json.Serialization;
+using Newtonsoft.Json.Utilities;
+using System.Runtime.Serialization;
+using ErrorEventArgs=Newtonsoft.Json.Serialization.ErrorEventArgs;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Serializes and deserializes objects into and from the JSON format.
+  /// The <see cref="JsonSerializer"/> enables you to control how objects are encoded into JSON.
+  /// </summary>
+  public class JsonSerializer
+  {
+    #region Properties
+    private TypeNameHandling _typeNameHandling;
+    private FormatterAssemblyStyle _typeNameAssemblyFormat;
+    private PreserveReferencesHandling _preserveReferencesHandling;
+    private ReferenceLoopHandling _referenceLoopHandling;
+    private MissingMemberHandling _missingMemberHandling;
+    private ObjectCreationHandling _objectCreationHandling;
+    private NullValueHandling _nullValueHandling;
+    private DefaultValueHandling _defaultValueHandling;
+    private ConstructorHandling _constructorHandling;
+    private JsonConverterCollection _converters;
+    private IContractResolver _contractResolver;
+    private IReferenceResolver _referenceResolver;
+    private SerializationBinder _binder;
+    private StreamingContext _context;
+    private Formatting? _formatting;
+    private DateFormatHandling? _dateFormatHandling;
+    private DateTimeZoneHandling? _dateTimeZoneHandling;
+    private DateParseHandling? _dateParseHandling;
+    private CultureInfo _culture;
+    private int? _maxDepth;
+    private bool _maxDepthSet;
+    private bool? _checkAdditionalContent;
+
+    /// <summary>
+    /// Occurs when the <see cref="JsonSerializer"/> errors during serialization and deserialization.
+    /// </summary>
+    public virtual event EventHandler<ErrorEventArgs> Error;
+
+    /// <summary>
+    /// Gets or sets the <see cref="IReferenceResolver"/> used by the serializer when resolving references.
+    /// </summary>
+    public virtual IReferenceResolver ReferenceResolver
+    {
+      get
+      {
+        if (_referenceResolver == null)
+          _referenceResolver = new DefaultReferenceResolver();
+
+        return _referenceResolver;
+      }
+      set
+      {
+        if (value == null)
+          throw new ArgumentNullException("value", "Reference resolver cannot be null.");
+
+        _referenceResolver = value;
+      }
+    }
+
+    /// <summary>
+    /// Gets or sets the <see cref="SerializationBinder"/> used by the serializer when resolving type names.
+    /// </summary>
+    public virtual SerializationBinder Binder
+    {
+      get
+      {
+        return _binder;
+      }
+      set
+      {
+        if (value == null)
+          throw new ArgumentNullException("value", "Serialization binder cannot be null.");
+
+        _binder = value;
+      }
+    }
+
+    /// <summary>
+    /// Gets or sets how type name writing and reading is handled by the serializer.
+    /// </summary>
+    public virtual TypeNameHandling TypeNameHandling
+    {
+      get { return _typeNameHandling; }
+      set
+      {
+        if (value < TypeNameHandling.None || value > TypeNameHandling.Auto)
+          throw new ArgumentOutOfRangeException("value");
+
+        _typeNameHandling = value;
+      }
+    }
+
+    /// <summary>
+    /// Gets or sets how a type name assembly is written and resolved by the serializer.
+    /// </summary>
+    /// <value>The type name assembly format.</value>
+    public virtual FormatterAssemblyStyle TypeNameAssemblyFormat
+    {
+      get { return _typeNameAssemblyFormat; }
+      set
+      {
+        if (value < FormatterAssemblyStyle.Simple || value > FormatterAssemblyStyle.Full)
+          throw new ArgumentOutOfRangeException("value");
+
+        _typeNameAssemblyFormat = value;
+      }
+    }
+
+    /// <summary>
+    /// Gets or sets how object references are preserved by the serializer.
+    /// </summary>
+    public virtual PreserveReferencesHandling PreserveReferencesHandling
+    {
+      get { return _preserveReferencesHandling; }
+      set
+      {
+        if (value < PreserveReferencesHandling.None || value > PreserveReferencesHandling.All)
+          throw new ArgumentOutOfRangeException("value");
+
+        _preserveReferencesHandling = value;
+      }
+    }
+
+    /// <summary>
+    /// Get or set how reference loops (e.g. a class referencing itself) is handled.
+    /// </summary>
+    public virtual ReferenceLoopHandling ReferenceLoopHandling
+    {
+      get { return _referenceLoopHandling; }
+      set
+      {
+        if (value < ReferenceLoopHandling.Error || value > ReferenceLoopHandling.Serialize)
+          throw new ArgumentOutOfRangeException("value");
+
+        _referenceLoopHandling = value;
+      }
+    }
+
+    /// <summary>
+    /// Get or set how missing members (e.g. JSON contains a property that isn't a member on the object) are handled during deserialization.
+    /// </summary>
+    public virtual MissingMemberHandling MissingMemberHandling
+    {
+      get { return _missingMemberHandling; }
+      set
+      {
+        if (value < MissingMemberHandling.Ignore || value > MissingMemberHandling.Error)
+          throw new ArgumentOutOfRangeException("value");
+
+        _missingMemberHandling = value;
+      }
+    }
+
+    /// <summary>
+    /// Get or set how null values are handled during serialization and deserialization.
+    /// </summary>
+    public virtual NullValueHandling NullValueHandling
+    {
+      get { return _nullValueHandling; }
+      set
+      {
+        if (value < NullValueHandling.Include || value > NullValueHandling.Ignore)
+          throw new ArgumentOutOfRangeException("value");
+
+        _nullValueHandling = value;
+      }
+    }
+
+    /// <summary>
+    /// Get or set how null default are handled during serialization and deserialization.
+    /// </summary>
+    public virtual DefaultValueHandling DefaultValueHandling
+    {
+      get { return _defaultValueHandling; }
+      set
+      {
+        if (value < DefaultValueHandling.Include || value > DefaultValueHandling.IgnoreAndPopulate)
+          throw new ArgumentOutOfRangeException("value");
+
+        _defaultValueHandling = value;
+      }
+    }
+
+    /// <summary>
+    /// Gets or sets how objects are created during deserialization.
+    /// </summary>
+    /// <value>The object creation handling.</value>
+    public virtual ObjectCreationHandling ObjectCreationHandling
+    {
+      get { return _objectCreationHandling; }
+      set
+      {
+        if (value < ObjectCreationHandling.Auto || value > ObjectCreationHandling.Replace)
+          throw new ArgumentOutOfRangeException("value");
+
+        _objectCreationHandling = value;
+      }
+    }
+
+    /// <summary>
+    /// Gets or sets how constructors are used during deserialization.
+    /// </summary>
+    /// <value>The constructor handling.</value>
+    public virtual ConstructorHandling ConstructorHandling
+    {
+      get { return _constructorHandling; }
+      set
+      {
+        if (value < ConstructorHandling.Default || value > ConstructorHandling.AllowNonPublicDefaultConstructor)
+          throw new ArgumentOutOfRangeException("value");
+
+        _constructorHandling = value;
+      }
+    }
+
+    /// <summary>
+    /// Gets a collection <see cref="JsonConverter"/> that will be used during serialization.
+    /// </summary>
+    /// <value>Collection <see cref="JsonConverter"/> that will be used during serialization.</value>
+    public virtual JsonConverterCollection Converters
+    {
+      get
+      {
+        if (_converters == null)
+          _converters = new JsonConverterCollection();
+
+        return _converters;
+      }
+    }
+
+    /// <summary>
+    /// Gets or sets the contract resolver used by the serializer when
+    /// serializing .NET objects to JSON and vice versa.
+    /// </summary>
+    public virtual IContractResolver ContractResolver
+    {
+      get
+      {
+        if (_contractResolver == null)
+          _contractResolver = DefaultContractResolver.Instance;
+
+        return _contractResolver;
+      }
+      set { _contractResolver = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets the <see cref="StreamingContext"/> used by the serializer when invoking serialization callback methods.
+    /// </summary>
+    /// <value>The context.</value>
+    public virtual StreamingContext Context
+    {
+      get { return _context; }
+      set { _context = value; }
+    }
+
+    /// <summary>
+    /// Indicates how JSON text output is formatted.
+    /// </summary>
+    public virtual Formatting Formatting
+    {
+      get { return _formatting ?? JsonSerializerSettings.DefaultFormatting; }
+      set { _formatting = value; }
+    }
+
+    /// <summary>
+    /// Get or set how dates are written to JSON text.
+    /// </summary>
+    public virtual DateFormatHandling DateFormatHandling
+    {
+      get { return _dateFormatHandling ?? JsonSerializerSettings.DefaultDateFormatHandling; }
+      set { _dateFormatHandling = value; }
+    }
+
+    /// <summary>
+    /// Get or set how <see cref="DateTime"/> time zones are handling during serialization and deserialization.
+    /// </summary>
+    public virtual DateTimeZoneHandling DateTimeZoneHandling
+    {
+      get { return _dateTimeZoneHandling ?? JsonSerializerSettings.DefaultDateTimeZoneHandling; }
+      set { _dateTimeZoneHandling = value; }
+    }
+
+    /// <summary>
+    /// Get or set how date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed when reading JSON.
+    /// </summary>
+    public virtual DateParseHandling DateParseHandling
+    {
+      get { return _dateParseHandling ?? JsonSerializerSettings.DefaultDateParseHandling; }
+      set { _dateParseHandling = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets the culture used when reading JSON. Defaults to <see cref="CultureInfo.InvariantCulture"/>.
+    /// </summary>
+    public virtual CultureInfo Culture
+    {
+      get { return _culture ?? JsonSerializerSettings.DefaultCulture; }
+      set { _culture = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets the maximum depth allowed when reading JSON. Reading past this depth will throw a <see cref="JsonReaderException"/>.
+    /// </summary>
+    public virtual int? MaxDepth
+    {
+      get { return _maxDepth; }
+      set
+      {
+        if (value <= 0)
+          throw new ArgumentException("Value must be positive.", "value");
+
+        _maxDepth = value;
+        _maxDepthSet = true;
+      }
+    }
+
+    /// <summary>
+    /// Gets a value indicating whether there will be a check for additional JSON content after deserializing an object.
+    /// </summary>
+    /// <value>
+    /// 	<c>true</c> if there will be a check for additional JSON content after deserializing an object; otherwise, <c>false</c>.
+    /// </value>
+    public virtual bool CheckAdditionalContent
+    {
+      get { return _checkAdditionalContent ?? JsonSerializerSettings.DefaultCheckAdditionalContent; }
+      set { _checkAdditionalContent = value; }
+    }
+
+    internal bool IsCheckAdditionalContentSet()
+    {
+      return (_checkAdditionalContent != null);
+    }
+
+    #endregion
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonSerializer"/> class.
+    /// </summary>
+    public JsonSerializer()
+    {
+      _referenceLoopHandling = JsonSerializerSettings.DefaultReferenceLoopHandling;
+      _missingMemberHandling = JsonSerializerSettings.DefaultMissingMemberHandling;
+      _nullValueHandling = JsonSerializerSettings.DefaultNullValueHandling;
+      _defaultValueHandling = JsonSerializerSettings.DefaultDefaultValueHandling;
+      _objectCreationHandling = JsonSerializerSettings.DefaultObjectCreationHandling;
+      _preserveReferencesHandling = JsonSerializerSettings.DefaultPreserveReferencesHandling;
+      _constructorHandling = JsonSerializerSettings.DefaultConstructorHandling;
+      _typeNameHandling = JsonSerializerSettings.DefaultTypeNameHandling;
+      _context = JsonSerializerSettings.DefaultContext;
+      _binder = DefaultSerializationBinder.Instance;
+    }
+
+    /// <summary>
+    /// Creates a new <see cref="JsonSerializer"/> instance using the specified <see cref="JsonSerializerSettings"/>.
+    /// </summary>
+    /// <param name="settings">The settings to be applied to the <see cref="JsonSerializer"/>.</param>
+    /// <returns>A new <see cref="JsonSerializer"/> instance using the specified <see cref="JsonSerializerSettings"/>.</returns>
+    public static JsonSerializer Create(JsonSerializerSettings settings)
+    {
+      JsonSerializer jsonSerializer = new JsonSerializer();
+
+      if (settings != null)
+      {
+        if (!CollectionUtils.IsNullOrEmpty(settings.Converters))
+          jsonSerializer.Converters.AddRange(settings.Converters);
+
+        // serializer specific
+        jsonSerializer.TypeNameHandling = settings.TypeNameHandling;
+        jsonSerializer.TypeNameAssemblyFormat = settings.TypeNameAssemblyFormat;
+        jsonSerializer.PreserveReferencesHandling = settings.PreserveReferencesHandling;
+        jsonSerializer.ReferenceLoopHandling = settings.ReferenceLoopHandling;
+        jsonSerializer.MissingMemberHandling = settings.MissingMemberHandling;
+        jsonSerializer.ObjectCreationHandling = settings.ObjectCreationHandling;
+        jsonSerializer.NullValueHandling = settings.NullValueHandling;
+        jsonSerializer.DefaultValueHandling = settings.DefaultValueHandling;
+        jsonSerializer.ConstructorHandling = settings.ConstructorHandling;
+        jsonSerializer.Context = settings.Context;
+        jsonSerializer._checkAdditionalContent = settings._checkAdditionalContent;
+
+        // reader/writer specific
+        // unset values won't override reader/writer set values
+        jsonSerializer._formatting = settings._formatting;
+        jsonSerializer._dateFormatHandling = settings._dateFormatHandling;
+        jsonSerializer._dateTimeZoneHandling = settings._dateTimeZoneHandling;
+        jsonSerializer._dateParseHandling = settings._dateParseHandling;
+        jsonSerializer._culture = settings._culture;
+        jsonSerializer._maxDepth = settings._maxDepth;
+        jsonSerializer._maxDepthSet = settings._maxDepthSet;
+
+        if (settings.Error != null)
+          jsonSerializer.Error += settings.Error;
+
+        if (settings.ContractResolver != null)
+          jsonSerializer.ContractResolver = settings.ContractResolver;
+        if (settings.ReferenceResolver != null)
+          jsonSerializer.ReferenceResolver = settings.ReferenceResolver;
+        if (settings.Binder != null)
+          jsonSerializer.Binder = settings.Binder;
+      }
+
+      return jsonSerializer;
+    }
+
+    /// <summary>
+    /// Populates the JSON values onto the target object.
+    /// </summary>
+    /// <param name="reader">The <see cref="TextReader"/> that contains the JSON structure to reader values from.</param>
+    /// <param name="target">The target object to populate values onto.</param>
+    public void Populate(TextReader reader, object target)
+    {
+      Populate(new JsonTextReader(reader), target);
+    }
+
+    /// <summary>
+    /// Populates the JSON values onto the target object.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> that contains the JSON structure to reader values from.</param>
+    /// <param name="target">The target object to populate values onto.</param>
+    public void Populate(JsonReader reader, object target)
+    {
+      PopulateInternal(reader, target);
+    }
+
+    internal virtual void PopulateInternal(JsonReader reader, object target)
+    {
+      ValidationUtils.ArgumentNotNull(reader, "reader");
+      ValidationUtils.ArgumentNotNull(target, "target");
+
+      JsonSerializerInternalReader serializerReader = new JsonSerializerInternalReader(this);
+      serializerReader.Populate(reader, target);
+    }
+
+    /// <summary>
+    /// Deserializes the Json structure contained by the specified <see cref="JsonReader"/>.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> that contains the JSON structure to deserialize.</param>
+    /// <returns>The <see cref="Object"/> being deserialized.</returns>
+    public object Deserialize(JsonReader reader)
+    {
+      return Deserialize(reader, null);
+    }
+
+    /// <summary>
+    /// Deserializes the Json structure contained by the specified <see cref="StringReader"/>
+    /// into an instance of the specified type.
+    /// </summary>
+    /// <param name="reader">The <see cref="TextReader"/> containing the object.</param>
+    /// <param name="objectType">The <see cref="Type"/> of object being deserialized.</param>
+    /// <returns>The instance of <paramref name="objectType"/> being deserialized.</returns>
+    public object Deserialize(TextReader reader, Type objectType)
+    {
+      return Deserialize(new JsonTextReader(reader), objectType);
+    }
+
+    /// <summary>
+    /// Deserializes the Json structure contained by the specified <see cref="JsonReader"/>
+    /// into an instance of the specified type.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> containing the object.</param>
+    /// <typeparam name="T">The type of the object to deserialize.</typeparam>
+    /// <returns>The instance of <typeparamref name="T"/> being deserialized.</returns>
+    public T Deserialize<T>(JsonReader reader)
+    {
+      return (T)Deserialize(reader, typeof(T));
+    }
+
+    /// <summary>
+    /// Deserializes the Json structure contained by the specified <see cref="JsonReader"/>
+    /// into an instance of the specified type.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> containing the object.</param>
+    /// <param name="objectType">The <see cref="Type"/> of object being deserialized.</param>
+    /// <returns>The instance of <paramref name="objectType"/> being deserialized.</returns>
+    public object Deserialize(JsonReader reader, Type objectType)
+    {
+      return DeserializeInternal(reader, objectType);
+    }
+
+    internal virtual object DeserializeInternal(JsonReader reader, Type objectType)
+    {
+      ValidationUtils.ArgumentNotNull(reader, "reader");
+
+      // set serialization options onto reader
+      CultureInfo previousCulture = null;
+      if (_culture != null && reader.Culture != _culture)
+      {
+        previousCulture = reader.Culture;
+        reader.Culture = _culture;
+      }
+      DateTimeZoneHandling? previousDateTimeZoneHandling = null;
+      if (_dateTimeZoneHandling != null && reader.DateTimeZoneHandling != _dateTimeZoneHandling)
+      {
+        previousDateTimeZoneHandling = reader.DateTimeZoneHandling;
+        reader.DateTimeZoneHandling = _dateTimeZoneHandling.Value;
+      }
+      DateParseHandling? previousDateParseHandling = null;
+      if (_dateParseHandling != null && reader.DateTimeZoneHandling != _dateTimeZoneHandling)
+      {
+        previousDateParseHandling = reader.DateParseHandling;
+        reader.DateParseHandling = _dateParseHandling.Value;
+      }
+      int? previousMaxDepth = null;
+      if (_maxDepthSet && reader.MaxDepth != _maxDepth)
+      {
+        previousMaxDepth = reader.MaxDepth;
+        reader.MaxDepth = _maxDepth;
+      }
+
+      JsonSerializerInternalReader serializerReader = new JsonSerializerInternalReader(this);
+      object value = serializerReader.Deserialize(reader, objectType, CheckAdditionalContent);
+
+      // reset reader back to previous options
+      if (previousCulture != null)
+        reader.Culture = previousCulture;
+      if (previousDateTimeZoneHandling != null)
+        reader.DateTimeZoneHandling = previousDateTimeZoneHandling.Value;
+      if (previousDateParseHandling != null)
+        reader.DateParseHandling = previousDateParseHandling.Value;
+      if (_maxDepthSet)
+        reader.MaxDepth = previousMaxDepth;
+
+      return value;
+    }
+
+    /// <summary>
+    /// Serializes the specified <see cref="Object"/> and writes the Json structure
+    /// to a <c>Stream</c> using the specified <see cref="TextWriter"/>. 
+    /// </summary>
+    /// <param name="textWriter">The <see cref="TextWriter"/> used to write the Json structure.</param>
+    /// <param name="value">The <see cref="Object"/> to serialize.</param>
+    public void Serialize(TextWriter textWriter, object value)
+    {
+      Serialize(new JsonTextWriter(textWriter), value);
+    }
+
+    /// <summary>
+    /// Serializes the specified <see cref="Object"/> and writes the Json structure
+    /// to a <c>Stream</c> using the specified <see cref="JsonWriter"/>. 
+    /// </summary>
+    /// <param name="jsonWriter">The <see cref="JsonWriter"/> used to write the Json structure.</param>
+    /// <param name="value">The <see cref="Object"/> to serialize.</param>
+    public void Serialize(JsonWriter jsonWriter, object value)
+    {
+      SerializeInternal(jsonWriter, value);
+    }
+
+    internal virtual void SerializeInternal(JsonWriter jsonWriter, object value)
+    {
+      ValidationUtils.ArgumentNotNull(jsonWriter, "jsonWriter");
+
+      // set serialization options onto writer
+      Formatting? previousFormatting = null;
+      if (_formatting != null && jsonWriter.Formatting != _formatting)
+      {
+        previousFormatting = jsonWriter.Formatting;
+        jsonWriter.Formatting = _formatting.Value;
+      }
+      DateFormatHandling? previousDateFormatHandling = null;
+      if (_dateFormatHandling != null && jsonWriter.DateFormatHandling != _dateFormatHandling)
+      {
+        previousDateFormatHandling = jsonWriter.DateFormatHandling;
+        jsonWriter.DateFormatHandling = _dateFormatHandling.Value;
+      }
+      DateTimeZoneHandling? previousDateTimeZoneHandling = null;
+      if (_dateTimeZoneHandling != null && jsonWriter.DateTimeZoneHandling != _dateTimeZoneHandling)
+      {
+        previousDateTimeZoneHandling = jsonWriter.DateTimeZoneHandling;
+        jsonWriter.DateTimeZoneHandling = _dateTimeZoneHandling.Value;
+      }
+      
+      JsonSerializerInternalWriter serializerWriter = new JsonSerializerInternalWriter(this);
+      serializerWriter.Serialize(jsonWriter, value);
+
+      // reset writer back to previous options
+      if (previousFormatting != null)
+        jsonWriter.Formatting = previousFormatting.Value;
+      if (previousDateFormatHandling != null)
+        jsonWriter.DateFormatHandling = previousDateFormatHandling.Value;
+      if (previousDateTimeZoneHandling != null)
+        jsonWriter.DateTimeZoneHandling = previousDateTimeZoneHandling.Value;
+    }
+
+    internal JsonConverter GetMatchingConverter(Type type)
+    {
+      return GetMatchingConverter(_converters, type);
+    }
+
+    internal static JsonConverter GetMatchingConverter(IList<JsonConverter> converters, Type objectType)
+    {
+#if DEBUG
+      ValidationUtils.ArgumentNotNull(objectType, "objectType");
+#endif
+
+      if (converters != null)
+      {
+        for (int i = 0; i < converters.Count; i++)
+        {
+          JsonConverter converter = converters[i];
+
+          if (converter.CanConvert(objectType))
+            return converter;
+        }
+      }
+
+      return null;
+    }
+
+    internal void OnError(ErrorEventArgs e)
+    {
+      EventHandler<ErrorEventArgs> error = Error;
+      if (error != null)
+        error(this, e);
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonSerializerSettings.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonSerializerSettings.cs
index 6537c66..43deb5c 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonSerializerSettings.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonSerializerSettings.cs
@@ -1,136 +1,255 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.Serialization.Formatters;
-using System.Text;
-using Newtonsoft.Json.Serialization;
-using Newtonsoft.Json.Utilities;
-using System.Runtime.Serialization;
-
-namespace Newtonsoft.Json
-{
-  /// <summary>
-  /// Specifies the settings on a <see cref="JsonSerializer"/> object.
-  /// </summary>
-  public class JsonSerializerSettings
-  {
-    internal const ReferenceLoopHandling DefaultReferenceLoopHandling = ReferenceLoopHandling.Error;
-    internal const MissingMemberHandling DefaultMissingMemberHandling = MissingMemberHandling.Ignore;
-    internal const NullValueHandling DefaultNullValueHandling = NullValueHandling.Include;
-    internal const DefaultValueHandling DefaultDefaultValueHandling = DefaultValueHandling.Include;
-    internal const ObjectCreationHandling DefaultObjectCreationHandling = ObjectCreationHandling.Auto;
-    internal const PreserveReferencesHandling DefaultPreserveReferencesHandling = PreserveReferencesHandling.None;
-    internal const ConstructorHandling DefaultConstructorHandling = ConstructorHandling.Default;
-    internal const TypeNameHandling DefaultTypeNameHandling = TypeNameHandling.None;
-    internal const FormatterAssemblyStyle DefaultTypeNameAssemblyFormat = FormatterAssemblyStyle.Simple;
-    internal static readonly StreamingContext DefaultContext = new StreamingContext();
-
-    /// <summary>
-    /// Gets or sets how reference loops (e.g. a class referencing itself) is handled.
-    /// </summary>
-    /// <value>Reference loop handling.</value>
-    public ReferenceLoopHandling ReferenceLoopHandling { get; set; }
-
-    /// <summary>
-    /// Gets or sets how missing members (e.g. JSON contains a property that isn't a member on the object) are handled during deserialization.
-    /// </summary>
-    /// <value>Missing member handling.</value>
-    public MissingMemberHandling MissingMemberHandling { get; set; }
-
-    /// <summary>
-    /// Gets or sets how objects are created during deserialization.
-    /// </summary>
-    /// <value>The object creation handling.</value>
-    public ObjectCreationHandling ObjectCreationHandling { get; set; }
-
-    /// <summary>
-    /// Gets or sets how null values are handled during serialization and deserialization.
-    /// </summary>
-    /// <value>Null value handling.</value>
-    public NullValueHandling NullValueHandling { get; set; }
-
-    /// <summary>
-    /// Gets or sets how null default are handled during serialization and deserialization.
-    /// </summary>
-    /// <value>The default value handling.</value>
-    public DefaultValueHandling DefaultValueHandling { get; set; }
-
-    /// <summary>
-    /// Gets or sets a collection <see cref="JsonConverter"/> that will be used during serialization.
-    /// </summary>
-    /// <value>The converters.</value>
-    public IList<JsonConverter> Converters { get; set; }
-
-    /// <summary>
-    /// Gets or sets how object references are preserved by the serializer.
-    /// </summary>
-    /// <value>The preserve references handling.</value>
-    public PreserveReferencesHandling PreserveReferencesHandling { get; set; }
-
-    /// <summary>
-    /// Gets or sets how type name writing and reading is handled by the serializer.
-    /// </summary>
-    /// <value>The type name handling.</value>
-    public TypeNameHandling TypeNameHandling { get; set; }
-
-    /// <summary>
-    /// Gets or sets how a type name assembly is written and resolved by the serializer.
-    /// </summary>
-    /// <value>The type name assembly format.</value>
-    public FormatterAssemblyStyle TypeNameAssemblyFormat { get; set; }
-
-    /// <summary>
-    /// Gets or sets how constructors are used during deserialization.
-    /// </summary>
-    /// <value>The constructor handling.</value>
-    public ConstructorHandling ConstructorHandling { get; set; }
-
-    /// <summary>
-    /// Gets or sets the contract resolver used by the serializer when
-    /// serializing .NET objects to JSON and vice versa.
-    /// </summary>
-    /// <value>The contract resolver.</value>
-    public IContractResolver ContractResolver { get; set; }
-
-    /// <summary>
-    /// Gets or sets the <see cref="IReferenceResolver"/> used by the serializer when resolving references.
-    /// </summary>
-    /// <value>The reference resolver.</value>
-    public IReferenceResolver ReferenceResolver { get; set; }
-
-    /// <summary>
-    /// Gets or sets the <see cref="SerializationBinder"/> used by the serializer when resolving type names.
-    /// </summary>
-    /// <value>The binder.</value>
-    public SerializationBinder Binder { get; set; }
-
-    /// <summary>
-    /// Gets or sets the error handler called during serialization and deserialization.
-    /// </summary>
-    /// <value>The error handler called during serialization and deserialization.</value>
-    public EventHandler<ErrorEventArgs> Error { get; set; }
-
-    /// <summary>
-    /// Gets or sets the <see cref="StreamingContext"/> used by the serializer when invoking serialization callback methods.
-    /// </summary>
-    /// <value>The context.</value>
-    public StreamingContext Context { get; set; }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonSerializerSettings"/> class.
-    /// </summary>
-    public JsonSerializerSettings()
-    {
-      ReferenceLoopHandling = DefaultReferenceLoopHandling;
-      MissingMemberHandling = DefaultMissingMemberHandling;
-      ObjectCreationHandling = DefaultObjectCreationHandling;
-      NullValueHandling = DefaultNullValueHandling;
-      DefaultValueHandling = DefaultDefaultValueHandling;
-      PreserveReferencesHandling = DefaultPreserveReferencesHandling;
-      TypeNameHandling = DefaultTypeNameHandling;
-      TypeNameAssemblyFormat = DefaultTypeNameAssemblyFormat;
-      Context = DefaultContext;
-      Converters = new List<JsonConverter>();
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Runtime.Serialization.Formatters;
+using Newtonsoft.Json.Serialization;
+using System.Runtime.Serialization;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Specifies the settings on a <see cref="JsonSerializer"/> object.
+  /// </summary>
+  public class JsonSerializerSettings
+  {
+    internal const ReferenceLoopHandling DefaultReferenceLoopHandling = ReferenceLoopHandling.Error;
+    internal const MissingMemberHandling DefaultMissingMemberHandling = MissingMemberHandling.Ignore;
+    internal const NullValueHandling DefaultNullValueHandling = NullValueHandling.Include;
+    internal const DefaultValueHandling DefaultDefaultValueHandling = DefaultValueHandling.Include;
+    internal const ObjectCreationHandling DefaultObjectCreationHandling = ObjectCreationHandling.Auto;
+    internal const PreserveReferencesHandling DefaultPreserveReferencesHandling = PreserveReferencesHandling.None;
+    internal const ConstructorHandling DefaultConstructorHandling = ConstructorHandling.Default;
+    internal const TypeNameHandling DefaultTypeNameHandling = TypeNameHandling.None;
+    internal const FormatterAssemblyStyle DefaultTypeNameAssemblyFormat = FormatterAssemblyStyle.Simple;
+    internal static readonly StreamingContext DefaultContext;
+
+    internal const Formatting DefaultFormatting = Formatting.None;
+    internal const DateFormatHandling DefaultDateFormatHandling = DateFormatHandling.IsoDateFormat;
+    internal const DateTimeZoneHandling DefaultDateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind;
+    internal const DateParseHandling DefaultDateParseHandling = DateParseHandling.DateTime;
+    internal static readonly CultureInfo DefaultCulture;
+    internal const bool DefaultCheckAdditionalContent = false;
+
+    internal Formatting? _formatting;
+    internal DateFormatHandling? _dateFormatHandling;
+    internal DateTimeZoneHandling? _dateTimeZoneHandling;
+    internal DateParseHandling? _dateParseHandling;
+    internal CultureInfo _culture;
+    internal bool? _checkAdditionalContent;
+    internal int? _maxDepth;
+    internal bool _maxDepthSet;
+
+    /// <summary>
+    /// Gets or sets how reference loops (e.g. a class referencing itself) is handled.
+    /// </summary>
+    /// <value>Reference loop handling.</value>
+    public ReferenceLoopHandling ReferenceLoopHandling { get; set; }
+
+    /// <summary>
+    /// Gets or sets how missing members (e.g. JSON contains a property that isn't a member on the object) are handled during deserialization.
+    /// </summary>
+    /// <value>Missing member handling.</value>
+    public MissingMemberHandling MissingMemberHandling { get; set; }
+
+    /// <summary>
+    /// Gets or sets how objects are created during deserialization.
+    /// </summary>
+    /// <value>The object creation handling.</value>
+    public ObjectCreationHandling ObjectCreationHandling { get; set; }
+
+    /// <summary>
+    /// Gets or sets how null values are handled during serialization and deserialization.
+    /// </summary>
+    /// <value>Null value handling.</value>
+    public NullValueHandling NullValueHandling { get; set; }
+
+    /// <summary>
+    /// Gets or sets how null default are handled during serialization and deserialization.
+    /// </summary>
+    /// <value>The default value handling.</value>
+    public DefaultValueHandling DefaultValueHandling { get; set; }
+
+    /// <summary>
+    /// Gets or sets a collection <see cref="JsonConverter"/> that will be used during serialization.
+    /// </summary>
+    /// <value>The converters.</value>
+    public IList<JsonConverter> Converters { get; set; }
+
+    /// <summary>
+    /// Gets or sets how object references are preserved by the serializer.
+    /// </summary>
+    /// <value>The preserve references handling.</value>
+    public PreserveReferencesHandling PreserveReferencesHandling { get; set; }
+
+    /// <summary>
+    /// Gets or sets how type name writing and reading is handled by the serializer.
+    /// </summary>
+    /// <value>The type name handling.</value>
+    public TypeNameHandling TypeNameHandling { get; set; }
+
+    /// <summary>
+    /// Gets or sets how a type name assembly is written and resolved by the serializer.
+    /// </summary>
+    /// <value>The type name assembly format.</value>
+    public FormatterAssemblyStyle TypeNameAssemblyFormat { get; set; }
+
+    /// <summary>
+    /// Gets or sets how constructors are used during deserialization.
+    /// </summary>
+    /// <value>The constructor handling.</value>
+    public ConstructorHandling ConstructorHandling { get; set; }
+
+    /// <summary>
+    /// Gets or sets the contract resolver used by the serializer when
+    /// serializing .NET objects to JSON and vice versa.
+    /// </summary>
+    /// <value>The contract resolver.</value>
+    public IContractResolver ContractResolver { get; set; }
+
+    /// <summary>
+    /// Gets or sets the <see cref="IReferenceResolver"/> used by the serializer when resolving references.
+    /// </summary>
+    /// <value>The reference resolver.</value>
+    public IReferenceResolver ReferenceResolver { get; set; }
+
+    /// <summary>
+    /// Gets or sets the <see cref="SerializationBinder"/> used by the serializer when resolving type names.
+    /// </summary>
+    /// <value>The binder.</value>
+    public SerializationBinder Binder { get; set; }
+
+    /// <summary>
+    /// Gets or sets the error handler called during serialization and deserialization.
+    /// </summary>
+    /// <value>The error handler called during serialization and deserialization.</value>
+    public EventHandler<ErrorEventArgs> Error { get; set; }
+
+    /// <summary>
+    /// Gets or sets the <see cref="StreamingContext"/> used by the serializer when invoking serialization callback methods.
+    /// </summary>
+    /// <value>The context.</value>
+    public StreamingContext Context { get; set; }
+
+    /// <summary>
+    /// Gets or sets the maximum depth allowed when reading JSON. Reading past this depth will throw a <see cref="JsonReaderException"/>.
+    /// </summary>
+    public int? MaxDepth
+    {
+      get { return _maxDepth; }
+      set
+      {
+        if (value <= 0)
+          throw new ArgumentException("Value must be positive.", "value");
+
+        _maxDepth = value;
+        _maxDepthSet = true;
+      }
+    }
+
+    /// <summary>
+    /// Indicates how JSON text output is formatted.
+    /// </summary>
+    public Formatting Formatting
+    {
+      get { return _formatting ?? DefaultFormatting; }
+      set { _formatting = value; }
+    }
+
+    /// <summary>
+    /// Get or set how dates are written to JSON text.
+    /// </summary>
+    public DateFormatHandling DateFormatHandling
+    {
+      get { return _dateFormatHandling ?? DefaultDateFormatHandling; }
+      set { _dateFormatHandling = value; }
+    }
+
+    /// <summary>
+    /// Get or set how <see cref="DateTime"/> time zones are handling during serialization and deserialization.
+    /// </summary>
+    public DateTimeZoneHandling DateTimeZoneHandling
+    {
+      get { return _dateTimeZoneHandling ?? DefaultDateTimeZoneHandling; }
+      set { _dateTimeZoneHandling = value; }
+    }
+
+    /// <summary>
+    /// Get or set how date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed when reading JSON.
+    /// </summary>
+    public DateParseHandling DateParseHandling
+    {
+      get { return _dateParseHandling ?? DefaultDateParseHandling; }
+      set { _dateParseHandling = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets the culture used when reading JSON. Defaults to <see cref="CultureInfo.InvariantCulture"/>.
+    /// </summary>
+    public CultureInfo Culture
+    {
+      get { return _culture ?? DefaultCulture; }
+      set { _culture = value; }
+    }
+
+    /// <summary>
+    /// Gets a value indicating whether there will be a check for additional content after deserializing an object.
+    /// </summary>
+    /// <value>
+    /// 	<c>true</c> if there will be a check for additional content after deserializing an object; otherwise, <c>false</c>.
+    /// </value>
+    public bool CheckAdditionalContent
+    {
+      get { return _checkAdditionalContent ?? DefaultCheckAdditionalContent; }
+      set { _checkAdditionalContent = value; }
+    }
+
+    static JsonSerializerSettings()
+    {
+      DefaultContext = new StreamingContext();
+      DefaultCulture = CultureInfo.InvariantCulture;
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonSerializerSettings"/> class.
+    /// </summary>
+    public JsonSerializerSettings()
+    {
+      ReferenceLoopHandling = DefaultReferenceLoopHandling;
+      MissingMemberHandling = DefaultMissingMemberHandling;
+      ObjectCreationHandling = DefaultObjectCreationHandling;
+      NullValueHandling = DefaultNullValueHandling;
+      DefaultValueHandling = DefaultDefaultValueHandling;
+      PreserveReferencesHandling = DefaultPreserveReferencesHandling;
+      TypeNameHandling = DefaultTypeNameHandling;
+      TypeNameAssemblyFormat = DefaultTypeNameAssemblyFormat;
+      Context = DefaultContext;
+
+      Converters = new List<JsonConverter>();
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonTextReader.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonTextReader.cs
index 9121732..ef8ffbc 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonTextReader.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonTextReader.cs
@@ -1,938 +1,1633 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.IO;
-using System.Xml;
-using System.Globalization;
-using Newtonsoft.Json.Utilities;
-
-namespace Newtonsoft.Json
-{
-  /// <summary>
-  /// Represents a reader that provides fast, non-cached, forward-only access to serialized Json data.
-  /// </summary>
-  public class JsonTextReader : JsonReader, IJsonLineInfo
-  {
-    private enum ReadType
-    {
-      Read,
-      ReadAsBytes
-    }
-
-    private readonly TextReader _reader;
-    private readonly StringBuffer _buffer;
-    private char? _lastChar;
-    private int _currentLinePosition;
-    private int _currentLineNumber;
-    private bool _end;
-    private ReadType _readType;
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonReader"/> class with the specified <see cref="TextReader"/>.
-    /// </summary>
-    /// <param name="reader">The <c>TextReader</c> containing the XML data to read.</param>
-    public JsonTextReader(TextReader reader)
-    {
-      if (reader == null)
-        throw new ArgumentNullException("reader");
-
-      _reader = reader;
-      _buffer = new StringBuffer(4096);
-      _currentLineNumber = 1;
-    }
-
-    private void ParseString(char quote)
-    {
-      ReadStringIntoBuffer(quote);
-
-      if (_readType == ReadType.ReadAsBytes)
-      {
-        byte[] data;
-        if (_buffer.Position == 0)
-        {
-          data = new byte[0];
-        }
-        else
-        {
-          data = Convert.FromBase64CharArray(_buffer.GetInternalBuffer(), 0, _buffer.Position);
-          _buffer.Position = 0;
-        }
-
-        SetToken(JsonToken.Bytes, data);
-      }
-      else
-      {
-        string text = _buffer.ToString();
-        _buffer.Position = 0;
-
-        if (text.StartsWith("/Date(", StringComparison.Ordinal) && text.EndsWith(")/", StringComparison.Ordinal))
-        {
-          ParseDate(text);
-        }
-        else
-        {
-          SetToken(JsonToken.String, text);
-          QuoteChar = quote;
-        } 
-      }
-    }
-
-    private void ReadStringIntoBuffer(char quote)
-    {
-      while (true)
-      {
-        char currentChar = MoveNext();
-
-        switch (currentChar)
-        {
-          case '\0':
-            if (_end)
-              throw CreateJsonReaderException("Unterminated string. Expected delimiter: {0}. Line {1}, position {2}.", quote, _currentLineNumber, _currentLinePosition);
-
-            _buffer.Append('\0');
-            break;
-          case '\\':
-            if ((currentChar = MoveNext()) != '\0' || !_end)
-            {
-              switch (currentChar)
-              {
-                case 'b':
-                  _buffer.Append('\b');
-                  break;
-                case 't':
-                  _buffer.Append('\t');
-                  break;
-                case 'n':
-                  _buffer.Append('\n');
-                  break;
-                case 'f':
-                  _buffer.Append('\f');
-                  break;
-                case 'r':
-                  _buffer.Append('\r');
-                  break;
-                case '\\':
-                  _buffer.Append('\\');
-                  break;
-                case '"':
-                case '\'':
-                case '/':
-                  _buffer.Append(currentChar);
-                  break;
-                case 'u':
-                  char[] hexValues = new char[4];
-                  for (int i = 0; i < hexValues.Length; i++)
-                  {
-                    if ((currentChar = MoveNext()) != '\0' || !_end)
-                      hexValues[i] = currentChar;
-                    else
-                      throw CreateJsonReaderException("Unexpected end while parsing unicode character. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
-                  }
-
-                  char hexChar = Convert.ToChar(int.Parse(new string(hexValues), NumberStyles.HexNumber, NumberFormatInfo.InvariantInfo));
-                  _buffer.Append(hexChar);
-                  break;
-                default:
-                  throw CreateJsonReaderException("Bad JSON escape sequence: {0}. Line {1}, position {2}.", @"\" + currentChar, _currentLineNumber, _currentLinePosition);
-              }
-            }
-            else
-            {
-              throw CreateJsonReaderException("Unterminated string. Expected delimiter: {0}. Line {1}, position {2}.", quote, _currentLineNumber, _currentLinePosition);
-            }
-            break;
-          case '"':
-          case '\'':
-            if (currentChar == quote)
-            {
-              return;
-            }
-            else
-            {
-              _buffer.Append(currentChar);
-            }
-            break;
-          default:
-            _buffer.Append(currentChar);
-            break;
-        }
-      }
-    }
-
-    private JsonReaderException CreateJsonReaderException(string format, params object[] args)
-    {
-      string message = format.FormatWith(CultureInfo.InvariantCulture, args);
-      return new JsonReaderException(message, null, _currentLineNumber, _currentLinePosition);
-    }
-
-    private void ParseDate(string text)
-    {
-      string value = text.Substring(6, text.Length - 8);
-      DateTimeKind kind = DateTimeKind.Utc;
-
-      int index = value.IndexOf('+', 1);
-
-      if (index == -1)
-        index = value.IndexOf('-', 1);
-
-      if (index != -1)
-      {
-        kind = DateTimeKind.Local;
-        value = value.Substring(0, index);
-      }
-
-      long javaScriptTicks = long.Parse(value, NumberStyles.Integer, CultureInfo.InvariantCulture);
-      DateTime utcDateTime = JsonConvert.ConvertJavaScriptTicksToDateTime(javaScriptTicks);
-      DateTime dateTime;
-
-      switch (kind)
-      {
-        case DateTimeKind.Unspecified:
-          dateTime = DateTime.SpecifyKind(utcDateTime.ToLocalTime(), DateTimeKind.Unspecified);
-          break;
-        case DateTimeKind.Local:
-          dateTime = utcDateTime.ToLocalTime();
-          break;
-        default:
-          dateTime = utcDateTime;
-          break;
-      }
-
-      SetToken(JsonToken.Date, dateTime);
-    }
-
-    private const int LineFeedValue = StringUtils.LineFeed;
-    private const int CarriageReturnValue = StringUtils.CarriageReturn;
-
-    private char MoveNext()
-    {
-      int value = _reader.Read();
-
-      switch (value)
-      {
-        case -1:
-          _end = true;
-          return '\0';
-        case CarriageReturnValue:
-          if (_reader.Peek() == LineFeedValue)
-            _reader.Read();
-
-          _currentLineNumber++;
-          _currentLinePosition = 0;
-          break;
-        case LineFeedValue:
-          _currentLineNumber++;
-          _currentLinePosition = 0;
-          break;
-        default:
-          _currentLinePosition++;
-          break;
-      }
-
-      return (char)value;
-    }
-
-    private bool HasNext()
-    {
-      return (_reader.Peek() != -1);
-    }
-
-    private int PeekNext()
-    {
-      return _reader.Peek();
-    }
-
-    /// <summary>
-    /// Reads the next JSON token from the stream.
-    /// </summary>
-    /// <returns>
-    /// true if the next token was read successfully; false if there are no more tokens to read.
-    /// </returns>
-    public override bool Read()
-    {
-      _readType = ReadType.Read;
-      return ReadInternal();
-    }
-
-    /// <summary>
-    /// Reads the next JSON token from the stream as a <see cref="T:Byte[]"/>.
-    /// </summary>
-    /// <returns>
-    /// A <see cref="T:Byte[]"/> or a null reference if the next JSON token is null.
-    /// </returns>
-    public override byte[] ReadAsBytes()
-    {
-      _readType = ReadType.ReadAsBytes;
-      if (!ReadInternal())
-        throw CreateJsonReaderException("Unexpected end when reading bytes: Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
-
-      if (TokenType == JsonToken.Null)
-        return null;
-      if (TokenType == JsonToken.Bytes)
-        return (byte[]) Value;
-
-      throw CreateJsonReaderException("Unexpected token when reading bytes: {0}. Line {1}, position {2}.", TokenType, _currentLineNumber, _currentLinePosition);
-    }
-
-    private bool ReadInternal()
-    {
-      while (true)
-      {
-        char currentChar;
-        if (_lastChar != null)
-        {
-          currentChar = _lastChar.Value;
-          _lastChar = null;
-        }
-        else
-        {
-          currentChar = MoveNext();
-        }
-
-        if (currentChar == '\0' && _end)
-          return false;
-
-        switch (CurrentState)
-        {
-          case State.Start:
-          case State.Property:
-          case State.Array:
-          case State.ArrayStart:
-          case State.Constructor:
-          case State.ConstructorStart:
-            return ParseValue(currentChar);
-          case State.Complete:
-            break;
-          case State.Object:
-          case State.ObjectStart:
-            return ParseObject(currentChar);
-          case State.PostValue:
-            // returns true if it hits
-            // end of object or array
-            if (ParsePostValue(currentChar))
-              return true;
-            break;
-          case State.Closed:
-            break;
-          case State.Error:
-            break;
-          default:
-            throw CreateJsonReaderException("Unexpected state: {0}. Line {1}, position {2}.", CurrentState, _currentLineNumber, _currentLinePosition);
-        }
-      }
-    }
-
-    private bool ParsePostValue(char currentChar)
-    {
-      do
-      {
-        switch (currentChar)
-        {
-          case '}':
-            SetToken(JsonToken.EndObject);
-            return true;
-          case ']':
-            SetToken(JsonToken.EndArray);
-            return true;
-          case ')':
-            SetToken(JsonToken.EndConstructor);
-            return true;
-          case '/':
-            ParseComment();
-            return true;
-          case ',':
-            // finished parsing
-            SetStateBasedOnCurrent();
-            return false;
-          case ' ':
-          case StringUtils.Tab:
-          case StringUtils.LineFeed:
-          case StringUtils.CarriageReturn:
-            // eat
-            break;
-          default:
-            if (char.IsWhiteSpace(currentChar))
-            {
-              // eat
-            }
-            else
-            {
-              throw CreateJsonReaderException("After parsing a value an unexpected character was encountered: {0}. Line {1}, position {2}.", currentChar, _currentLineNumber, _currentLinePosition);
-            }
-            break;
-        }
-      } while ((currentChar = MoveNext()) != '\0' || !_end);
-
-      return false;
-    }
-
-    private bool ParseObject(char currentChar)
-    {
-      do
-      {
-        switch (currentChar)
-        {
-          case '}':
-            SetToken(JsonToken.EndObject);
-            return true;
-          case '/':
-            ParseComment();
-            return true;
-          case ' ':
-          case StringUtils.Tab:
-          case StringUtils.LineFeed:
-          case StringUtils.CarriageReturn:
-            // eat
-            break;
-          default:
-            if (char.IsWhiteSpace(currentChar))
-            {
-              // eat
-            }
-            else
-            {
-              return ParseProperty(currentChar);
-            }
-            break;
-        }
-      } while ((currentChar = MoveNext()) != '\0' || !_end);
-
-      return false;
-    }
-
-    private bool ParseProperty(char firstChar)
-    {
-      char currentChar = firstChar;
-      char quoteChar;
-
-      if (ValidIdentifierChar(currentChar))
-      {
-        quoteChar = '\0';
-        currentChar = ParseUnquotedProperty(currentChar);
-      }
-      else if (currentChar == '"' || currentChar == '\'')
-      {
-        quoteChar = currentChar;
-        ReadStringIntoBuffer(quoteChar);
-        currentChar = MoveNext();
-      }
-      else
-      {
-        throw CreateJsonReaderException("Invalid property identifier character: {0}. Line {1}, position {2}.", currentChar, _currentLineNumber, _currentLinePosition);
-      }
-
-      if (currentChar != ':')
-      {
-        currentChar = MoveNext();
-
-        // finished property. skip any whitespace and move to colon
-        EatWhitespace(currentChar, false, out currentChar);
-
-        if (currentChar != ':')
-          throw CreateJsonReaderException("Invalid character after parsing property name. Expected ':' but got: {0}. Line {1}, position {2}.", currentChar, _currentLineNumber, _currentLinePosition);
-      }
-
-      SetToken(JsonToken.PropertyName, _buffer.ToString());
-      QuoteChar = quoteChar;
-      _buffer.Position = 0;
-
-      return true;
-    }
-
-    private bool ValidIdentifierChar(char value)
-    {
-      return (char.IsLetterOrDigit(value) || value == '_' || value == '$');
-    }
-
-    private char ParseUnquotedProperty(char firstChar)
-    {
-      // parse unquoted property name until whitespace or colon
-      _buffer.Append(firstChar);
-
-      char currentChar;
-
-      while ((currentChar = MoveNext()) != '\0' || !_end)
-      {
-        if (char.IsWhiteSpace(currentChar) || currentChar == ':')
-        {
-          return currentChar;
-        }
-        else if (ValidIdentifierChar(currentChar))
-        {
-          _buffer.Append(currentChar);
-        }
-        else
-        {
-          throw CreateJsonReaderException("Invalid JavaScript property identifier character: {0}. Line {1}, position {2}.", currentChar, _currentLineNumber, _currentLinePosition);
-        }
-      }
-
-      throw CreateJsonReaderException("Unexpected end when parsing unquoted property name. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
-    }
-
-    private bool ParseValue(char currentChar)
-    {
-      do
-      {
-        switch (currentChar)
-        {
-          case '"':
-          case '\'':
-            ParseString(currentChar);
-            return true;
-          case 't':
-            ParseTrue();
-            return true;
-          case 'f':
-            ParseFalse();
-            return true;
-          case 'n':
-            if (HasNext())
-            {
-              char next = (char)PeekNext();
-
-              if (next == 'u')
-                ParseNull();
-              else if (next == 'e')
-                ParseConstructor();
-              else
-                throw CreateJsonReaderException("Unexpected character encountered while parsing value: {0}. Line {1}, position {2}.", currentChar, _currentLineNumber, _currentLinePosition);
-            }
-            else
-            {
-              throw CreateJsonReaderException("Unexpected end. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
-            }
-            return true;
-          case 'N':
-            ParseNumberNaN();
-            return true;
-          case 'I':
-            ParseNumberPositiveInfinity();
-            return true;
-          case '-':
-            if (PeekNext() == 'I')
-              ParseNumberNegativeInfinity();
-            else
-              ParseNumber(currentChar);
-            return true;
-          case '/':
-            ParseComment();
-            return true;
-          case 'u':
-            ParseUndefined();
-            return true;
-          case '{':
-            SetToken(JsonToken.StartObject);
-            return true;
-          case '[':
-            SetToken(JsonToken.StartArray);
-            return true;
-          case '}':
-            SetToken(JsonToken.EndObject);
-            return true;
-          case ']':
-            SetToken(JsonToken.EndArray);
-            return true;
-          case ',':
-            SetToken(JsonToken.Undefined);
-            return true;
-          case ')':
-            SetToken(JsonToken.EndConstructor);
-            return true;
-          case ' ':
-          case StringUtils.Tab:
-          case StringUtils.LineFeed:
-          case StringUtils.CarriageReturn:
-            // eat
-            break;
-          default:
-            if (char.IsWhiteSpace(currentChar))
-            {
-              // eat
-            }
-            else if (char.IsNumber(currentChar) || currentChar == '-' || currentChar == '.')
-            {
-              ParseNumber(currentChar);
-              return true;
-            }
-            else
-            {
-              throw CreateJsonReaderException("Unexpected character encountered while parsing value: {0}. Line {1}, position {2}.", currentChar, _currentLineNumber, _currentLinePosition);
-            }
-            break;
-        }
-      } while ((currentChar = MoveNext()) != '\0' || !_end);
-
-      return false;
-    }
-
-    private bool EatWhitespace(char initialChar, bool oneOrMore, out char finalChar)
-    {
-      bool whitespace = false;
-      char currentChar = initialChar;
-      while (currentChar == ' ' || char.IsWhiteSpace(currentChar))
-      {
-        whitespace = true;
-        currentChar = MoveNext();
-      }
-
-      finalChar = currentChar;
-
-      return (!oneOrMore || whitespace);
-    }
-
-    private void ParseConstructor()
-    {
-      if (MatchValue('n', "new", true))
-      {
-        char currentChar = MoveNext();
-
-        if (EatWhitespace(currentChar, true, out currentChar))
-        {
-          while (char.IsLetter(currentChar))
-          {
-            _buffer.Append(currentChar);
-            currentChar = MoveNext();
-          }
-
-          EatWhitespace(currentChar, false, out currentChar);
-
-          if (currentChar != '(')
-            throw CreateJsonReaderException("Unexpected character while parsing constructor: {0}. Line {1}, position {2}.", currentChar, _currentLineNumber, _currentLinePosition);
-
-          string constructorName = _buffer.ToString();
-          _buffer.Position = 0;
-
-          SetToken(JsonToken.StartConstructor, constructorName);
-        }
-      }
-    }
-
-    private void ParseNumber(char firstChar)
-    {
-      char currentChar = firstChar;
-
-      // parse until seperator character or end
-      bool end = false;
-      do
-      {
-        if (IsSeperator(currentChar))
-        {
-          end = true;
-          _lastChar = currentChar;
-        }
-        else
-        {
-          _buffer.Append(currentChar);
-        }
-
-      } while (!end && ((currentChar = MoveNext()) != '\0' || !_end));
-
-      string number = _buffer.ToString();
-      object numberValue;
-      JsonToken numberType;
-
-      if (firstChar == '0' && !number.StartsWith("0.", StringComparison.OrdinalIgnoreCase))
-      {
-        numberValue = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase)
-          ? Convert.ToInt64(number, 16)
-          : Convert.ToInt64(number, 8);
-        numberType = JsonToken.Integer;
-      } 
-      else if (number.IndexOf(".", StringComparison.OrdinalIgnoreCase) != -1 || number.IndexOf("e", StringComparison.OrdinalIgnoreCase) != -1)
-      {
-        numberValue = Convert.ToDouble(number, CultureInfo.InvariantCulture);
-        numberType = JsonToken.Float;
-      }
-      else
-      {
-        try
-        {
-          numberValue = Convert.ToInt64(number, CultureInfo.InvariantCulture);
-        }
-        catch (OverflowException ex)
-        {
-          throw new JsonReaderException("JSON integer {0} is too large or small for an Int64.".FormatWith(CultureInfo.InvariantCulture, number), ex);
-        }
-
-        numberType = JsonToken.Integer;
-      }
-
-      _buffer.Position = 0;
-
-      SetToken(numberType, numberValue);
-    }
-
-    private void ParseComment()
-    {
-      // should have already parsed / character before reaching this method
-
-      char currentChar = MoveNext();
-
-      if (currentChar == '*')
-      {
-        while ((currentChar = MoveNext()) != '\0' || !_end)
-        {
-          if (currentChar == '*')
-          {
-            if ((currentChar = MoveNext()) != '\0' || !_end)
-            {
-              if (currentChar == '/')
-              {
-                break;
-              }
-              else
-              {
-                _buffer.Append('*');
-                _buffer.Append(currentChar);
-              }
-            }
-          }
-          else
-          {
-            _buffer.Append(currentChar);
-          }
-        }
-      }
-      else
-      {
-        throw CreateJsonReaderException("Error parsing comment. Expected: *. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
-      }
-
-      SetToken(JsonToken.Comment, _buffer.ToString());
-
-      _buffer.Position = 0;
-    }
-
-    private bool MatchValue(char firstChar, string value)
-    {
-      char currentChar = firstChar;
-
-      int i = 0;
-      do
-      {
-        if (currentChar != value[i])
-        {
-          break;
-        }
-        i++;
-      }
-      while (i < value.Length && ((currentChar = MoveNext()) != '\0' || !_end));
-
-      return (i == value.Length);
-    }
-
-    private bool MatchValue(char firstChar, string value, bool noTrailingNonSeperatorCharacters)
-    {
-      // will match value and then move to the next character, checking that it is a seperator character
-      bool match = MatchValue(firstChar, value);
-
-      if (!noTrailingNonSeperatorCharacters)
-      {
-        return match;
-      }
-      else
-      {
-        int c = PeekNext();
-        char next = (c != -1) ? (char) c : '\0';
-        bool matchAndNoTrainingNonSeperatorCharacters = (match && (next == '\0' || IsSeperator(next)));
-
-        return matchAndNoTrainingNonSeperatorCharacters;
-      }
-    }
-
-    private bool IsSeperator(char c)
-    {
-      switch (c)
-      {
-        case '}':
-        case ']':
-        case ',':
-          return true;
-        case '/':
-          // check next character to see if start of a comment
-          return (HasNext() && PeekNext() == '*');
-        case ')':
-          if (CurrentState == State.Constructor || CurrentState == State.ConstructorStart)
-            return true;
-          break;
-        case ' ':
-        case StringUtils.Tab:
-        case StringUtils.LineFeed:
-        case StringUtils.CarriageReturn:
-          return true;
-        default:
-          if (char.IsWhiteSpace(c))
-            return true;
-          break;
-      }
-
-      return false;
-    }
-
-    private void ParseTrue()
-    {
-      // check characters equal 'true'
-      // and that it is followed by either a seperator character
-      // or the text ends
-      if (MatchValue('t', JsonConvert.True, true))
-      {
-        SetToken(JsonToken.Boolean, true);
-      }
-      else
-      {
-        throw CreateJsonReaderException("Error parsing boolean value. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
-      }
-    }
-
-    private void ParseNull()
-    {
-      if (MatchValue('n', JsonConvert.Null, true))
-      {
-        SetToken(JsonToken.Null);
-      }
-      else
-      {
-        throw CreateJsonReaderException("Error parsing null value. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
-      }
-    }
-
-    private void ParseUndefined()
-    {
-      if (MatchValue('u', JsonConvert.Undefined, true))
-      {
-        SetToken(JsonToken.Undefined);
-      }
-      else
-      {
-        throw CreateJsonReaderException("Error parsing undefined value. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
-      }
-    }
-
-    private void ParseFalse()
-    {
-      if (MatchValue('f', JsonConvert.False, true))
-      {
-        SetToken(JsonToken.Boolean, false);
-      }
-      else
-      {
-        throw CreateJsonReaderException("Error parsing boolean value. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
-      }
-    }
-
-    private void ParseNumberNegativeInfinity()
-    {
-      if (MatchValue('-', JsonConvert.NegativeInfinity, true))
-      {
-        SetToken(JsonToken.Float, double.NegativeInfinity);
-      }
-      else
-      {
-        throw CreateJsonReaderException("Error parsing negative infinity value. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
-      }
-    }
-
-    private void ParseNumberPositiveInfinity()
-    {
-      if (MatchValue('I', JsonConvert.PositiveInfinity, true))
-      {
-        SetToken(JsonToken.Float, double.PositiveInfinity);
-      }
-      else
-      {
-        throw CreateJsonReaderException("Error parsing positive infinity value. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
-      }
-    }
-
-    private void ParseNumberNaN()
-    {
-      if (MatchValue('N', JsonConvert.NaN, true))
-      {
-        SetToken(JsonToken.Float, double.NaN);
-      }
-      else
-      {
-        throw CreateJsonReaderException("Error parsing NaN value. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
-      }
-    }
-
-    /// <summary>
-    /// Changes the state to closed. 
-    /// </summary>
-    public override void Close()
-    {
-      base.Close();
-
-      if (_reader != null)
-        _reader.Close();
-
-      if (_buffer != null)
-        _buffer.Clear();
-    }
-
-    /// <summary>
-    /// Gets a value indicating whether the class can return line information.
-    /// </summary>
-    /// <returns>
-    /// 	<c>true</c> if LineNumber and LinePosition can be provided; otherwise, <c>false</c>.
-    /// </returns>
-    public bool HasLineInfo()
-    {
-      return true;
-    }
-
-    /// <summary>
-    /// Gets the current line number.
-    /// </summary>
-    /// <value>
-    /// The current line number or 0 if no line information is available (for example, HasLineInfo returns false).
-    /// </value>
-    public int LineNumber
-    {
-      get
-      {
-        if (CurrentState == State.Start)
-          return 0;
-
-        return _currentLineNumber;
-      }
-    }
-
-    /// <summary>
-    /// Gets the current line position.
-    /// </summary>
-    /// <value>
-    /// The current line position or 0 if no line information is available (for example, HasLineInfo returns false).
-    /// </value>
-    public int LinePosition
-    {
-      get { return _currentLinePosition; }
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Text;
+using System.IO;
+using System.Xml;
+using System.Globalization;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json
+{
+  internal enum ReadType
+  {
+    Read,
+    ReadAsInt32,
+    ReadAsBytes,
+    ReadAsString,
+    ReadAsDecimal,
+    ReadAsDateTime,
+#if !NET20
+    ReadAsDateTimeOffset
+#endif
+  }
+
+  /// <summary>
+  /// Represents a reader that provides fast, non-cached, forward-only access to JSON text data.
+  /// </summary>
+  public class JsonTextReader : JsonReader, IJsonLineInfo
+  {
+    private const char UnicodeReplacementChar = '\uFFFD';
+
+    private readonly TextReader _reader;
+    private char[] _chars;
+    private int _charsUsed;
+    private int _charPos;
+    private int _lineStartPos;
+    private int _lineNumber;
+    private bool _isEndOfFile;
+    private StringBuffer _buffer;
+    private StringReference _stringReference;
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonReader"/> class with the specified <see cref="TextReader"/>.
+    /// </summary>
+    /// <param name="reader">The <c>TextReader</c> containing the XML data to read.</param>
+    public JsonTextReader(TextReader reader)
+    {
+      if (reader == null)
+        throw new ArgumentNullException("reader");
+
+      _reader = reader;
+      _lineNumber = 1;
+      _chars = new char[4097];
+    }
+
+    internal void SetCharBuffer(char[] chars)
+    {
+      _chars = chars;
+    }
+
+    private StringBuffer GetBuffer()
+    {
+      if (_buffer == null)
+      {
+        _buffer = new StringBuffer(4096);
+      }
+      else
+      {
+        _buffer.Position = 0;
+      }
+
+      return _buffer;
+    }
+
+    private void OnNewLine(int pos)
+    {
+      _lineNumber++;
+      _lineStartPos = pos - 1;
+    }
+
+    private void ParseString(char quote)
+    {
+      _charPos++;
+
+      ShiftBufferIfNeeded();
+      ReadStringIntoBuffer(quote);
+
+      if (_readType == ReadType.ReadAsBytes)
+      {
+        byte[] data;
+        if (_stringReference.Length == 0)
+        {
+          data = new byte[0];
+        }
+        else
+        {
+          data = Convert.FromBase64CharArray(_stringReference.Chars, _stringReference.StartIndex, _stringReference.Length);
+        }
+
+        SetToken(JsonToken.Bytes, data);
+      }
+      else if (_readType == ReadType.ReadAsString)
+      {
+        string text = _stringReference.ToString();
+
+        SetToken(JsonToken.String, text);
+        QuoteChar = quote;
+      }
+      else
+      {
+        string text = _stringReference.ToString();
+
+        if (_dateParseHandling != DateParseHandling.None)
+        {
+          if (text.Length > 0)
+          {
+            if (text[0] == '/')
+            {
+              if (text.StartsWith("/Date(", StringComparison.Ordinal) && text.EndsWith(")/", StringComparison.Ordinal))
+              {
+                ParseDateMicrosoft(text);
+                return;
+              }
+            }
+            else if (char.IsDigit(text[0]) && text.Length >= 19 && text.Length <= 40)
+            {
+              if (ParseDateIso(text))
+                return;
+            }
+          }
+        }
+
+        SetToken(JsonToken.String, text);
+        QuoteChar = quote;
+      }
+    }
+
+    private bool ParseDateIso(string text)
+    {
+      const string isoDateFormat = "yyyy-MM-ddTHH:mm:ss.FFFFFFFK";
+
+#if !NET20
+      if (_readType == ReadType.ReadAsDateTimeOffset || (_readType == ReadType.Read && _dateParseHandling == DateParseHandling.DateTimeOffset))
+      {
+        DateTimeOffset dateTimeOffset;
+        if (DateTimeOffset.TryParseExact(text, isoDateFormat, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out dateTimeOffset))
+        {
+          SetToken(JsonToken.Date, dateTimeOffset);
+          return true;
+        }
+      }
+      else
+#endif
+      {
+        DateTime dateTime;
+        if (DateTime.TryParseExact(text, isoDateFormat, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out dateTime))
+        {
+          dateTime = JsonConvert.EnsureDateTime(dateTime, DateTimeZoneHandling);
+
+          SetToken(JsonToken.Date, dateTime);
+          return true;
+        }
+      }
+
+      return false;
+    }
+
+    private void ParseDateMicrosoft(string text)
+    {
+      string value = text.Substring(6, text.Length - 8);
+      DateTimeKind kind = DateTimeKind.Utc;
+
+      int index = value.IndexOf('+', 1);
+
+      if (index == -1)
+        index = value.IndexOf('-', 1);
+
+      TimeSpan offset = TimeSpan.Zero;
+
+      if (index != -1)
+      {
+        kind = DateTimeKind.Local;
+        offset = ReadOffset(value.Substring(index));
+        value = value.Substring(0, index);
+      }
+
+      long javaScriptTicks = long.Parse(value, NumberStyles.Integer, CultureInfo.InvariantCulture);
+
+      DateTime utcDateTime = JsonConvert.ConvertJavaScriptTicksToDateTime(javaScriptTicks);
+
+#if !NET20
+      if (_readType == ReadType.ReadAsDateTimeOffset || (_readType == ReadType.Read && _dateParseHandling == DateParseHandling.DateTimeOffset))
+      {
+        SetToken(JsonToken.Date, new DateTimeOffset(utcDateTime.Add(offset).Ticks, offset));
+      }
+      else
+#endif
+      {
+        DateTime dateTime;
+
+        switch (kind)
+        {
+          case DateTimeKind.Unspecified:
+            dateTime = DateTime.SpecifyKind(utcDateTime.ToLocalTime(), DateTimeKind.Unspecified);
+            break;
+          case DateTimeKind.Local:
+            dateTime = utcDateTime.ToLocalTime();
+            break;
+          default:
+            dateTime = utcDateTime;
+            break;
+        }
+
+        dateTime = JsonConvert.EnsureDateTime(dateTime, DateTimeZoneHandling);
+
+        SetToken(JsonToken.Date, dateTime);
+      }
+    }
+
+    private static void BlockCopyChars(char[] src, int srcOffset, char[] dst, int dstOffset, int count)
+    {
+      const int charByteCount = 2;
+
+      Buffer.BlockCopy(src, srcOffset * charByteCount, dst, dstOffset * charByteCount, count * charByteCount);
+    }
+
+    private void ShiftBufferIfNeeded()
+    {
+      // once in the last 10% of the buffer shift the remainling content to the start to avoid
+      // unnessesarly increasing the buffer size when reading numbers/strings
+      int length = _chars.Length;
+      if (length - _charPos <= length * 0.1)
+      {
+        int count = _charsUsed - _charPos;
+        if (count > 0)
+          BlockCopyChars(_chars, _charPos, _chars, 0, count);
+
+        _lineStartPos -= _charPos;
+        _charPos = 0;
+        _charsUsed = count;
+        _chars[_charsUsed] = '\0';
+      }
+    }
+
+    private int ReadData(bool append)
+    {
+      return ReadData(append, 0);
+    }
+
+    private int ReadData(bool append, int charsRequired)
+    {
+      if (_isEndOfFile)
+        return 0;
+
+      // char buffer is full
+      if (_charsUsed + charsRequired >= _chars.Length - 1)
+      {
+        if (append)
+        {
+          // copy to new array either double the size of the current or big enough to fit required content
+          int newArrayLength = Math.Max(_chars.Length * 2, _charsUsed + charsRequired + 1);
+
+          // increase the size of the buffer
+          char[] dst = new char[newArrayLength];
+
+          BlockCopyChars(_chars, 0, dst, 0, _chars.Length);
+
+          _chars = dst;
+        }
+        else
+        {
+          int remainingCharCount = _charsUsed - _charPos;
+
+          if (remainingCharCount + charsRequired + 1 >= _chars.Length)
+          {
+            // the remaining count plus the required is bigger than the current buffer size
+            char[] dst = new char[remainingCharCount + charsRequired + 1];
+
+            if (remainingCharCount > 0)
+              BlockCopyChars(_chars, _charPos, dst, 0, remainingCharCount);
+
+            _chars = dst;
+          }
+          else
+          {
+            // copy any remaining data to the beginning of the buffer if needed and reset positions
+            if (remainingCharCount > 0)
+              BlockCopyChars(_chars, _charPos, _chars, 0, remainingCharCount);
+          }
+
+          _lineStartPos -= _charPos;
+          _charPos = 0;
+          _charsUsed = remainingCharCount;
+        }
+      }
+
+      int attemptCharReadCount = _chars.Length - _charsUsed - 1;
+
+      int charsRead = _reader.Read(_chars, _charsUsed, attemptCharReadCount);
+
+      _charsUsed += charsRead;
+
+      if (charsRead == 0)
+        _isEndOfFile = true;
+
+      _chars[_charsUsed] = '\0';
+      return charsRead;
+    }
+
+    private bool EnsureChars(int relativePosition, bool append)
+    {
+      if (_charPos + relativePosition >= _charsUsed)
+        return ReadChars(relativePosition, append);
+
+      return true;
+    }
+
+    private bool ReadChars(int relativePosition, bool append)
+    {
+      if (_isEndOfFile)
+        return false;
+
+      int charsRequired = _charPos + relativePosition - _charsUsed + 1;
+
+      int totalCharsRead = 0;
+
+      // it is possible that the TextReader doesn't return all data at once
+      // repeat read until the required text is returned or the reader is out of content
+      do
+      {
+        int charsRead = ReadData(append, charsRequired - totalCharsRead);
+
+        // no more content
+        if (charsRead == 0)
+          break;
+
+        totalCharsRead += charsRead;
+      }
+      while (totalCharsRead < charsRequired);
+
+      if (totalCharsRead < charsRequired)
+        return false;
+      return true;
+    }
+
+    private static TimeSpan ReadOffset(string offsetText)
+    {
+      bool negative = (offsetText[0] == '-');
+
+      int hours = int.Parse(offsetText.Substring(1, 2), NumberStyles.Integer, CultureInfo.InvariantCulture);
+      int minutes = 0;
+      if (offsetText.Length >= 5)
+        minutes = int.Parse(offsetText.Substring(3, 2), NumberStyles.Integer, CultureInfo.InvariantCulture);
+
+      TimeSpan offset = TimeSpan.FromHours(hours) + TimeSpan.FromMinutes(minutes);
+      if (negative)
+        offset = offset.Negate();
+
+      return offset;
+    }
+
+    /// <summary>
+    /// Reads the next JSON token from the stream.
+    /// </summary>
+    /// <returns>
+    /// true if the next token was read successfully; false if there are no more tokens to read.
+    /// </returns>
+    [DebuggerStepThrough]
+    public override bool Read()
+    {
+      _readType = ReadType.Read;
+      if (!ReadInternal())
+      {
+        SetToken(JsonToken.None);
+        return false;
+      }
+
+      return true;
+    }
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="T:Byte[]"/>.
+    /// </summary>
+    /// <returns>
+    /// A <see cref="T:Byte[]"/> or a null reference if the next JSON token is null. This method will return <c>null</c> at the end of an array.
+    /// </returns>
+    public override byte[] ReadAsBytes()
+    {
+      return ReadAsBytesInternal();
+    }
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="Nullable{Decimal}"/>.
+    /// </summary>
+    /// <returns>A <see cref="Nullable{Decimal}"/>. This method will return <c>null</c> at the end of an array.</returns>
+    public override decimal? ReadAsDecimal()
+    {
+      return ReadAsDecimalInternal();
+    }
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="Nullable{Int32}"/>.
+    /// </summary>
+    /// <returns>A <see cref="Nullable{Int32}"/>. This method will return <c>null</c> at the end of an array.</returns>
+    public override int? ReadAsInt32()
+    {
+      return ReadAsInt32Internal();
+    }
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="String"/>.
+    /// </summary>
+    /// <returns>A <see cref="String"/>. This method will return <c>null</c> at the end of an array.</returns>
+    public override string ReadAsString()
+    {
+      return ReadAsStringInternal();
+    }
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="Nullable{DateTime}"/>.
+    /// </summary>
+    /// <returns>A <see cref="String"/>. This method will return <c>null</c> at the end of an array.</returns>
+    public override DateTime? ReadAsDateTime()
+    {
+      return ReadAsDateTimeInternal();
+    }
+
+#if !NET20
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="Nullable{DateTimeOffset}"/>.
+    /// </summary>
+    /// <returns>A <see cref="DateTimeOffset"/>. This method will return <c>null</c> at the end of an array.</returns>
+    public override DateTimeOffset? ReadAsDateTimeOffset()
+    {
+      return ReadAsDateTimeOffsetInternal();
+    }
+#endif
+
+    internal override bool ReadInternal()
+    {
+      while (true)
+      {
+        switch (_currentState)
+        {
+          case State.Start:
+          case State.Property:
+          case State.Array:
+          case State.ArrayStart:
+          case State.Constructor:
+          case State.ConstructorStart:
+            return ParseValue();
+          case State.Complete:
+            break;
+          case State.Object:
+          case State.ObjectStart:
+            return ParseObject();
+          case State.PostValue:
+            // returns true if it hits
+            // end of object or array
+            if (ParsePostValue())
+              return true;
+            break;
+          case State.Finished:
+            if (EnsureChars(0, false))
+            {
+              EatWhitespace(false);
+              if (_isEndOfFile)
+              {
+                return false;
+              }
+              if (_chars[_charPos] == '/')
+              {
+                ParseComment();
+                return true;
+              }
+              else
+              {
+                throw JsonReaderException.Create(this, "Additional text encountered after finished reading JSON content: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos]));
+              }
+            }
+            return false;
+          case State.Closed:
+            break;
+          case State.Error:
+            break;
+          default:
+            throw JsonReaderException.Create(this, "Unexpected state: {0}.".FormatWith(CultureInfo.InvariantCulture, CurrentState));
+        }
+      }
+    }
+
+    private void ReadStringIntoBuffer(char quote)
+    {
+      int charPos = _charPos;
+      int initialPosition = _charPos;
+      int lastWritePosition = _charPos;
+      StringBuffer buffer = null;
+
+      while (true)
+      {
+        switch (_chars[charPos++])
+        {
+          case '\0':
+            if (_charsUsed == charPos - 1)
+            {
+              charPos--;
+
+              if (ReadData(true) == 0)
+              {
+                _charPos = charPos;
+                throw JsonReaderException.Create(this, "Unterminated string. Expected delimiter: {0}.".FormatWith(CultureInfo.InvariantCulture, quote));
+              }
+            }
+            break;
+          case '\\':
+            _charPos = charPos;
+            if (!EnsureChars(0, true))
+            {
+              _charPos = charPos;
+              throw JsonReaderException.Create(this, "Unterminated string. Expected delimiter: {0}.".FormatWith(CultureInfo.InvariantCulture, quote));
+            }
+
+            // start of escape sequence
+            int escapeStartPos = charPos - 1;
+
+            char currentChar = _chars[charPos];
+
+            char writeChar;
+
+            switch (currentChar)
+            {
+              case 'b':
+                charPos++;
+                writeChar = '\b';
+                break;
+              case 't':
+                charPos++;
+                writeChar = '\t';
+                break;
+              case 'n':
+                charPos++;
+                writeChar = '\n';
+                break;
+              case 'f':
+                charPos++;
+                writeChar = '\f';
+                break;
+              case 'r':
+                charPos++;
+                writeChar = '\r';
+                break;
+              case '\\':
+                charPos++;
+                writeChar = '\\';
+                break;
+              case '"':
+              case '\'':
+              case '/':
+                writeChar = currentChar;
+                charPos++;
+                break;
+              case 'u':
+                charPos++;
+                _charPos = charPos;
+                writeChar = ParseUnicode();
+                
+                if (StringUtils.IsLowSurrogate(writeChar))
+                {
+                  // low surrogate with no preceding high surrogate; this char is replaced
+                  writeChar = UnicodeReplacementChar;
+                }
+                else if (StringUtils.IsHighSurrogate(writeChar))
+                {
+                  bool anotherHighSurrogate;
+
+                  // loop for handling situations where there are multiple consecutive high surrogates
+                  do
+                  {
+                    anotherHighSurrogate = false;
+
+                    // potential start of a surrogate pair
+                    if (EnsureChars(2, true) && _chars[_charPos] == '\\' && _chars[_charPos + 1] == 'u')
+                    {
+                      char highSurrogate = writeChar;
+
+                      _charPos += 2;
+                      writeChar = ParseUnicode();
+
+                      if (StringUtils.IsLowSurrogate(writeChar))
+                      {
+                        // a valid surrogate pair!
+                      }
+                      else if (StringUtils.IsHighSurrogate(writeChar))
+                      {
+                        // another high surrogate; replace current and start check over
+                        highSurrogate = UnicodeReplacementChar;
+                        anotherHighSurrogate = true;
+                      }
+                      else
+                      {
+                        // high surrogate not followed by low surrogate; original char is replaced
+                        highSurrogate = UnicodeReplacementChar;
+                      }
+
+                      if (buffer == null)
+                        buffer = GetBuffer();
+
+                      WriteCharToBuffer(buffer, highSurrogate, lastWritePosition, escapeStartPos);
+                      lastWritePosition = _charPos;
+                    }
+                    else
+                    {
+                      // there are not enough remaining chars for the low surrogate or is not follow by unicode sequence
+                      // replace high surrogate and continue on as usual
+                      writeChar = UnicodeReplacementChar;
+                    }
+                  } while (anotherHighSurrogate);
+                }
+
+                charPos = _charPos;
+                break;
+              default:
+                charPos++;
+                _charPos = charPos;
+                throw JsonReaderException.Create(this, "Bad JSON escape sequence: {0}.".FormatWith(CultureInfo.InvariantCulture, @"\" + currentChar));
+            }
+
+            if (buffer == null)
+              buffer = GetBuffer();
+
+            WriteCharToBuffer(buffer, writeChar, lastWritePosition, escapeStartPos);
+
+            lastWritePosition = charPos;
+            break;
+          case StringUtils.CarriageReturn:
+            _charPos = charPos - 1;
+            ProcessCarriageReturn(true);
+            charPos = _charPos;
+            break;
+          case StringUtils.LineFeed:
+            _charPos = charPos - 1;
+            ProcessLineFeed();
+            charPos = _charPos;
+            break;
+          case '"':
+          case '\'':
+            if (_chars[charPos - 1] == quote)
+            {
+              charPos--;
+
+              if (initialPosition == lastWritePosition)
+              {
+                _stringReference = new StringReference(_chars, initialPosition, charPos - initialPosition);
+              }
+              else
+              {
+                if (buffer == null)
+                  buffer = GetBuffer();
+
+                if (charPos > lastWritePosition)
+                  buffer.Append(_chars, lastWritePosition, charPos - lastWritePosition);
+
+                _stringReference = new StringReference(buffer.GetInternalBuffer(), 0, buffer.Position);
+              }
+
+              charPos++;
+              _charPos = charPos;
+              return;
+            }
+            break;
+        }
+      }
+    }
+
+    private void WriteCharToBuffer(StringBuffer buffer, char writeChar, int lastWritePosition, int writeToPosition)
+    {
+      if (writeToPosition > lastWritePosition)
+      {
+        buffer.Append(_chars, lastWritePosition, writeToPosition - lastWritePosition);
+      }
+
+      buffer.Append(writeChar);
+    }
+
+    private char ParseUnicode()
+    {
+      char writeChar;
+      if (EnsureChars(4, true))
+      {
+        string hexValues = new string(_chars, _charPos, 4);
+        char hexChar = Convert.ToChar(int.Parse(hexValues, NumberStyles.HexNumber, NumberFormatInfo.InvariantInfo));
+        writeChar = hexChar;
+
+        _charPos += 4;
+      }
+      else
+      {
+        throw JsonReaderException.Create(this, "Unexpected end while parsing unicode character.");
+      }
+      return writeChar;
+    }
+
+    private void ReadNumberIntoBuffer()
+    {
+      int charPos = _charPos;
+
+      while (true)
+      {
+        switch (_chars[charPos++])
+        {
+          case '\0':
+            if (_charsUsed == charPos - 1)
+            {
+              charPos--;
+              _charPos = charPos;
+              if (ReadData(true) == 0)
+                return;
+            }
+            break;
+          case '-':
+          case '+':
+          case 'a':
+          case 'A':
+          case 'b':
+          case 'B':
+          case 'c':
+          case 'C':
+          case 'd':
+          case 'D':
+          case 'e':
+          case 'E':
+          case 'f':
+          case 'F':
+          case 'x':
+          case 'X':
+          case '.':
+          case '0':
+          case '1':
+          case '2':
+          case '3':
+          case '4':
+          case '5':
+          case '6':
+          case '7':
+          case '8':
+          case '9':
+            break;
+          default:
+            _charPos = charPos - 1;
+            return;
+        }
+      }
+    }
+
+    private void ClearRecentString()
+    {
+      if (_buffer != null)
+        _buffer.Position = 0;
+
+      _stringReference = new StringReference();
+    }
+
+    private bool ParsePostValue()
+    {
+      while (true)
+      {
+        char currentChar = _chars[_charPos];
+
+        switch (currentChar)
+        {
+          case '\0':
+            if (_charsUsed == _charPos)
+            {
+              if (ReadData(false) == 0)
+              {
+                _currentState = State.Finished;
+                return false;
+              }
+            }
+            else
+            {
+              _charPos++;
+            }
+            break;
+          case '}':
+            _charPos++;
+            SetToken(JsonToken.EndObject);
+            return true;
+          case ']':
+            _charPos++;
+            SetToken(JsonToken.EndArray);
+            return true;
+          case ')':
+            _charPos++;
+            SetToken(JsonToken.EndConstructor);
+            return true;
+          case '/':
+            ParseComment();
+            return true;
+          case ',':
+            _charPos++;
+
+            // finished parsing
+            SetStateBasedOnCurrent();
+            return false;
+          case ' ':
+          case StringUtils.Tab:
+            // eat
+            _charPos++;
+            break;
+          case StringUtils.CarriageReturn:
+            ProcessCarriageReturn(false);
+            break;
+          case StringUtils.LineFeed:
+            ProcessLineFeed();
+            break;
+          default:
+            if (char.IsWhiteSpace(currentChar))
+            {
+              // eat
+              _charPos++;
+            }
+            else
+            {
+              throw JsonReaderException.Create(this, "After parsing a value an unexpected character was encountered: {0}.".FormatWith(CultureInfo.InvariantCulture, currentChar));
+            }
+            break;
+        }
+      }
+    }
+
+    private bool ParseObject()
+    {
+      while (true)
+      {
+        char currentChar = _chars[_charPos];
+
+        switch (currentChar)
+        {
+          case '\0':
+            if (_charsUsed == _charPos)
+            {
+              if (ReadData(false) == 0)
+                return false;
+            }
+            else
+            {
+              _charPos++;
+            }
+            break;
+          case '}':
+            SetToken(JsonToken.EndObject);
+            _charPos++;
+            return true;
+          case '/':
+            ParseComment();
+            return true;
+          case StringUtils.CarriageReturn:
+            ProcessCarriageReturn(false);
+            break;
+          case StringUtils.LineFeed:
+            ProcessLineFeed();
+            break;
+          case ' ':
+          case StringUtils.Tab:
+            // eat
+            _charPos++;
+            break;
+          default:
+            if (char.IsWhiteSpace(currentChar))
+            {
+              // eat
+              _charPos++;
+            }
+            else
+            {
+              return ParseProperty();
+            }
+            break;
+        }
+      }
+    }
+
+    private bool ParseProperty()
+    {
+      char firstChar = _chars[_charPos];
+      char quoteChar;
+
+      if (firstChar == '"' || firstChar == '\'')
+      {
+        _charPos++;
+        quoteChar = firstChar;
+        ShiftBufferIfNeeded();
+        ReadStringIntoBuffer(quoteChar);
+      }
+      else if (ValidIdentifierChar(firstChar))
+      {
+        quoteChar = '\0';
+        ShiftBufferIfNeeded();
+        ParseUnquotedProperty();
+      }
+      else
+      {
+        throw JsonReaderException.Create(this, "Invalid property identifier character: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos]));
+      }
+
+      string propertyName = _stringReference.ToString();
+
+      EatWhitespace(false);
+
+      if (_chars[_charPos] != ':')
+        throw JsonReaderException.Create(this, "Invalid character after parsing property name. Expected ':' but got: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos]));
+
+      _charPos++;
+
+      SetToken(JsonToken.PropertyName, propertyName);
+      QuoteChar = quoteChar;
+      ClearRecentString();
+
+      return true;
+    }
+
+    private bool ValidIdentifierChar(char value)
+    {
+      return (char.IsLetterOrDigit(value) || value == '_' || value == '$');
+    }
+
+    private void ParseUnquotedProperty()
+    {
+      int initialPosition = _charPos;
+
+      // parse unquoted property name until whitespace or colon
+      while (true)
+      {
+        switch (_chars[_charPos])
+        {
+          case '\0':
+            if (_charsUsed == _charPos)
+            {
+              if (ReadData(true) == 0)
+                throw JsonReaderException.Create(this, "Unexpected end while parsing unquoted property name.");
+
+              break;
+            }
+
+            _stringReference = new StringReference(_chars, initialPosition, _charPos - initialPosition);
+            return;
+          default:
+            char currentChar = _chars[_charPos];
+
+            if (ValidIdentifierChar(currentChar))
+            {
+              _charPos++;
+              break;
+            }
+            else if (char.IsWhiteSpace(currentChar) || currentChar == ':')
+            {
+              _stringReference = new StringReference(_chars, initialPosition, _charPos - initialPosition);
+              return;
+            }
+
+            throw JsonReaderException.Create(this, "Invalid JavaScript property identifier character: {0}.".FormatWith(CultureInfo.InvariantCulture, currentChar));
+        }
+      }
+    }
+
+    private bool ParseValue()
+    {
+      while (true)
+      {
+        char currentChar = _chars[_charPos];
+
+        switch (currentChar)
+        {
+          case '\0':
+            if (_charsUsed == _charPos)
+            {
+              if (ReadData(false) == 0)
+                return false;
+            }
+            else
+            {
+              _charPos++;
+            }
+            break;
+          case '"':
+          case '\'':
+            ParseString(currentChar);
+            return true;
+          case 't':
+            ParseTrue();
+            return true;
+          case 'f':
+            ParseFalse();
+            return true;
+          case 'n':
+            if (EnsureChars(1, true))
+            {
+              char next = _chars[_charPos + 1];
+
+              if (next == 'u')
+                ParseNull();
+              else if (next == 'e')
+                ParseConstructor();
+              else
+                throw JsonReaderException.Create(this, "Unexpected character encountered while parsing value: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos]));
+            }
+            else
+            {
+              throw JsonReaderException.Create(this, "Unexpected end.");
+            }
+            return true;
+          case 'N':
+            ParseNumberNaN();
+            return true;
+          case 'I':
+            ParseNumberPositiveInfinity();
+            return true;
+          case '-':
+            if (EnsureChars(1, true) && _chars[_charPos + 1] == 'I')
+              ParseNumberNegativeInfinity();
+            else
+              ParseNumber();
+            return true;
+          case '/':
+            ParseComment();
+            return true;
+          case 'u':
+            ParseUndefined();
+            return true;
+          case '{':
+            _charPos++;
+            SetToken(JsonToken.StartObject);
+            return true;
+          case '[':
+            _charPos++;
+            SetToken(JsonToken.StartArray);
+            return true;
+          case ']':
+            _charPos++;
+            SetToken(JsonToken.EndArray);
+            return true;
+          case ',':
+            // don't increment position, the next call to read will handle comma
+            // this is done to handle multiple empty comma values
+            SetToken(JsonToken.Undefined);
+            return true;
+          case ')':
+            _charPos++;
+            SetToken(JsonToken.EndConstructor);
+            return true;
+          case StringUtils.CarriageReturn:
+            ProcessCarriageReturn(false);
+            break;
+          case StringUtils.LineFeed:
+            ProcessLineFeed();
+            break;
+          case ' ':
+          case StringUtils.Tab:
+            // eat
+            _charPos++;
+            break;
+          default:
+            if (char.IsWhiteSpace(currentChar))
+            {
+              // eat
+              _charPos++;
+              break;
+            }
+            else if (char.IsNumber(currentChar) || currentChar == '-' || currentChar == '.')
+            {
+              ParseNumber();
+              return true;
+            }
+            else
+            {
+              throw JsonReaderException.Create(this, "Unexpected character encountered while parsing value: {0}.".FormatWith(CultureInfo.InvariantCulture, currentChar));
+            }
+        }
+      }
+    }
+
+    private void ProcessLineFeed()
+    {
+      _charPos++;
+      OnNewLine(_charPos);
+    }
+
+    private void ProcessCarriageReturn(bool append)
+    {
+      _charPos++;
+
+      if (EnsureChars(1, append) && _chars[_charPos] == StringUtils.LineFeed)
+        _charPos++;
+
+      OnNewLine(_charPos);
+    }
+
+    private bool EatWhitespace(bool oneOrMore)
+    {
+      bool finished = false;
+      bool ateWhitespace = false;
+      while (!finished)
+      {
+        char currentChar = _chars[_charPos];
+
+        switch (currentChar)
+        {
+          case '\0':
+            if (_charsUsed == _charPos)
+            {
+              if (ReadData(false) == 0)
+                finished = true;
+            }
+            else
+            {
+              _charPos++;
+            }
+            break;
+          case StringUtils.CarriageReturn:
+            ProcessCarriageReturn(false);
+            break;
+          case StringUtils.LineFeed:
+            ProcessLineFeed();
+            break;
+          default:
+            if (currentChar == ' ' || char.IsWhiteSpace(currentChar))
+            {
+              ateWhitespace = true;
+              _charPos++;
+            }
+            else
+            {
+              finished = true;
+            }
+            break;
+        }
+      }
+
+      return (!oneOrMore || ateWhitespace);
+    }
+
+    private void ParseConstructor()
+    {
+      if (MatchValueWithTrailingSeperator("new"))
+      {
+        EatWhitespace(false);
+
+        int initialPosition = _charPos;
+        int endPosition;
+
+        while (true)
+        {
+          char currentChar = _chars[_charPos];
+          if (currentChar == '\0')
+          {
+            if (_charsUsed == _charPos)
+            {
+              if (ReadData(true) == 0)
+                throw JsonReaderException.Create(this, "Unexpected end while parsing constructor.");
+            }
+            else
+            {
+              endPosition = _charPos;
+              _charPos++;
+              break;
+            }
+          }
+          else if (char.IsLetterOrDigit(currentChar))
+          {
+            _charPos++;
+          }
+          else if (currentChar == StringUtils.CarriageReturn)
+          {
+            endPosition = _charPos;
+            ProcessCarriageReturn(true);
+            break;
+          }
+          else if (currentChar == StringUtils.LineFeed)
+          {
+            endPosition = _charPos;
+            ProcessLineFeed();
+            break;
+          }
+          else if (char.IsWhiteSpace(currentChar))
+          {
+            endPosition = _charPos;
+            _charPos++;
+            break;
+          }
+          else if (currentChar == '(')
+          {
+            endPosition = _charPos;
+            break;
+          }
+          else
+          {
+            throw JsonReaderException.Create(this, "Unexpected character while parsing constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, currentChar));
+          }
+        }
+
+        _stringReference = new StringReference(_chars, initialPosition, endPosition - initialPosition);
+        string constructorName = _stringReference.ToString();
+
+        EatWhitespace(false);
+
+        if (_chars[_charPos] != '(')
+          throw JsonReaderException.Create(this, "Unexpected character while parsing constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos]));
+
+        _charPos++;
+
+        ClearRecentString();
+
+        SetToken(JsonToken.StartConstructor, constructorName);
+      }
+    }
+
+    private void ParseNumber()
+    {
+      ShiftBufferIfNeeded();
+
+      char firstChar = _chars[_charPos];
+      int initialPosition = _charPos;
+
+      ReadNumberIntoBuffer();
+
+      _stringReference = new StringReference(_chars, initialPosition, _charPos - initialPosition);
+
+      object numberValue;
+      JsonToken numberType;
+
+      bool singleDigit = (char.IsDigit(firstChar) && _stringReference.Length == 1);
+      bool nonBase10 = (firstChar == '0' && _stringReference.Length > 1
+        && _stringReference.Chars[_stringReference.StartIndex + 1] != '.'
+        && _stringReference.Chars[_stringReference.StartIndex + 1] != 'e'
+        && _stringReference.Chars[_stringReference.StartIndex + 1] != 'E');
+
+      if (_readType == ReadType.ReadAsInt32)
+      {
+        if (singleDigit)
+        {
+          // digit char values start at 48
+          numberValue = firstChar - 48;
+        }
+        else if (nonBase10)
+        {
+          string number = _stringReference.ToString();
+
+          // decimal.Parse doesn't support parsing hexadecimal values
+          int integer = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase)
+                           ? Convert.ToInt32(number, 16)
+                           : Convert.ToInt32(number, 8);
+
+          numberValue = integer;
+        }
+        else
+        {
+          string number = _stringReference.ToString();
+
+          numberValue = Convert.ToInt32(number, CultureInfo.InvariantCulture);
+        }
+
+        numberType = JsonToken.Integer;
+      }
+      else if (_readType == ReadType.ReadAsDecimal)
+      {
+        if (singleDigit)
+        {
+          // digit char values start at 48
+          numberValue = (decimal)firstChar - 48;
+        }
+        else if (nonBase10)
+        {
+          string number = _stringReference.ToString();
+
+          // decimal.Parse doesn't support parsing hexadecimal values
+          long integer = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase)
+                           ? Convert.ToInt64(number, 16)
+                           : Convert.ToInt64(number, 8);
+
+          numberValue = Convert.ToDecimal(integer);
+        }
+        else
+        {
+          string number = _stringReference.ToString();
+
+          numberValue = decimal.Parse(number, NumberStyles.Number | NumberStyles.AllowExponent, CultureInfo.InvariantCulture);
+        }
+
+        numberType = JsonToken.Float;
+      }
+      else
+      {
+        if (singleDigit)
+        {
+          // digit char values start at 48
+          numberValue = (long)firstChar - 48;
+          numberType = JsonToken.Integer;
+        }
+        else if (nonBase10)
+        {
+          string number = _stringReference.ToString();
+
+          numberValue = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase)
+                          ? Convert.ToInt64(number, 16)
+                          : Convert.ToInt64(number, 8);
+          numberType = JsonToken.Integer;
+        }
+        else
+        {
+          string number = _stringReference.ToString();
+
+          // it's faster to do 3 indexof with single characters than an indexofany
+          if (number.IndexOf('.') != -1 || number.IndexOf('E') != -1 || number.IndexOf('e') != -1)
+          {
+            numberValue = Convert.ToDouble(number, CultureInfo.InvariantCulture);
+            numberType = JsonToken.Float;
+          }
+          else
+          {
+            try
+            {
+              numberValue = Convert.ToInt64(number, CultureInfo.InvariantCulture);
+            }
+            catch (OverflowException ex)
+            {
+              throw JsonReaderException.Create((JsonReader)this, "JSON integer {0} is too large or small for an Int64.".FormatWith(CultureInfo.InvariantCulture, number), ex);
+            }
+
+            numberType = JsonToken.Integer;
+          }
+        }
+      }
+
+      ClearRecentString();
+
+      SetToken(numberType, numberValue);
+    }
+
+    private void ParseComment()
+    {
+      // should have already parsed / character before reaching this method
+      _charPos++;
+
+      if (!EnsureChars(1, false) || _chars[_charPos] != '*')
+        throw JsonReaderException.Create(this, "Error parsing comment. Expected: *, got {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos]));
+      else
+        _charPos++;
+
+      int initialPosition = _charPos;
+
+      bool commentFinished = false;
+
+      while (!commentFinished)
+      {
+        switch (_chars[_charPos])
+        {
+          case '\0':
+            if (_charsUsed == _charPos)
+            {
+              if (ReadData(true) == 0)
+                throw JsonReaderException.Create(this, "Unexpected end while parsing comment.");
+            }
+            else
+            {
+              _charPos++;
+            }
+            break;
+          case '*':
+            _charPos++;
+
+            if (EnsureChars(0, true))
+            {
+              if (_chars[_charPos] == '/')
+              {
+                _stringReference = new StringReference(_chars, initialPosition, _charPos - initialPosition - 1);
+
+                _charPos++;
+                commentFinished = true;
+              }
+            }
+            break;
+          case StringUtils.CarriageReturn:
+            ProcessCarriageReturn(true);
+            break;
+          case StringUtils.LineFeed:
+            ProcessLineFeed();
+            break;
+          default:
+            _charPos++;
+            break;
+        }
+      }
+
+      SetToken(JsonToken.Comment, _stringReference.ToString());
+
+      ClearRecentString();
+    }
+
+    private bool MatchValue(string value)
+    {
+      if (!EnsureChars(value.Length - 1, true))
+        return false;
+
+      for (int i = 0; i < value.Length; i++)
+      {
+        if (_chars[_charPos + i] != value[i])
+        {
+          return false;
+        }
+      }
+
+      _charPos += value.Length;
+
+      return true;
+    }
+
+    private bool MatchValueWithTrailingSeperator(string value)
+    {
+      // will match value and then move to the next character, checking that it is a seperator character
+      bool match = MatchValue(value);
+
+      if (!match)
+        return false;
+
+      if (!EnsureChars(0, false))
+        return true;
+
+      return IsSeperator(_chars[_charPos]) || _chars[_charPos] == '\0';
+    }
+
+    private bool IsSeperator(char c)
+    {
+      switch (c)
+      {
+        case '}':
+        case ']':
+        case ',':
+          return true;
+        case '/':
+          // check next character to see if start of a comment
+          if (!EnsureChars(1, false))
+            return false;
+
+          return (_chars[_charPos + 1] == '*');
+        case ')':
+          if (CurrentState == State.Constructor || CurrentState == State.ConstructorStart)
+            return true;
+          break;
+        case ' ':
+        case StringUtils.Tab:
+        case StringUtils.LineFeed:
+        case StringUtils.CarriageReturn:
+          return true;
+        default:
+          if (char.IsWhiteSpace(c))
+            return true;
+          break;
+      }
+
+      return false;
+    }
+
+    private void ParseTrue()
+    {
+      // check characters equal 'true'
+      // and that it is followed by either a seperator character
+      // or the text ends
+      if (MatchValueWithTrailingSeperator(JsonConvert.True))
+      {
+        SetToken(JsonToken.Boolean, true);
+      }
+      else
+      {
+        throw JsonReaderException.Create(this, "Error parsing boolean value.");
+      }
+    }
+
+    private void ParseNull()
+    {
+      if (MatchValueWithTrailingSeperator(JsonConvert.Null))
+      {
+        SetToken(JsonToken.Null);
+      }
+      else
+      {
+        throw JsonReaderException.Create(this, "Error parsing null value.");
+      }
+    }
+
+    private void ParseUndefined()
+    {
+      if (MatchValueWithTrailingSeperator(JsonConvert.Undefined))
+      {
+        SetToken(JsonToken.Undefined);
+      }
+      else
+      {
+        throw JsonReaderException.Create(this, "Error parsing undefined value.");
+      }
+    }
+
+    private void ParseFalse()
+    {
+      if (MatchValueWithTrailingSeperator(JsonConvert.False))
+      {
+        SetToken(JsonToken.Boolean, false);
+      }
+      else
+      {
+        throw JsonReaderException.Create(this, "Error parsing boolean value.");
+      }
+    }
+
+    private void ParseNumberNegativeInfinity()
+    {
+      if (MatchValueWithTrailingSeperator(JsonConvert.NegativeInfinity))
+      {
+        SetToken(JsonToken.Float, double.NegativeInfinity);
+      }
+      else
+      {
+        throw JsonReaderException.Create(this, "Error parsing negative infinity value.");
+      }
+    }
+
+    private void ParseNumberPositiveInfinity()
+    {
+      if (MatchValueWithTrailingSeperator(JsonConvert.PositiveInfinity))
+      {
+        SetToken(JsonToken.Float, double.PositiveInfinity);
+      }
+      else
+      {
+        throw JsonReaderException.Create(this, "Error parsing positive infinity value.");
+      }
+    }
+
+    private void ParseNumberNaN()
+    {
+      if (MatchValueWithTrailingSeperator(JsonConvert.NaN))
+      {
+        SetToken(JsonToken.Float, double.NaN);
+      }
+      else
+      {
+        throw JsonReaderException.Create(this, "Error parsing NaN value.");
+      }
+    }
+
+    /// <summary>
+    /// Changes the state to closed. 
+    /// </summary>
+    public override void Close()
+    {
+      base.Close();
+
+      if (CloseInput && _reader != null)
+#if !(NETFX_CORE || PORTABLE)
+        _reader.Close();
+#else
+        _reader.Dispose();
+#endif
+
+      if (_buffer != null)
+        _buffer.Clear();
+    }
+
+    /// <summary>
+    /// Gets a value indicating whether the class can return line information.
+    /// </summary>
+    /// <returns>
+    /// 	<c>true</c> if LineNumber and LinePosition can be provided; otherwise, <c>false</c>.
+    /// </returns>
+    public bool HasLineInfo()
+    {
+      return true;
+    }
+
+    /// <summary>
+    /// Gets the current line number.
+    /// </summary>
+    /// <value>
+    /// The current line number or 0 if no line information is available (for example, HasLineInfo returns false).
+    /// </value>
+    public int LineNumber
+    {
+      get
+      {
+        if (CurrentState == State.Start && LinePosition == 0)
+          return 0;
+
+        return _lineNumber;
+      }
+    }
+
+    /// <summary>
+    /// Gets the current line position.
+    /// </summary>
+    /// <value>
+    /// The current line position or 0 if no line information is available (for example, HasLineInfo returns false).
+    /// </value>
+    public int LinePosition
+    {
+      get { return _charPos - _lineStartPos; }
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonTextWriter.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonTextWriter.cs
index c233722..18f012e 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonTextWriter.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonTextWriter.cs
@@ -1,489 +1,528 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.IO;
-using System.Xml;
-using Newtonsoft.Json.Utilities;
-
-namespace Newtonsoft.Json
-{
-  /// <summary>
-  /// Represents a writer that provides a fast, non-cached, forward-only way of generating Json data.
-  /// </summary>
-  public class JsonTextWriter : JsonWriter
-  {
-    private readonly TextWriter _writer;
-    private Base64Encoder _base64Encoder;
-    private char _indentChar;
-    private int _indentation;
-    private char _quoteChar;
-    private bool _quoteName;
-
-    private Base64Encoder Base64Encoder
-    {
-      get
-      {
-        if (_base64Encoder == null)
-          _base64Encoder = new Base64Encoder(_writer);
-
-        return _base64Encoder;
-      }
-    }
-
-    /// <summary>
-    /// Gets or sets how many IndentChars to write for each level in the hierarchy when <paramref name="Formatting"/> is set to <c>Formatting.Indented</c>.
-    /// </summary>
-    public int Indentation
-    {
-      get { return _indentation; }
-      set
-      {
-        if (value < 0)
-          throw new ArgumentException("Indentation value must be greater than 0.");
-
-        _indentation = value;
-      }
-    }
-
-    /// <summary>
-    /// Gets or sets which character to use to quote attribute values.
-    /// </summary>
-    public char QuoteChar
-    {
-      get { return _quoteChar; }
-      set
-      {
-        if (value != '"' && value != '\'')
-          throw new ArgumentException(@"Invalid JavaScript string quote character. Valid quote characters are ' and "".");
-
-        _quoteChar = value;
-      }
-    }
-
-    /// <summary>
-    /// Gets or sets which character to use for indenting when <paramref name="Formatting"/> is set to <c>Formatting.Indented</c>.
-    /// </summary>
-    public char IndentChar
-    {
-      get { return _indentChar; }
-      set { _indentChar = value; }
-    }
-
-    /// <summary>
-    /// Gets or sets a value indicating whether object names will be surrounded with quotes.
-    /// </summary>
-    public bool QuoteName
-    {
-      get { return _quoteName; }
-      set { _quoteName = value; }
-    }
-
-    /// <summary>
-    /// Creates an instance of the <c>JsonWriter</c> class using the specified <see cref="TextWriter"/>. 
-    /// </summary>
-    /// <param name="textWriter">The <c>TextWriter</c> to write to.</param>
-    public JsonTextWriter(TextWriter textWriter)
-    {
-      if (textWriter == null)
-        throw new ArgumentNullException("textWriter");
-
-      _writer = textWriter;
-      _quoteChar = '"';
-      _quoteName = true;
-      _indentChar = ' ';
-      _indentation = 2;
-    }
-
-    /// <summary>
-    /// Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream.
-    /// </summary>
-    public override void Flush()
-    {
-      _writer.Flush();
-    }
-
-    /// <summary>
-    /// Closes this stream and the underlying stream.
-    /// </summary>
-    public override void Close()
-    {
-      base.Close();
-
-      _writer.Close();
-    }
-
-    /// <summary>
-    /// Writes the beginning of a Json object.
-    /// </summary>
-    public override void WriteStartObject()
-    {
-      base.WriteStartObject();
-
-      _writer.Write("{");
-    }
-
-    /// <summary>
-    /// Writes the beginning of a Json array.
-    /// </summary>
-    public override void WriteStartArray()
-    {
-      base.WriteStartArray();
-
-      _writer.Write("[");
-    }
-
-    /// <summary>
-    /// Writes the start of a constructor with the given name.
-    /// </summary>
-    /// <param name="name">The name of the constructor.</param>
-    public override void WriteStartConstructor(string name)
-    {
-      base.WriteStartConstructor(name);
-
-      _writer.Write("new ");
-      _writer.Write(name);
-      _writer.Write("(");
-    }
-
-    /// <summary>
-    /// Writes the specified end token.
-    /// </summary>
-    /// <param name="token">The end token to write.</param>
-    protected override void WriteEnd(JsonToken token)
-    {
-      switch (token)
-      {
-        case JsonToken.EndObject:
-          _writer.Write("}");
-          break;
-        case JsonToken.EndArray:
-          _writer.Write("]");
-          break;
-        case JsonToken.EndConstructor:
-          _writer.Write(")");
-          break;
-        default:
-          throw new JsonWriterException("Invalid JsonToken: " + token);
-      }
-    }
-
-    /// <summary>
-    /// Writes the property name of a name/value pair on a Json object.
-    /// </summary>
-    /// <param name="name">The name of the property.</param>
-    public override void WritePropertyName(string name)
-    {
-      base.WritePropertyName(name);
-
-      JavaScriptUtils.WriteEscapedJavaScriptString(_writer, name, _quoteChar, _quoteName);
-
-      _writer.Write(':');
-    }
-
-    /// <summary>
-    /// Writes indent characters.
-    /// </summary>
-    protected override void WriteIndent()
-    {
-      if (Formatting == Formatting.Indented)
-      {
-        _writer.Write(Environment.NewLine);
-
-        // levels of indentation multiplied by the indent count
-        int currentIndentCount = Top * _indentation;
-
-        for (int i = 0; i < currentIndentCount; i++)
-        {
-          _writer.Write(_indentChar);
-        }
-      }
-    }
-
-    /// <summary>
-    /// Writes the JSON value delimiter.
-    /// </summary>
-    protected override void WriteValueDelimiter()
-    {
-      _writer.Write(',');
-    }
-
-    /// <summary>
-    /// Writes an indent space.
-    /// </summary>
-    protected override void WriteIndentSpace()
-    {
-      _writer.Write(' ');
-    }
-
-    private void WriteValueInternal(string value, JsonToken token)
-    {
-      _writer.Write(value);
-    }
-
-    #region WriteValue methods
-    /// <summary>
-    /// Writes a null value.
-    /// </summary>
-    public override void WriteNull()
-    {
-      base.WriteNull();
-      WriteValueInternal(JsonConvert.Null, JsonToken.Null);
-    }
-
-    /// <summary>
-    /// Writes an undefined value.
-    /// </summary>
-    public override void WriteUndefined()
-    {
-      base.WriteUndefined();
-      WriteValueInternal(JsonConvert.Undefined, JsonToken.Undefined);
-    }
-
-    /// <summary>
-    /// Writes raw JSON.
-    /// </summary>
-    /// <param name="json">The raw JSON to write.</param>
-    public override void WriteRaw(string json)
-    {
-      base.WriteRaw(json);
-
-      _writer.Write(json);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="String"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="String"/> value to write.</param>
-    public override void WriteValue(string value)
-    {
-      base.WriteValue(value);
-      if (value == null)
-        WriteValueInternal(JsonConvert.Null, JsonToken.Null);
-      else
-        JavaScriptUtils.WriteEscapedJavaScriptString(_writer, value, _quoteChar, true);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Int32"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Int32"/> value to write.</param>
-    public override void WriteValue(int value)
-    {
-      base.WriteValue(value);
-      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="UInt32"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="UInt32"/> value to write.</param>
-    [CLSCompliant(false)]
-    public override void WriteValue(uint value)
-    {
-      base.WriteValue(value);
-      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Int64"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Int64"/> value to write.</param>
-    public override void WriteValue(long value)
-    {
-      base.WriteValue(value);
-      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="UInt64"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="UInt64"/> value to write.</param>
-    [CLSCompliant(false)]
-    public override void WriteValue(ulong value)
-    {
-      base.WriteValue(value);
-      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Single"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Single"/> value to write.</param>
-    public override void WriteValue(float value)
-    {
-      base.WriteValue(value);
-      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Float);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Double"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Double"/> value to write.</param>
-    public override void WriteValue(double value)
-    {
-      base.WriteValue(value);
-      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Float);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Boolean"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Boolean"/> value to write.</param>
-    public override void WriteValue(bool value)
-    {
-      base.WriteValue(value);
-      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Boolean);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Int16"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Int16"/> value to write.</param>
-    public override void WriteValue(short value)
-    {
-      base.WriteValue(value);
-      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="UInt16"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="UInt16"/> value to write.</param>
-    [CLSCompliant(false)]
-    public override void WriteValue(ushort value)
-    {
-      base.WriteValue(value);
-      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Char"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Char"/> value to write.</param>
-    public override void WriteValue(char value)
-    {
-      base.WriteValue(value);
-      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Byte"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Byte"/> value to write.</param>
-    public override void WriteValue(byte value)
-    {
-      base.WriteValue(value);
-      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="SByte"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="SByte"/> value to write.</param>
-    [CLSCompliant(false)]
-    public override void WriteValue(sbyte value)
-    {
-      base.WriteValue(value);
-      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Decimal"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Decimal"/> value to write.</param>
-    public override void WriteValue(decimal value)
-    {
-      base.WriteValue(value);
-      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Float);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="DateTime"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="DateTime"/> value to write.</param>
-    public override void WriteValue(DateTime value)
-    {
-      base.WriteValue(value);
-      JsonConvert.WriteDateTimeString(_writer, value);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="T:Byte[]"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="T:Byte[]"/> value to write.</param>
-    public override void WriteValue(byte[] value)
-    {
-      base.WriteValue(value);
-
-      if (value != null)
-      {
-        _writer.Write(_quoteChar);
-        Base64Encoder.Encode(value, 0, value.Length);
-        Base64Encoder.Flush();
-        _writer.Write(_quoteChar);
-      }
-    }
-
-#if !PocketPC && !NET20
-    /// <summary>
-    /// Writes a <see cref="DateTimeOffset"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="DateTimeOffset"/> value to write.</param>
-    public override void WriteValue(DateTimeOffset value)
-    {
-      base.WriteValue(value);
-      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Date);
-    }
-#endif
-    #endregion
-
-    /// <summary>
-    /// Writes out a comment <code>/*...*/</code> containing the specified text. 
-    /// </summary>
-    /// <param name="text">Text to place inside the comment.</param>
-    public override void WriteComment(string text)
-    {
-      base.WriteComment(text);
-
-      _writer.Write("/*");
-      _writer.Write(text);
-      _writer.Write("*/");
-    }
-
-    /// <summary>
-    /// Writes out the given white space.
-    /// </summary>
-    /// <param name="ws">The string of white space characters.</param>
-    public override void WriteWhitespace(string ws)
-    {
-      base.WriteWhitespace(ws);
-
-      _writer.Write(ws);
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Text;
+using System.IO;
+using System.Xml;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Represents a writer that provides a fast, non-cached, forward-only way of generating Json data.
+  /// </summary>
+  public class JsonTextWriter : JsonWriter
+  {
+    private readonly TextWriter _writer;
+    private Base64Encoder _base64Encoder;
+    private char _indentChar;
+    private int _indentation;
+    private char _quoteChar;
+    private bool _quoteName;
+
+    private Base64Encoder Base64Encoder
+    {
+      get
+      {
+        if (_base64Encoder == null)
+          _base64Encoder = new Base64Encoder(_writer);
+
+        return _base64Encoder;
+      }
+    }
+
+    /// <summary>
+    /// Gets or sets how many IndentChars to write for each level in the hierarchy when <see cref="Formatting"/> is set to <c>Formatting.Indented</c>.
+    /// </summary>
+    public int Indentation
+    {
+      get { return _indentation; }
+      set
+      {
+        if (value < 0)
+          throw new ArgumentException("Indentation value must be greater than 0.");
+
+        _indentation = value;
+      }
+    }
+
+    /// <summary>
+    /// Gets or sets which character to use to quote attribute values.
+    /// </summary>
+    public char QuoteChar
+    {
+      get { return _quoteChar; }
+      set
+      {
+        if (value != '"' && value != '\'')
+          throw new ArgumentException(@"Invalid JavaScript string quote character. Valid quote characters are ' and "".");
+
+        _quoteChar = value;
+      }
+    }
+
+    /// <summary>
+    /// Gets or sets which character to use for indenting when <see cref="Formatting"/> is set to <c>Formatting.Indented</c>.
+    /// </summary>
+    public char IndentChar
+    {
+      get { return _indentChar; }
+      set { _indentChar = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets a value indicating whether object names will be surrounded with quotes.
+    /// </summary>
+    public bool QuoteName
+    {
+      get { return _quoteName; }
+      set { _quoteName = value; }
+    }
+
+    /// <summary>
+    /// Creates an instance of the <c>JsonWriter</c> class using the specified <see cref="TextWriter"/>. 
+    /// </summary>
+    /// <param name="textWriter">The <c>TextWriter</c> to write to.</param>
+    public JsonTextWriter(TextWriter textWriter)
+    {
+      if (textWriter == null)
+        throw new ArgumentNullException("textWriter");
+
+      _writer = textWriter;
+      _quoteChar = '"';
+      _quoteName = true;
+      _indentChar = ' ';
+      _indentation = 2;
+    }
+
+    /// <summary>
+    /// Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream.
+    /// </summary>
+    public override void Flush()
+    {
+      _writer.Flush();
+    }
+
+    /// <summary>
+    /// Closes this stream and the underlying stream.
+    /// </summary>
+    public override void Close()
+    {
+      base.Close();
+
+      if (CloseOutput && _writer != null)
+#if !(NETFX_CORE || PORTABLE)
+        _writer.Close();
+#else
+        _writer.Dispose();
+#endif
+    }
+
+    /// <summary>
+    /// Writes the beginning of a Json object.
+    /// </summary>
+    public override void WriteStartObject()
+    {
+      base.WriteStartObject();
+
+      _writer.Write("{");
+    }
+
+    /// <summary>
+    /// Writes the beginning of a Json array.
+    /// </summary>
+    public override void WriteStartArray()
+    {
+      base.WriteStartArray();
+
+      _writer.Write("[");
+    }
+
+    /// <summary>
+    /// Writes the start of a constructor with the given name.
+    /// </summary>
+    /// <param name="name">The name of the constructor.</param>
+    public override void WriteStartConstructor(string name)
+    {
+      base.WriteStartConstructor(name);
+
+      _writer.Write("new ");
+      _writer.Write(name);
+      _writer.Write("(");
+    }
+
+    /// <summary>
+    /// Writes the specified end token.
+    /// </summary>
+    /// <param name="token">The end token to write.</param>
+    protected override void WriteEnd(JsonToken token)
+    {
+      switch (token)
+      {
+        case JsonToken.EndObject:
+          _writer.Write("}");
+          break;
+        case JsonToken.EndArray:
+          _writer.Write("]");
+          break;
+        case JsonToken.EndConstructor:
+          _writer.Write(")");
+          break;
+        default:
+          throw JsonWriterException.Create(this, "Invalid JsonToken: " + token, null);
+      }
+    }
+
+    /// <summary>
+    /// Writes the property name of a name/value pair on a Json object.
+    /// </summary>
+    /// <param name="name">The name of the property.</param>
+    public override void WritePropertyName(string name)
+    {
+      base.WritePropertyName(name);
+
+      JavaScriptUtils.WriteEscapedJavaScriptString(_writer, name, _quoteChar, _quoteName);
+
+      _writer.Write(':');
+    }
+
+    /// <summary>
+    /// Writes indent characters.
+    /// </summary>
+    protected override void WriteIndent()
+    {
+      _writer.Write(Environment.NewLine);
+
+      // levels of indentation multiplied by the indent count
+      int currentIndentCount = Top*_indentation;
+
+      while (currentIndentCount > 0)
+      {
+        // write up to a max of 10 characters at once to avoid creating too many new strings
+        int writeCount = Math.Min(currentIndentCount, 10);
+
+        _writer.Write(new string(_indentChar, writeCount));
+
+        currentIndentCount -= writeCount;
+      }
+    }
+
+    /// <summary>
+    /// Writes the JSON value delimiter.
+    /// </summary>
+    protected override void WriteValueDelimiter()
+    {
+      _writer.Write(',');
+    }
+
+    /// <summary>
+    /// Writes an indent space.
+    /// </summary>
+    protected override void WriteIndentSpace()
+    {
+      _writer.Write(' ');
+    }
+
+    private void WriteValueInternal(string value, JsonToken token)
+    {
+      _writer.Write(value);
+    }
+
+    #region WriteValue methods
+    /// <summary>
+    /// Writes a null value.
+    /// </summary>
+    public override void WriteNull()
+    {
+      base.WriteNull();
+      WriteValueInternal(JsonConvert.Null, JsonToken.Null);
+    }
+
+    /// <summary>
+    /// Writes an undefined value.
+    /// </summary>
+    public override void WriteUndefined()
+    {
+      base.WriteUndefined();
+      WriteValueInternal(JsonConvert.Undefined, JsonToken.Undefined);
+    }
+
+    /// <summary>
+    /// Writes raw JSON.
+    /// </summary>
+    /// <param name="json">The raw JSON to write.</param>
+    public override void WriteRaw(string json)
+    {
+      base.WriteRaw(json);
+
+      _writer.Write(json);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="String"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="String"/> value to write.</param>
+    public override void WriteValue(string value)
+    {
+      base.WriteValue(value);
+      if (value == null)
+        WriteValueInternal(JsonConvert.Null, JsonToken.Null);
+      else
+        JavaScriptUtils.WriteEscapedJavaScriptString(_writer, value, _quoteChar, true);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Int32"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Int32"/> value to write.</param>
+    public override void WriteValue(int value)
+    {
+      base.WriteValue(value);
+      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="UInt32"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="UInt32"/> value to write.</param>
+    [CLSCompliant(false)]
+    public override void WriteValue(uint value)
+    {
+      base.WriteValue(value);
+      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Int64"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Int64"/> value to write.</param>
+    public override void WriteValue(long value)
+    {
+      base.WriteValue(value);
+      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="UInt64"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="UInt64"/> value to write.</param>
+    [CLSCompliant(false)]
+    public override void WriteValue(ulong value)
+    {
+      base.WriteValue(value);
+      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Single"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Single"/> value to write.</param>
+    public override void WriteValue(float value)
+    {
+      base.WriteValue(value);
+      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Float);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Double"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Double"/> value to write.</param>
+    public override void WriteValue(double value)
+    {
+      base.WriteValue(value);
+      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Float);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Boolean"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Boolean"/> value to write.</param>
+    public override void WriteValue(bool value)
+    {
+      base.WriteValue(value);
+      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Boolean);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Int16"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Int16"/> value to write.</param>
+    public override void WriteValue(short value)
+    {
+      base.WriteValue(value);
+      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="UInt16"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="UInt16"/> value to write.</param>
+    [CLSCompliant(false)]
+    public override void WriteValue(ushort value)
+    {
+      base.WriteValue(value);
+      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Char"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Char"/> value to write.</param>
+    public override void WriteValue(char value)
+    {
+      base.WriteValue(value);
+      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Byte"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Byte"/> value to write.</param>
+    public override void WriteValue(byte value)
+    {
+      base.WriteValue(value);
+      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="SByte"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="SByte"/> value to write.</param>
+    [CLSCompliant(false)]
+    public override void WriteValue(sbyte value)
+    {
+      base.WriteValue(value);
+      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Decimal"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Decimal"/> value to write.</param>
+    public override void WriteValue(decimal value)
+    {
+      base.WriteValue(value);
+      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Float);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="DateTime"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="DateTime"/> value to write.</param>
+    public override void WriteValue(DateTime value)
+    {
+      base.WriteValue(value);
+      value = JsonConvert.EnsureDateTime(value, DateTimeZoneHandling);
+      JsonConvert.WriteDateTimeString(_writer, value, DateFormatHandling);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="T:Byte[]"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="T:Byte[]"/> value to write.</param>
+    public override void WriteValue(byte[] value)
+    {
+      base.WriteValue(value);
+
+      if (value != null)
+      {
+        _writer.Write(_quoteChar);
+        Base64Encoder.Encode(value, 0, value.Length);
+        Base64Encoder.Flush();
+        _writer.Write(_quoteChar);
+      }
+    }
+
+#if !PocketPC && !NET20
+    /// <summary>
+    /// Writes a <see cref="DateTimeOffset"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="DateTimeOffset"/> value to write.</param>
+    public override void WriteValue(DateTimeOffset value)
+    {
+      base.WriteValue(value);
+      WriteValueInternal(JsonConvert.ToString(value, DateFormatHandling), JsonToken.Date);
+    }
+#endif
+
+    /// <summary>
+    /// Writes a <see cref="Guid"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Guid"/> value to write.</param>
+    public override void WriteValue(Guid value)
+    {
+      base.WriteValue(value);
+      WriteValueInternal(JsonConvert.ToString(value), JsonToken.String);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="TimeSpan"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="TimeSpan"/> value to write.</param>
+    public override void WriteValue(TimeSpan value)
+    {
+      base.WriteValue(value);
+      WriteValueInternal(JsonConvert.ToString(value), JsonToken.String);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Uri"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Uri"/> value to write.</param>
+    public override void WriteValue(Uri value)
+    {
+      base.WriteValue(value);
+      WriteValueInternal(JsonConvert.ToString(value), JsonToken.String);
+    }
+    #endregion
+
+    /// <summary>
+    /// Writes out a comment <code>/*...*/</code> containing the specified text. 
+    /// </summary>
+    /// <param name="text">Text to place inside the comment.</param>
+    public override void WriteComment(string text)
+    {
+      base.WriteComment(text);
+
+      _writer.Write("/*");
+      _writer.Write(text);
+      _writer.Write("*/");
+    }
+
+    /// <summary>
+    /// Writes out the given white space.
+    /// </summary>
+    /// <param name="ws">The string of white space characters.</param>
+    public override void WriteWhitespace(string ws)
+    {
+      base.WriteWhitespace(ws);
+
+      _writer.Write(ws);
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonToken.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonToken.cs
index 5870c42..313659c 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonToken.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonToken.cs
@@ -1,110 +1,110 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace Newtonsoft.Json
-{
-  /// <summary>
-  /// Specifies the type of Json token.
-  /// </summary>
-  public enum JsonToken
-  {
-    /// <summary>
-    /// This is returned by the <see cref="JsonReader"/> if a <see cref="JsonReader.Read"/> method has not been called. 
-    /// </summary>
-    None,
-    /// <summary>
-    /// An object start token.
-    /// </summary>
-    StartObject,
-    /// <summary>
-    /// An array start token.
-    /// </summary>
-    StartArray,
-    /// <summary>
-    /// A constructor start token.
-    /// </summary>
-    StartConstructor,
-    /// <summary>
-    /// An object property name.
-    /// </summary>
-    PropertyName,
-    /// <summary>
-    /// A comment.
-    /// </summary>
-    Comment,
-    /// <summary>
-    /// Raw JSON.
-    /// </summary>
-    Raw,
-    /// <summary>
-    /// An interger.
-    /// </summary>
-    Integer,
-    /// <summary>
-    /// A float.
-    /// </summary>
-    Float,
-    /// <summary>
-    /// A string.
-    /// </summary>
-    String,
-    /// <summary>
-    /// A boolean.
-    /// </summary>
-    Boolean,
-    /// <summary>
-    /// A null token.
-    /// </summary>
-    Null,
-    /// <summary>
-    /// An undefined token.
-    /// </summary>
-    Undefined,
-    /// <summary>
-    /// An object end token.
-    /// </summary>
-    EndObject,
-    /// <summary>
-    /// An array end token.
-    /// </summary>
-    EndArray,
-    /// <summary>
-    /// A constructor end token.
-    /// </summary>
-    EndConstructor,
-    /// <summary>
-    /// A Date.
-    /// </summary>
-    Date,
-    /// <summary>
-    /// Byte data.
-    /// </summary>
-    Bytes
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Specifies the type of Json token.
+  /// </summary>
+  public enum JsonToken
+  {
+    /// <summary>
+    /// This is returned by the <see cref="JsonReader"/> if a <see cref="JsonReader.Read"/> method has not been called. 
+    /// </summary>
+    None,
+    /// <summary>
+    /// An object start token.
+    /// </summary>
+    StartObject,
+    /// <summary>
+    /// An array start token.
+    /// </summary>
+    StartArray,
+    /// <summary>
+    /// A constructor start token.
+    /// </summary>
+    StartConstructor,
+    /// <summary>
+    /// An object property name.
+    /// </summary>
+    PropertyName,
+    /// <summary>
+    /// A comment.
+    /// </summary>
+    Comment,
+    /// <summary>
+    /// Raw JSON.
+    /// </summary>
+    Raw,
+    /// <summary>
+    /// An integer.
+    /// </summary>
+    Integer,
+    /// <summary>
+    /// A float.
+    /// </summary>
+    Float,
+    /// <summary>
+    /// A string.
+    /// </summary>
+    String,
+    /// <summary>
+    /// A boolean.
+    /// </summary>
+    Boolean,
+    /// <summary>
+    /// A null token.
+    /// </summary>
+    Null,
+    /// <summary>
+    /// An undefined token.
+    /// </summary>
+    Undefined,
+    /// <summary>
+    /// An object end token.
+    /// </summary>
+    EndObject,
+    /// <summary>
+    /// An array end token.
+    /// </summary>
+    EndArray,
+    /// <summary>
+    /// A constructor end token.
+    /// </summary>
+    EndConstructor,
+    /// <summary>
+    /// A Date.
+    /// </summary>
+    Date,
+    /// <summary>
+    /// Byte data.
+    /// </summary>
+    Bytes
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonValidatingReader.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonValidatingReader.cs
index 23a1cd4..f65fb96 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonValidatingReader.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonValidatingReader.cs
@@ -1,619 +1,805 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Newtonsoft.Json.Linq;
-using Newtonsoft.Json.Schema;
-using Newtonsoft.Json.Utilities;
-using System.Globalization;
-using System.Text.RegularExpressions;
-
-namespace Newtonsoft.Json
-{
-  /// <summary>
-  /// Represents a reader that provides <see cref="JsonSchema"/> validation.
-  /// </summary>
-  public class JsonValidatingReader : JsonReader, IJsonLineInfo
-  {
-    private class SchemaScope
-    {
-      private readonly JTokenType _tokenType;
-      private readonly JsonSchemaModel _schema;
-      private readonly Dictionary<string, bool> _requiredProperties;
-
-      public string CurrentPropertyName { get; set; }
-      public int ArrayItemCount { get; set; }
-
-      public JsonSchemaModel Schema
-      {
-        get { return _schema; }
-      }
-
-      public Dictionary<string, bool> RequiredProperties
-      {
-        get { return _requiredProperties; }
-      }
-
-      public JTokenType TokenType
-      {
-        get { return _tokenType; }
-      }
-
-      public SchemaScope(JTokenType tokenType, JsonSchemaModel schema)
-      {
-        _tokenType = tokenType;
-        _schema = schema;
-
-        if (_schema != null && _schema.Properties != null)
-          _requiredProperties = GetRequiredProperties(_schema).Distinct().ToDictionary(p => p, p => false);
-        else
-          _requiredProperties = new Dictionary<string, bool>();
-      }
-
-      private IEnumerable<string> GetRequiredProperties(JsonSchemaModel schema)
-      {
-        return schema.Properties.Where(p => !p.Value.Optional).Select(p => p.Key);
-      }
-    }
-
-    private readonly JsonReader _reader;
-    private readonly Stack<SchemaScope> _stack;
-    private JsonSchema _schema;
-    private JsonSchemaModel _model;
-    private SchemaScope _currentScope;
-
-    /// <summary>
-    /// Sets an event handler for receiving schema validation errors.
-    /// </summary>
-    public event ValidationEventHandler ValidationEventHandler;
-
-    /// <summary>
-    /// Gets the text value of the current Json token.
-    /// </summary>
-    /// <value></value>
-    public override object Value
-    {
-      get { return _reader.Value; }
-    }
-
-    /// <summary>
-    /// Gets the depth of the current token in the JSON document.
-    /// </summary>
-    /// <value>The depth of the current token in the JSON document.</value>
-    public override int Depth
-    {
-      get { return _reader.Depth; }
-    }
-
-    /// <summary>
-    /// Gets the quotation mark character used to enclose the value of a string.
-    /// </summary>
-    /// <value></value>
-    public override char QuoteChar
-    {
-      get { return _reader.QuoteChar; }
-      protected internal set { }
-    }
-
-    /// <summary>
-    /// Gets the type of the current Json token.
-    /// </summary>
-    /// <value></value>
-    public override JsonToken TokenType
-    {
-      get { return _reader.TokenType; }
-    }
-
-    /// <summary>
-    /// Gets The Common Language Runtime (CLR) type for the current Json token.
-    /// </summary>
-    /// <value></value>
-    public override Type ValueType
-    {
-      get { return _reader.ValueType; }
-    }
-
-    private void Push(SchemaScope scope)
-    {
-      _stack.Push(scope);
-      _currentScope = scope;
-    }
-
-    private SchemaScope Pop()
-    {
-      SchemaScope poppedScope = _stack.Pop();
-      _currentScope = (_stack.Count != 0)
-        ? _stack.Peek()
-        : null;
-
-      return poppedScope;
-    }
-
-    private JsonSchemaModel CurrentSchema
-    {
-      get { return _currentScope.Schema; }
-    }
-
-    private JsonSchemaModel CurrentMemberSchema
-    {
-      get
-      {
-        if (_currentScope == null)
-          return _model;
-
-        if (_currentScope.Schema == null)
-          return null;
-
-        switch (_currentScope.TokenType)
-        {
-          case JTokenType.None:
-            return _currentScope.Schema;
-          case JTokenType.Object:
-            if (_currentScope.CurrentPropertyName == null)
-              throw new Exception("CurrentPropertyName has not been set on scope.");
-
-            JsonSchemaModel propertySchema;
-            if (CurrentSchema.Properties != null && CurrentSchema.Properties.TryGetValue(_currentScope.CurrentPropertyName, out propertySchema))
-              return propertySchema;
-
-            return (CurrentSchema.AllowAdditionalProperties) ? CurrentSchema.AdditionalProperties : null;
-          case JTokenType.Array:
-            if (!CollectionUtils.IsNullOrEmpty(CurrentSchema.Items))
-            {
-              if (CurrentSchema.Items.Count == 1)
-                return CurrentSchema.Items[0];
-
-              if (CurrentSchema.Items.Count > (_currentScope.ArrayItemCount - 1))
-                return CurrentSchema.Items[_currentScope.ArrayItemCount - 1];
-            }
-
-            return (CurrentSchema.AllowAdditionalProperties) ? CurrentSchema.AdditionalProperties : null;
-          case JTokenType.Constructor:
-            return null;
-          default:
-            throw new ArgumentOutOfRangeException("TokenType", "Unexpected token type: {0}".FormatWith(CultureInfo.InvariantCulture, _currentScope.TokenType));
-        }
-      }
-    }
-
-    private void RaiseError(string message, JsonSchemaModel schema)
-    {
-      IJsonLineInfo lineInfo = this;
-
-      string exceptionMessage = (lineInfo.HasLineInfo())
-                                  ? message + " Line {0}, position {1}.".FormatWith(CultureInfo.InvariantCulture, lineInfo.LineNumber, lineInfo.LinePosition)
-                                  : message;
-
-      OnValidationEvent(new JsonSchemaException(exceptionMessage, null, lineInfo.LineNumber, lineInfo.LinePosition));
-    }
-
-    private void OnValidationEvent(JsonSchemaException exception)
-    {
-      ValidationEventHandler handler = ValidationEventHandler;
-      if (handler != null)
-        handler(this, new ValidationEventArgs(exception));
-      else
-        throw exception;
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonValidatingReader"/> class that
-    /// validates the content returned from the given <see cref="JsonReader"/>.
-    /// </summary>
-    /// <param name="reader">The <see cref="JsonReader"/> to read from while validating.</param>
-    public JsonValidatingReader(JsonReader reader)
-    {
-      ValidationUtils.ArgumentNotNull(reader, "reader");
-      _reader = reader;
-      _stack = new Stack<SchemaScope>();
-    }
-
-    /// <summary>
-    /// Gets or sets the schema.
-    /// </summary>
-    /// <value>The schema.</value>
-    public JsonSchema Schema
-    {
-      get { return _schema; }
-      set
-      {
-        if (TokenType != JsonToken.None)
-          throw new Exception("Cannot change schema while validating JSON.");
-
-        _schema = value;
-        _model = null;
-      }
-    }
-
-    /// <summary>
-    /// Gets the <see cref="JsonReader"/> used to construct this <see cref="JsonValidatingReader"/>.
-    /// </summary>
-    /// <value>The <see cref="JsonReader"/> specified in the constructor.</value>
-    public JsonReader Reader
-    {
-      get { return _reader; }
-    }
-
-    private void ValidateInEnumAndNotDisallowed(JsonSchemaModel schema)
-    {
-      if (schema == null)
-        return;
-
-      JToken value = new JValue(_reader.Value);
-
-      if (schema.Enum != null)
-      {
-        if (!schema.Enum.ContainsValue(value, new JTokenEqualityComparer()))
-          RaiseError("Value {0} is not defined in enum.".FormatWith(CultureInfo.InvariantCulture, value),
-                     schema);
-      }
-
-      JsonSchemaType? currentNodeType = GetCurrentNodeSchemaType();
-      if (currentNodeType != null)
-      {
-        if (JsonSchemaGenerator.HasFlag(schema.Disallow, currentNodeType.Value))
-          RaiseError("Type {0} is disallowed.".FormatWith(CultureInfo.InvariantCulture, currentNodeType), schema);
-      }
-    }
-
-    private JsonSchemaType? GetCurrentNodeSchemaType()
-    {
-      switch (_reader.TokenType)
-      {
-        case JsonToken.StartObject:
-          return JsonSchemaType.Object;
-        case JsonToken.StartArray:
-          return JsonSchemaType.Array;
-        case JsonToken.Integer:
-          return JsonSchemaType.Integer;
-        case JsonToken.Float:
-          return JsonSchemaType.Float;
-        case JsonToken.String:
-          return JsonSchemaType.String;
-        case JsonToken.Boolean:
-          return JsonSchemaType.Boolean;
-        case JsonToken.Null:
-          return JsonSchemaType.Null;
-        default:
-          return null;
-      }
-    }
-
-    /// <summary>
-    /// Reads the next JSON token from the stream as a <see cref="T:Byte[]"/>.
-    /// </summary>
-    /// <returns>
-    /// A <see cref="T:Byte[]"/> or a null reference if the next JSON token is null.
-    /// </returns>
-    public override byte[] ReadAsBytes()
-    {
-      byte[] data = _reader.ReadAsBytes();
-
-      ValidateCurrentToken();
-      return data;
-    }
-
-    /// <summary>
-    /// Reads the next JSON token from the stream.
-    /// </summary>
-    /// <returns>
-    /// true if the next token was read successfully; false if there are no more tokens to read.
-    /// </returns>
-    public override bool Read()
-    {
-      if (!_reader.Read())
-        return false;
-
-      if (_reader.TokenType == JsonToken.Comment)
-        return true;
-
-      ValidateCurrentToken();
-      return true;
-    }
-
-    private void ValidateCurrentToken()
-    {
-      // first time validate has been called. build model
-      if (_model == null)
-      {
-        JsonSchemaModelBuilder builder = new JsonSchemaModelBuilder();
-        _model = builder.Build(_schema);
-      }
-
-      switch (_reader.TokenType)
-      {
-        case JsonToken.StartObject:
-          ProcessValue();
-          JsonSchemaModel objectSchema = (ValidateObject(CurrentMemberSchema))
-                                           ? CurrentMemberSchema 
-                                           : null;
-          Push(new SchemaScope(JTokenType.Object, objectSchema));
-          break;
-        case JsonToken.StartArray:
-          ProcessValue();
-          JsonSchemaModel arraySchema = (ValidateArray(CurrentMemberSchema))
-                                          ? CurrentMemberSchema
-                                          : null;
-          Push(new SchemaScope(JTokenType.Array, arraySchema));
-          break;
-        case JsonToken.StartConstructor:
-          Push(new SchemaScope(JTokenType.Constructor, null));
-          break;
-        case JsonToken.PropertyName:
-          ValidatePropertyName(CurrentSchema);
-          break;
-        case JsonToken.Raw:
-          break;
-        case JsonToken.Integer:
-          ProcessValue();
-          ValidateInteger(CurrentMemberSchema);
-          break;
-        case JsonToken.Float:
-          ProcessValue();
-          ValidateFloat(CurrentMemberSchema);
-          break;
-        case JsonToken.String:
-          ProcessValue();
-          ValidateString(CurrentMemberSchema);
-          break;
-        case JsonToken.Boolean:
-          ProcessValue();
-          ValidateBoolean(CurrentMemberSchema);
-          break;
-        case JsonToken.Null:
-          ProcessValue();
-          ValidateNull(CurrentMemberSchema);
-          break;
-        case JsonToken.Undefined:
-          break;
-        case JsonToken.EndObject:
-          ValidateEndObject(CurrentSchema);
-          Pop();
-          break;
-        case JsonToken.EndArray:
-          ValidateEndArray(CurrentSchema);
-          Pop();
-          break;
-        case JsonToken.EndConstructor:
-          Pop();
-          break;
-        case JsonToken.Date:
-          break;
-        default:
-          throw new ArgumentOutOfRangeException();
-      }
-    }
-
-    private void ValidateEndObject(JsonSchemaModel schema)
-    {
-      if (schema == null)
-        return;
-
-      Dictionary<string, bool> requiredProperties = _currentScope.RequiredProperties;
-
-      if (requiredProperties != null)
-      {
-        List<string> unmatchedRequiredProperties =
-          requiredProperties.Where(kv => !kv.Value).Select(kv => kv.Key).ToList();
-
-        if (unmatchedRequiredProperties.Count > 0)
-          RaiseError("Non-optional properties are missing from object: {0}.".FormatWith(CultureInfo.InvariantCulture, string.Join(", ", unmatchedRequiredProperties.ToArray())), schema);
-      }
-    }
-
-    private void ValidateEndArray(JsonSchemaModel schema)
-    {
-      if (schema == null)
-        return;
-
-      int arrayItemCount = _currentScope.ArrayItemCount;
-
-      if (schema.MaximumItems != null && arrayItemCount > schema.MaximumItems)
-        RaiseError("Array item count {0} exceeds maximum count of {1}.".FormatWith(CultureInfo.InvariantCulture, arrayItemCount, schema.MaximumItems), schema);
-
-      if (schema.MinimumItems != null && arrayItemCount < schema.MinimumItems)
-        RaiseError("Array item count {0} is less than minimum count of {1}.".FormatWith(CultureInfo.InvariantCulture, arrayItemCount, schema.MinimumItems), schema);
-    }
-
-    private void ValidateNull(JsonSchemaModel schema)
-    {
-      if (schema == null)
-        return;
-
-      if (!TestType(schema, JsonSchemaType.Null))
-        return;
-
-      ValidateInEnumAndNotDisallowed(schema);
-    }
-
-    private void ValidateBoolean(JsonSchemaModel schema)
-    {
-      if (schema == null)
-        return;
-
-      if (!TestType(schema, JsonSchemaType.Boolean))
-        return;
-
-      ValidateInEnumAndNotDisallowed(schema);
-    }
-
-    private void ValidateString(JsonSchemaModel schema)
-    {
-      if (schema == null)
-        return;
-
-      if (!TestType(schema, JsonSchemaType.String))
-        return;
-
-      ValidateInEnumAndNotDisallowed(schema);
-
-      string value = _reader.Value.ToString();
-
-      if (schema.MaximumLength != null && value.Length > schema.MaximumLength)
-        RaiseError("String '{0}' exceeds maximum length of {1}.".FormatWith(CultureInfo.InvariantCulture, value, schema.MaximumLength), schema);
-
-      if (schema.MinimumLength != null && value.Length < schema.MinimumLength)
-        RaiseError("String '{0}' is less than minimum length of {1}.".FormatWith(CultureInfo.InvariantCulture, value, schema.MinimumLength), schema);
-
-      if (schema.Patterns != null)
-      {
-        foreach (string pattern in schema.Patterns)
-        {
-          if (!Regex.IsMatch(value, pattern))
-            RaiseError("String '{0}' does not match regex pattern '{1}'.".FormatWith(CultureInfo.InvariantCulture, value, pattern), schema);
-        }
-      }
-    }
-
-    private void ValidateInteger(JsonSchemaModel schema)
-    {
-      if (schema == null)
-        return;
-
-      if (!TestType(schema, JsonSchemaType.Integer))
-        return;
-
-      ValidateInEnumAndNotDisallowed(schema);
-      
-      long value = Convert.ToInt64(_reader.Value, CultureInfo.InvariantCulture);
-
-      if (schema.Maximum != null && value > schema.Maximum)
-        RaiseError("Integer {0} exceeds maximum value of {1}.".FormatWith(CultureInfo.InvariantCulture, value, schema.Maximum), schema);
-
-      if (schema.Minimum != null && value < schema.Minimum)
-        RaiseError("Integer {0} is less than minimum value of {1}.".FormatWith(CultureInfo.InvariantCulture, value, schema.Minimum), schema);
-    }
-
-    private void ProcessValue()
-    {
-      if (_currentScope != null && _currentScope.TokenType == JTokenType.Array)
-      {
-        _currentScope.ArrayItemCount++;
-
-        if (CurrentSchema != null && CurrentSchema.Items != null && CurrentSchema.Items.Count > 1 && _currentScope.ArrayItemCount >= CurrentSchema.Items.Count)
-          RaiseError("Index {0} has not been defined and the schema does not allow additional items.".FormatWith(CultureInfo.InvariantCulture, _currentScope.ArrayItemCount), CurrentSchema);
-      }
-    }
-
-    private void ValidateFloat(JsonSchemaModel schema)
-    {
-      if (schema == null)
-        return;
-
-      if (!TestType(schema, JsonSchemaType.Float))
-        return;
-
-      ValidateInEnumAndNotDisallowed(schema);
-      
-      double value = Convert.ToDouble(_reader.Value, CultureInfo.InvariantCulture);
-
-      if (schema.Maximum != null && value > schema.Maximum)
-        RaiseError("Float {0} exceeds maximum value of {1}.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(value), schema.Maximum), schema);
-
-      if (schema.Minimum != null && value < schema.Minimum)
-        RaiseError("Float {0} is less than minimum value of {1}.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(value), schema.Minimum), schema);
-
-      if (schema.MaximumDecimals != null && MathUtils.GetDecimalPlaces(value) > schema.MaximumDecimals)
-        RaiseError("Float {0} exceeds the maximum allowed number decimal places of {1}.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(value), schema.MaximumDecimals), schema);
-    }
-
-    private void ValidatePropertyName(JsonSchemaModel schema)
-    {
-      if (schema == null)
-        return;
-
-      string propertyName = Convert.ToString(_reader.Value, CultureInfo.InvariantCulture);
-
-      if (_currentScope.RequiredProperties.ContainsKey(propertyName))
-        _currentScope.RequiredProperties[propertyName] = true;
-
-      if (schema.Properties != null && !schema.Properties.ContainsKey(propertyName))
-      {
-        IList<string> definedProperties = schema.Properties.Select(p => p.Key).ToList();
-
-        if (!schema.AllowAdditionalProperties && !definedProperties.Contains(propertyName))
-        {
-          RaiseError("Property '{0}' has not been defined and the schema does not allow additional properties.".FormatWith(CultureInfo.InvariantCulture, propertyName), schema);
-        }
-      }
-
-      _currentScope.CurrentPropertyName = propertyName;
-    }
-
-    private bool ValidateArray(JsonSchemaModel schema)
-    {
-      if (schema == null)
-        return true;
-
-      return (TestType(schema, JsonSchemaType.Array));
-    }
-
-    private bool ValidateObject(JsonSchemaModel schema)
-    {
-      if (schema == null)
-        return true;
-
-      return (TestType(schema, JsonSchemaType.Object));
-    }
-
-    private bool TestType(JsonSchemaModel currentSchema, JsonSchemaType currentType)
-    {
-      if (!JsonSchemaGenerator.HasFlag(currentSchema.Type, currentType))
-      {
-        RaiseError("Invalid type. Expected {0} but got {1}.".FormatWith(CultureInfo.InvariantCulture, currentSchema.Type, currentType), currentSchema);
-        return false;
-      }
-
-      return true;
-    }
-
-    bool IJsonLineInfo.HasLineInfo()
-    {
-      IJsonLineInfo lineInfo = _reader as IJsonLineInfo;
-      return (lineInfo != null) ? lineInfo.HasLineInfo() : false;
-    }
-
-    int IJsonLineInfo.LineNumber
-    {
-      get
-      {
-        IJsonLineInfo lineInfo = _reader as IJsonLineInfo;
-        return (lineInfo != null) ? lineInfo.LineNumber : 0;
-      }
-    }
-
-    int IJsonLineInfo.LinePosition
-    {
-      get
-      {
-        IJsonLineInfo lineInfo = _reader as IJsonLineInfo;
-        return (lineInfo != null) ? lineInfo.LinePosition : 0;
-      }
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Schema;
+using Newtonsoft.Json.Utilities;
+using System.Globalization;
+using System.Text.RegularExpressions;
+using System.IO;
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#else
+using System.Linq;
+#endif
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Represents a reader that provides <see cref="JsonSchema"/> validation.
+  /// </summary>
+  public class JsonValidatingReader : JsonReader, IJsonLineInfo
+  {
+    private class SchemaScope
+    {
+      private readonly JTokenType _tokenType;
+      private readonly IList<JsonSchemaModel> _schemas;
+      private readonly Dictionary<string, bool> _requiredProperties;
+
+      public string CurrentPropertyName { get; set; }
+      public int ArrayItemCount { get; set; }
+
+      public IList<JsonSchemaModel> Schemas
+      {
+        get { return _schemas; }
+      }
+
+      public Dictionary<string, bool> RequiredProperties
+      {
+        get { return _requiredProperties; }
+      }
+
+      public JTokenType TokenType
+      {
+        get { return _tokenType; }
+      }
+
+      public SchemaScope(JTokenType tokenType, IList<JsonSchemaModel> schemas)
+      {
+        _tokenType = tokenType;
+        _schemas = schemas;
+
+        _requiredProperties = schemas.SelectMany<JsonSchemaModel, string>(GetRequiredProperties).Distinct().ToDictionary(p => p, p => false);
+      }
+
+      private IEnumerable<string> GetRequiredProperties(JsonSchemaModel schema)
+      {
+        if (schema == null || schema.Properties == null)
+          return Enumerable.Empty<string>();
+
+        return schema.Properties.Where(p => p.Value.Required).Select(p => p.Key);
+      }
+    }
+
+    private readonly JsonReader _reader;
+    private readonly Stack<SchemaScope> _stack;
+    private JsonSchema _schema;
+    private JsonSchemaModel _model;
+    private SchemaScope _currentScope;
+
+    /// <summary>
+    /// Sets an event handler for receiving schema validation errors.
+    /// </summary>
+    public event ValidationEventHandler ValidationEventHandler;
+
+    /// <summary>
+    /// Gets the text value of the current Json token.
+    /// </summary>
+    /// <value></value>
+    public override object Value
+    {
+      get { return _reader.Value; }
+    }
+
+    /// <summary>
+    /// Gets the depth of the current token in the JSON document.
+    /// </summary>
+    /// <value>The depth of the current token in the JSON document.</value>
+    public override int Depth
+    {
+      get { return _reader.Depth; }
+    }
+
+    /// <summary>
+    /// Gets the path of the current JSON token. 
+    /// </summary>
+    public override string Path
+    {
+      get { return _reader.Path; }
+    }
+
+    /// <summary>
+    /// Gets the quotation mark character used to enclose the value of a string.
+    /// </summary>
+    /// <value></value>
+    public override char QuoteChar
+    {
+      get { return _reader.QuoteChar; }
+      protected internal set { }
+    }
+
+    /// <summary>
+    /// Gets the type of the current Json token.
+    /// </summary>
+    /// <value></value>
+    public override JsonToken TokenType
+    {
+      get { return _reader.TokenType; }
+    }
+
+    /// <summary>
+    /// Gets the Common Language Runtime (CLR) type for the current Json token.
+    /// </summary>
+    /// <value></value>
+    public override Type ValueType
+    {
+      get { return _reader.ValueType; }
+    }
+
+    private void Push(SchemaScope scope)
+    {
+      _stack.Push(scope);
+      _currentScope = scope;
+    }
+
+    private SchemaScope Pop()
+    {
+      SchemaScope poppedScope = _stack.Pop();
+      _currentScope = (_stack.Count != 0)
+        ? _stack.Peek()
+        : null;
+
+      return poppedScope;
+    }
+
+    private IEnumerable<JsonSchemaModel> CurrentSchemas
+    {
+      get { return _currentScope.Schemas; }
+    }
+
+    private IEnumerable<JsonSchemaModel> CurrentMemberSchemas
+    {
+      get
+      {
+        if (_currentScope == null)
+          return new List<JsonSchemaModel>(new [] { _model });
+
+        if (_currentScope.Schemas == null || _currentScope.Schemas.Count == 0)
+          return Enumerable.Empty<JsonSchemaModel>();
+
+        switch (_currentScope.TokenType)
+        {
+          case JTokenType.None:
+            return _currentScope.Schemas;
+          case JTokenType.Object:
+            {
+              if (_currentScope.CurrentPropertyName == null)
+                throw new JsonReaderException("CurrentPropertyName has not been set on scope.");
+
+              IList<JsonSchemaModel> schemas = new List<JsonSchemaModel>();
+
+              foreach (JsonSchemaModel schema in CurrentSchemas)
+              {
+                JsonSchemaModel propertySchema;
+                if (schema.Properties != null && schema.Properties.TryGetValue(_currentScope.CurrentPropertyName, out propertySchema))
+                {
+                  schemas.Add(propertySchema);
+                }
+                if (schema.PatternProperties != null)
+                {
+                  foreach (KeyValuePair<string, JsonSchemaModel> patternProperty in schema.PatternProperties)
+                  {
+                    if (Regex.IsMatch(_currentScope.CurrentPropertyName, patternProperty.Key))
+                    {
+                      schemas.Add(patternProperty.Value);
+                    }
+                  }
+                }
+
+                if (schemas.Count == 0 && schema.AllowAdditionalProperties && schema.AdditionalProperties != null)
+                  schemas.Add(schema.AdditionalProperties);
+              }
+
+              return schemas;
+            }
+          case JTokenType.Array:
+            {
+              IList<JsonSchemaModel> schemas = new List<JsonSchemaModel>();
+              
+              foreach (JsonSchemaModel schema in CurrentSchemas)
+              {
+                if (!CollectionUtils.IsNullOrEmpty(schema.Items))
+                {
+                  if (schema.Items.Count == 1)
+                  {
+                    schemas.Add(schema.Items[0]);
+                  }
+                  else
+                  {
+                    if (schema.Items.Count > (_currentScope.ArrayItemCount - 1))
+                      schemas.Add(schema.Items[_currentScope.ArrayItemCount - 1]);
+                  }
+                }
+
+                if (schema.AllowAdditionalProperties && schema.AdditionalProperties != null)
+                  schemas.Add(schema.AdditionalProperties);
+              }
+
+              return schemas;
+            }
+          case JTokenType.Constructor:
+            return Enumerable.Empty<JsonSchemaModel>();
+          default:
+            throw new ArgumentOutOfRangeException("TokenType", "Unexpected token type: {0}".FormatWith(CultureInfo.InvariantCulture, _currentScope.TokenType));
+        }
+      }
+    }
+
+    private void RaiseError(string message, JsonSchemaModel schema)
+    {
+      IJsonLineInfo lineInfo = this;
+
+      string exceptionMessage = (lineInfo.HasLineInfo())
+                                  ? message + " Line {0}, position {1}.".FormatWith(CultureInfo.InvariantCulture, lineInfo.LineNumber, lineInfo.LinePosition)
+                                  : message;
+
+      OnValidationEvent(new JsonSchemaException(exceptionMessage, null, Path, lineInfo.LineNumber, lineInfo.LinePosition));
+    }
+
+    private void OnValidationEvent(JsonSchemaException exception)
+    {
+      ValidationEventHandler handler = ValidationEventHandler;
+      if (handler != null)
+        handler(this, new ValidationEventArgs(exception));
+      else
+        throw exception;
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonValidatingReader"/> class that
+    /// validates the content returned from the given <see cref="JsonReader"/>.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> to read from while validating.</param>
+    public JsonValidatingReader(JsonReader reader)
+    {
+      ValidationUtils.ArgumentNotNull(reader, "reader");
+      _reader = reader;
+      _stack = new Stack<SchemaScope>();
+    }
+
+    /// <summary>
+    /// Gets or sets the schema.
+    /// </summary>
+    /// <value>The schema.</value>
+    public JsonSchema Schema
+    {
+      get { return _schema; }
+      set
+      {
+        if (TokenType != JsonToken.None)
+          throw new InvalidOperationException("Cannot change schema while validating JSON.");
+
+        _schema = value;
+        _model = null;
+      }
+    }
+
+    /// <summary>
+    /// Gets the <see cref="JsonReader"/> used to construct this <see cref="JsonValidatingReader"/>.
+    /// </summary>
+    /// <value>The <see cref="JsonReader"/> specified in the constructor.</value>
+    public JsonReader Reader
+    {
+      get { return _reader; }
+    }
+
+    private void ValidateInEnumAndNotDisallowed(JsonSchemaModel schema)
+    {
+      if (schema == null)
+        return;
+
+      JToken value = new JValue(_reader.Value);
+
+      if (schema.Enum != null)
+      {
+        StringWriter sw = new StringWriter(CultureInfo.InvariantCulture);
+        value.WriteTo(new JsonTextWriter(sw));
+ 
+        if (!schema.Enum.ContainsValue(value, new JTokenEqualityComparer()))
+          RaiseError("Value {0} is not defined in enum.".FormatWith(CultureInfo.InvariantCulture, sw.ToString()),
+                     schema);
+      }
+
+      JsonSchemaType? currentNodeType = GetCurrentNodeSchemaType();
+      if (currentNodeType != null)
+      {
+        if (JsonSchemaGenerator.HasFlag(schema.Disallow, currentNodeType.Value))
+          RaiseError("Type {0} is disallowed.".FormatWith(CultureInfo.InvariantCulture, currentNodeType), schema);
+      }
+    }
+
+    private JsonSchemaType? GetCurrentNodeSchemaType()
+    {
+      switch (_reader.TokenType)
+      {
+        case JsonToken.StartObject:
+          return JsonSchemaType.Object;
+        case JsonToken.StartArray:
+          return JsonSchemaType.Array;
+        case JsonToken.Integer:
+          return JsonSchemaType.Integer;
+        case JsonToken.Float:
+          return JsonSchemaType.Float;
+        case JsonToken.String:
+          return JsonSchemaType.String;
+        case JsonToken.Boolean:
+          return JsonSchemaType.Boolean;
+        case JsonToken.Null:
+          return JsonSchemaType.Null;
+        default:
+          return null;
+      }
+    }
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="Nullable{Int32}"/>.
+    /// </summary>
+    /// <returns>A <see cref="Nullable{Int32}"/>.</returns>
+    public override int? ReadAsInt32()
+    {
+      int? i = _reader.ReadAsInt32();
+
+      ValidateCurrentToken();
+      return i;
+    }
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="T:Byte[]"/>.
+    /// </summary>
+    /// <returns>
+    /// A <see cref="T:Byte[]"/> or a null reference if the next JSON token is null.
+    /// </returns>
+    public override byte[] ReadAsBytes()
+    {
+      byte[] data = _reader.ReadAsBytes();
+
+      ValidateCurrentToken();
+      return data;
+    }
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="Nullable{Decimal}"/>.
+    /// </summary>
+    /// <returns>A <see cref="Nullable{Decimal}"/>.</returns>
+    public override decimal? ReadAsDecimal()
+    {
+      decimal? d = _reader.ReadAsDecimal();
+
+      ValidateCurrentToken();
+      return d;
+    }
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="String"/>.
+    /// </summary>
+    /// <returns>A <see cref="String"/>. This method will return <c>null</c> at the end of an array.</returns>
+    public override string ReadAsString()
+    {
+      string s = _reader.ReadAsString();
+
+      ValidateCurrentToken();
+      return s;
+    }
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="Nullable{DateTime}"/>.
+    /// </summary>
+    /// <returns>A <see cref="String"/>. This method will return <c>null</c> at the end of an array.</returns>
+    public override DateTime? ReadAsDateTime()
+    {
+      DateTime? dateTime = _reader.ReadAsDateTime();
+
+      ValidateCurrentToken();
+      return dateTime;
+    }
+
+#if !NET20
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="Nullable{DateTimeOffset}"/>.
+    /// </summary>
+    /// <returns>A <see cref="Nullable{DateTimeOffset}"/>.</returns>
+    public override DateTimeOffset? ReadAsDateTimeOffset()
+    {
+      DateTimeOffset? dateTimeOffset = _reader.ReadAsDateTimeOffset();
+
+      ValidateCurrentToken();
+      return dateTimeOffset;
+    }
+#endif
+
+    /// <summary>
+    /// Reads the next JSON token from the stream.
+    /// </summary>
+    /// <returns>
+    /// true if the next token was read successfully; false if there are no more tokens to read.
+    /// </returns>
+    public override bool Read()
+    {
+      if (!_reader.Read())
+        return false;
+
+      if (_reader.TokenType == JsonToken.Comment)
+        return true;
+
+      ValidateCurrentToken();
+      return true;
+    }
+
+    private void ValidateCurrentToken()
+    {
+      // first time validate has been called. build model
+      if (_model == null)
+      {
+        JsonSchemaModelBuilder builder = new JsonSchemaModelBuilder();
+        _model = builder.Build(_schema);
+      }
+
+      switch (_reader.TokenType)
+      {
+        case JsonToken.StartObject:
+          ProcessValue();
+          IList<JsonSchemaModel> objectSchemas = CurrentMemberSchemas.Where(ValidateObject).ToList();
+          Push(new SchemaScope(JTokenType.Object, objectSchemas));
+          break;
+        case JsonToken.StartArray:
+          ProcessValue();
+          IList<JsonSchemaModel> arraySchemas = CurrentMemberSchemas.Where(ValidateArray).ToList();
+          Push(new SchemaScope(JTokenType.Array, arraySchemas));
+          break;
+        case JsonToken.StartConstructor:
+          Push(new SchemaScope(JTokenType.Constructor, null));
+          break;
+        case JsonToken.PropertyName:
+          foreach (JsonSchemaModel schema in CurrentSchemas)
+          {
+            ValidatePropertyName(schema);
+          }
+          break;
+        case JsonToken.Raw:
+          break;
+        case JsonToken.Integer:
+          ProcessValue();
+          foreach (JsonSchemaModel schema in CurrentMemberSchemas)
+          {
+            ValidateInteger(schema);
+          }
+          break;
+        case JsonToken.Float:
+          ProcessValue();
+          foreach (JsonSchemaModel schema in CurrentMemberSchemas)
+          {
+            ValidateFloat(schema);
+          }
+          break;
+        case JsonToken.String:
+          ProcessValue();
+          foreach (JsonSchemaModel schema in CurrentMemberSchemas)
+          {
+            ValidateString(schema);
+          }
+          break;
+        case JsonToken.Boolean:
+          ProcessValue();
+          foreach (JsonSchemaModel schema in CurrentMemberSchemas)
+          {
+            ValidateBoolean(schema);
+          }
+          break;
+        case JsonToken.Null:
+          ProcessValue();
+          foreach (JsonSchemaModel schema in CurrentMemberSchemas)
+          {
+            ValidateNull(schema);
+          }
+          break;
+        case JsonToken.Undefined:
+          break;
+        case JsonToken.EndObject:
+          foreach (JsonSchemaModel schema in CurrentSchemas)
+          {
+            ValidateEndObject(schema);
+          }
+          Pop();
+          break;
+        case JsonToken.EndArray:
+          foreach (JsonSchemaModel schema in CurrentSchemas)
+          {
+            ValidateEndArray(schema);
+          }
+          Pop();
+          break;
+        case JsonToken.EndConstructor:
+          Pop();
+          break;
+        case JsonToken.Date:
+        case JsonToken.Bytes:
+          // these have no equivalent in JSON schema
+          break;
+        case JsonToken.None:
+          // no content, do nothing
+          break;
+        default:
+          throw new ArgumentOutOfRangeException();
+      }
+    }
+
+    private void ValidateEndObject(JsonSchemaModel schema)
+    {
+      if (schema == null)
+        return;
+
+      Dictionary<string, bool> requiredProperties = _currentScope.RequiredProperties;
+
+      if (requiredProperties != null)
+      {
+        List<string> unmatchedRequiredProperties =
+          requiredProperties.Where(kv => !kv.Value).Select(kv => kv.Key).ToList();
+
+        if (unmatchedRequiredProperties.Count > 0)
+          RaiseError("Required properties are missing from object: {0}.".FormatWith(CultureInfo.InvariantCulture, string.Join(", ", unmatchedRequiredProperties.ToArray())), schema);
+      }
+    }
+
+    private void ValidateEndArray(JsonSchemaModel schema)
+    {
+      if (schema == null)
+        return;
+
+      int arrayItemCount = _currentScope.ArrayItemCount;
+
+      if (schema.MaximumItems != null && arrayItemCount > schema.MaximumItems)
+        RaiseError("Array item count {0} exceeds maximum count of {1}.".FormatWith(CultureInfo.InvariantCulture, arrayItemCount, schema.MaximumItems), schema);
+
+      if (schema.MinimumItems != null && arrayItemCount < schema.MinimumItems)
+        RaiseError("Array item count {0} is less than minimum count of {1}.".FormatWith(CultureInfo.InvariantCulture, arrayItemCount, schema.MinimumItems), schema);
+    }
+
+    private void ValidateNull(JsonSchemaModel schema)
+    {
+      if (schema == null)
+        return;
+
+      if (!TestType(schema, JsonSchemaType.Null))
+        return;
+
+      ValidateInEnumAndNotDisallowed(schema);
+    }
+
+    private void ValidateBoolean(JsonSchemaModel schema)
+    {
+      if (schema == null)
+        return;
+
+      if (!TestType(schema, JsonSchemaType.Boolean))
+        return;
+
+      ValidateInEnumAndNotDisallowed(schema);
+    }
+
+    private void ValidateString(JsonSchemaModel schema)
+    {
+      if (schema == null)
+        return;
+
+      if (!TestType(schema, JsonSchemaType.String))
+        return;
+
+      ValidateInEnumAndNotDisallowed(schema);
+
+      string value = _reader.Value.ToString();
+
+      if (schema.MaximumLength != null && value.Length > schema.MaximumLength)
+        RaiseError("String '{0}' exceeds maximum length of {1}.".FormatWith(CultureInfo.InvariantCulture, value, schema.MaximumLength), schema);
+
+      if (schema.MinimumLength != null && value.Length < schema.MinimumLength)
+        RaiseError("String '{0}' is less than minimum length of {1}.".FormatWith(CultureInfo.InvariantCulture, value, schema.MinimumLength), schema);
+
+      if (schema.Patterns != null)
+      {
+        foreach (string pattern in schema.Patterns)
+        {
+          if (!Regex.IsMatch(value, pattern))
+            RaiseError("String '{0}' does not match regex pattern '{1}'.".FormatWith(CultureInfo.InvariantCulture, value, pattern), schema);
+        }
+      }
+    }
+
+    private void ValidateInteger(JsonSchemaModel schema)
+    {
+      if (schema == null)
+        return;
+
+      if (!TestType(schema, JsonSchemaType.Integer))
+        return;
+
+      ValidateInEnumAndNotDisallowed(schema);
+      
+      long value = Convert.ToInt64(_reader.Value, CultureInfo.InvariantCulture);
+
+      if (schema.Maximum != null)
+      {
+        if (value > schema.Maximum)
+          RaiseError("Integer {0} exceeds maximum value of {1}.".FormatWith(CultureInfo.InvariantCulture, value, schema.Maximum), schema);
+        if (schema.ExclusiveMaximum && value == schema.Maximum)
+          RaiseError("Integer {0} equals maximum value of {1} and exclusive maximum is true.".FormatWith(CultureInfo.InvariantCulture, value, schema.Maximum), schema);
+      }
+
+      if (schema.Minimum != null)
+      {
+        if (value < schema.Minimum)
+          RaiseError("Integer {0} is less than minimum value of {1}.".FormatWith(CultureInfo.InvariantCulture, value, schema.Minimum), schema);
+        if (schema.ExclusiveMinimum && value == schema.Minimum)
+          RaiseError("Integer {0} equals minimum value of {1} and exclusive minimum is true.".FormatWith(CultureInfo.InvariantCulture, value, schema.Minimum), schema);
+      }
+
+      if (schema.DivisibleBy != null && !IsZero(value % schema.DivisibleBy.Value))
+        RaiseError("Integer {0} is not evenly divisible by {1}.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(value), schema.DivisibleBy), schema);
+    }
+
+    private void ProcessValue()
+    {
+      if (_currentScope != null && _currentScope.TokenType == JTokenType.Array)
+      {
+        _currentScope.ArrayItemCount++;
+
+        foreach (JsonSchemaModel currentSchema in CurrentSchemas)
+        {
+          if (currentSchema != null && currentSchema.Items != null && currentSchema.Items.Count > 1 && _currentScope.ArrayItemCount >= currentSchema.Items.Count)
+            RaiseError("Index {0} has not been defined and the schema does not allow additional items.".FormatWith(CultureInfo.InvariantCulture, _currentScope.ArrayItemCount), currentSchema);
+        }
+      }
+    }
+
+    private void ValidateFloat(JsonSchemaModel schema)
+    {
+      if (schema == null)
+        return;
+
+      if (!TestType(schema, JsonSchemaType.Float))
+        return;
+
+      ValidateInEnumAndNotDisallowed(schema);
+      
+      double value = Convert.ToDouble(_reader.Value, CultureInfo.InvariantCulture);
+
+      if (schema.Maximum != null)
+      {
+        if (value > schema.Maximum)
+          RaiseError("Float {0} exceeds maximum value of {1}.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(value), schema.Maximum), schema);
+        if (schema.ExclusiveMaximum && value == schema.Maximum)
+          RaiseError("Float {0} equals maximum value of {1} and exclusive maximum is true.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(value), schema.Maximum), schema);
+      }
+
+      if (schema.Minimum != null)
+      {
+        if (value < schema.Minimum)
+          RaiseError("Float {0} is less than minimum value of {1}.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(value), schema.Minimum), schema);
+        if (schema.ExclusiveMinimum && value == schema.Minimum)
+          RaiseError("Float {0} equals minimum value of {1} and exclusive minimum is true.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(value), schema.Minimum), schema);
+      }
+
+      if (schema.DivisibleBy != null && !IsZero(value % schema.DivisibleBy.Value))
+        RaiseError("Float {0} is not evenly divisible by {1}.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(value), schema.DivisibleBy), schema);
+    }
+
+    private static bool IsZero(double value)
+    {
+      const double epsilon = 2.2204460492503131e-016;
+
+      return Math.Abs(value) < 10.0 * epsilon;
+    }
+
+    private void ValidatePropertyName(JsonSchemaModel schema)
+    {
+      if (schema == null)
+        return;
+
+      string propertyName = Convert.ToString(_reader.Value, CultureInfo.InvariantCulture);
+
+      if (_currentScope.RequiredProperties.ContainsKey(propertyName))
+        _currentScope.RequiredProperties[propertyName] = true;
+
+      if (!schema.AllowAdditionalProperties)
+      {
+        bool propertyDefinied = IsPropertyDefinied(schema, propertyName);
+
+        if (!propertyDefinied)
+          RaiseError("Property '{0}' has not been defined and the schema does not allow additional properties.".FormatWith(CultureInfo.InvariantCulture, propertyName), schema);
+      }
+
+      _currentScope.CurrentPropertyName = propertyName;
+    }
+
+    private bool IsPropertyDefinied(JsonSchemaModel schema, string propertyName)
+    {
+      if (schema.Properties != null && schema.Properties.ContainsKey(propertyName))
+        return true;
+
+      if (schema.PatternProperties != null)
+      {
+        foreach (string pattern in schema.PatternProperties.Keys)
+        {
+          if (Regex.IsMatch(propertyName, pattern))
+            return true;
+        }
+      }
+
+      return false;
+    }
+
+    private bool ValidateArray(JsonSchemaModel schema)
+    {
+      if (schema == null)
+        return true;
+
+      return (TestType(schema, JsonSchemaType.Array));
+    }
+
+    private bool ValidateObject(JsonSchemaModel schema)
+    {
+      if (schema == null)
+        return true;
+
+      return (TestType(schema, JsonSchemaType.Object));
+    }
+
+    private bool TestType(JsonSchemaModel currentSchema, JsonSchemaType currentType)
+    {
+      if (!JsonSchemaGenerator.HasFlag(currentSchema.Type, currentType))
+      {
+        RaiseError("Invalid type. Expected {0} but got {1}.".FormatWith(CultureInfo.InvariantCulture, currentSchema.Type, currentType), currentSchema);
+        return false;
+      }
+
+      return true;
+    }
+
+    bool IJsonLineInfo.HasLineInfo()
+    {
+      IJsonLineInfo lineInfo = _reader as IJsonLineInfo;
+      return lineInfo != null && lineInfo.HasLineInfo();
+    }
+
+    int IJsonLineInfo.LineNumber
+    {
+      get
+      {
+        IJsonLineInfo lineInfo = _reader as IJsonLineInfo;
+        return (lineInfo != null) ? lineInfo.LineNumber : 0;
+      }
+    }
+
+    int IJsonLineInfo.LinePosition
+    {
+      get
+      {
+        IJsonLineInfo lineInfo = _reader as IJsonLineInfo;
+        return (lineInfo != null) ? lineInfo.LinePosition : 0;
+      }
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonWriter.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonWriter.cs
index 374a9c9..4367efb 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonWriter.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonWriter.cs
@@ -1,1122 +1,1288 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.IO;
-using System.Xml;
-using Newtonsoft.Json.Utilities;
-using Newtonsoft.Json.Linq;
-using System.Globalization;
-
-namespace Newtonsoft.Json
-{
-  /// <summary>
-  /// Specifies the state of the <see cref="JsonWriter"/>.
-  /// </summary>
-  public enum WriteState
-  {
-    /// <summary>
-    /// An exception has been thrown, which has left the <see cref="JsonWriter"/> in an invalid state.
-    /// You may call the <see cref="JsonWriter.Close"/> method to put the <see cref="JsonWriter"/> in the <c>Closed</c> state.
-    /// Any other <see cref="JsonWriter"/> method calls results in an <see cref="InvalidOperationException"/> being thrown. 
-    /// </summary>
-    Error,
-    /// <summary>
-    /// The <see cref="JsonWriter.Close"/> method has been called. 
-    /// </summary>
-    Closed,
-    /// <summary>
-    /// An object is being written. 
-    /// </summary>
-    Object,
-    /// <summary>
-    /// A array is being written.
-    /// </summary>
-    Array,
-    /// <summary>
-    /// A constructor is being written.
-    /// </summary>
-    Constructor,
-    /// <summary>
-    /// A property is being written.
-    /// </summary>
-    Property,
-    /// <summary>
-    /// A write method has not been called.
-    /// </summary>
-    Start
-  }
-
-  /// <summary>
-  /// Specifies formatting options for the <see cref="JsonTextWriter"/>.
-  /// </summary>
-  public enum Formatting
-  {
-    /// <summary>
-    /// No special formatting is applied. This is the default.
-    /// </summary>
-    None,
-    /// <summary>
-    /// Causes child objects to be indented according to the <see cref="JsonTextWriter.Indentation"/> and <see cref="JsonTextWriter.IndentChar"/> settings.
-    /// </summary>
-    Indented
-  }
-
-  /// <summary>
-  /// Represents a writer that provides a fast, non-cached, forward-only way of generating Json data.
-  /// </summary>
-  public abstract class JsonWriter : IDisposable
-  {
-    private enum State
-    {
-      Start,
-      Property,
-      ObjectStart,
-      Object,
-      ArrayStart,
-      Array,
-      ConstructorStart,
-      Constructor,
-      Bytes,
-      Closed,
-      Error
-    }
-
-    // array that gives a new state based on the current state an the token being written
-    private static readonly State[][] stateArray = new[] {
-//                      Start                   PropertyName            ObjectStart         Object            ArrayStart              Array                   ConstructorStart        Constructor             Closed          Error
-//                        
-/* None             */new[]{ State.Error,            State.Error,            State.Error,        State.Error,      State.Error,            State.Error,            State.Error,            State.Error,            State.Error,    State.Error },
-/* StartObject      */new[]{ State.ObjectStart,      State.ObjectStart,      State.Error,        State.Error,      State.ObjectStart,      State.ObjectStart,      State.ObjectStart,      State.ObjectStart,      State.Error,    State.Error },
-/* StartArray       */new[]{ State.ArrayStart,       State.ArrayStart,       State.Error,        State.Error,      State.ArrayStart,       State.ArrayStart,       State.ArrayStart,       State.ArrayStart,       State.Error,    State.Error },
-/* StartConstructor */new[]{ State.ConstructorStart, State.ConstructorStart, State.Error,        State.Error,      State.ConstructorStart, State.ConstructorStart, State.ConstructorStart, State.ConstructorStart, State.Error,    State.Error },
-/* StartProperty    */new[]{ State.Property,         State.Error,            State.Property,     State.Property,   State.Error,            State.Error,            State.Error,            State.Error,            State.Error,    State.Error },
-/* Comment          */new[]{ State.Start,            State.Property,         State.ObjectStart,  State.Object,     State.ArrayStart,       State.Array,            State.Constructor,      State.Constructor,      State.Error,    State.Error },
-/* Raw              */new[]{ State.Start,            State.Property,         State.ObjectStart,  State.Object,     State.ArrayStart,       State.Array,            State.Constructor,      State.Constructor,      State.Error,    State.Error },
-/* Value            */new[]{ State.Start,            State.Object,           State.Error,        State.Error,      State.Array,            State.Array,            State.Constructor,      State.Constructor,      State.Error,    State.Error },
-		};
-
-    private int _top;
-
-    private readonly List<JTokenType> _stack;
-    private State _currentState;
-    private Formatting _formatting;
-
-    /// <summary>
-    /// Gets the top.
-    /// </summary>
-    /// <value>The top.</value>
-    protected internal int Top
-    {
-      get { return _top; }
-    }
-
-    /// <summary>
-    /// Gets the state of the writer.
-    /// </summary>
-    public WriteState WriteState
-    {
-      get
-      {
-        switch (_currentState)
-        {
-          case State.Error:
-            return WriteState.Error;
-          case State.Closed:
-            return WriteState.Closed;
-          case State.Object:
-          case State.ObjectStart:
-            return WriteState.Object;
-          case State.Array:
-          case State.ArrayStart:
-            return WriteState.Array;
-          case State.Constructor:
-          case State.ConstructorStart:
-            return WriteState.Constructor;
-          case State.Property:
-            return WriteState.Property;
-          case State.Start:
-            return WriteState.Start;
-          default:
-            throw new JsonWriterException("Invalid state: " + _currentState);
-        }
-      }
-    }
-
-    /// <summary>
-    /// Indicates how the output is formatted.
-    /// </summary>
-    public Formatting Formatting
-    {
-      get { return _formatting; }
-      set { _formatting = value; }
-    }
-
-    /// <summary>
-    /// Creates an instance of the <c>JsonWriter</c> class. 
-    /// </summary>
-    public JsonWriter()
-    {
-      _stack = new List<JTokenType>(8);
-      _stack.Add(JTokenType.None);
-      _currentState = State.Start;
-      _formatting = Formatting.None;
-    }
-
-    private void Push(JTokenType value)
-    {
-      _top++;
-      if (_stack.Count <= _top)
-        _stack.Add(value);
-      else
-        _stack[_top] = value;
-    }
-
-    private JTokenType Pop()
-    {
-      JTokenType value = Peek();
-      _top--;
-
-      return value;
-    }
-
-    private JTokenType Peek()
-    {
-      return _stack[_top];
-    }
-
-    /// <summary>
-    /// Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream.
-    /// </summary>
-    public abstract void Flush();
-
-    /// <summary>
-    /// Closes this stream and the underlying stream.
-    /// </summary>
-    public virtual void Close()
-    {
-      AutoCompleteAll();
-    }
-
-    /// <summary>
-    /// Writes the beginning of a Json object.
-    /// </summary>
-    public virtual void WriteStartObject()
-    {
-      AutoComplete(JsonToken.StartObject);
-      Push(JTokenType.Object);
-    }
-
-    /// <summary>
-    /// Writes the end of a Json object.
-    /// </summary>
-    public void WriteEndObject()
-    {
-      AutoCompleteClose(JsonToken.EndObject);
-    }
-
-    /// <summary>
-    /// Writes the beginning of a Json array.
-    /// </summary>
-    public virtual void WriteStartArray()
-    {
-      AutoComplete(JsonToken.StartArray);
-      Push(JTokenType.Array);
-    }
-
-    /// <summary>
-    /// Writes the end of an array.
-    /// </summary>
-    public void WriteEndArray()
-    {
-      AutoCompleteClose(JsonToken.EndArray);
-    }
-
-    /// <summary>
-    /// Writes the start of a constructor with the given name.
-    /// </summary>
-    /// <param name="name">The name of the constructor.</param>
-    public virtual void WriteStartConstructor(string name)
-    {
-      AutoComplete(JsonToken.StartConstructor);
-      Push(JTokenType.Constructor);
-    }
-
-    /// <summary>
-    /// Writes the end constructor.
-    /// </summary>
-    public void WriteEndConstructor()
-    {
-      AutoCompleteClose(JsonToken.EndConstructor);
-    }
-
-    /// <summary>
-    /// Writes the property name of a name/value pair on a Json object.
-    /// </summary>
-    /// <param name="name">The name of the property.</param>
-    public virtual void WritePropertyName(string name)
-    {
-      AutoComplete(JsonToken.PropertyName);
-    }
-
-    /// <summary>
-    /// Writes the end of the current Json object or array.
-    /// </summary>
-    public void WriteEnd()
-    {
-      WriteEnd(Peek());
-    }
-
-    /// <summary>
-    /// Writes the current <see cref="JsonReader"/> token.
-    /// </summary>
-    /// <param name="reader">The <see cref="JsonReader"/> to read the token from.</param>
-    public void WriteToken(JsonReader reader)
-    {
-      ValidationUtils.ArgumentNotNull(reader, "reader");
-
-      int initialDepth;
-
-      if (reader.TokenType == JsonToken.None)
-        initialDepth = -1;
-      else if (!IsStartToken(reader.TokenType))
-        initialDepth = reader.Depth + 1;
-      else
-        initialDepth = reader.Depth;
-
-      WriteToken(reader, initialDepth);
-    }
-
-    internal void WriteToken(JsonReader reader, int initialDepth)
-    {
-      do
-      {
-        switch (reader.TokenType)
-        {
-          case JsonToken.None:
-            // read to next
-            break;
-          case JsonToken.StartObject:
-            WriteStartObject();
-            break;
-          case JsonToken.StartArray:
-            WriteStartArray();
-            break;
-          case JsonToken.StartConstructor:
-            string constructorName = reader.Value.ToString();
-            // write a JValue date when the constructor is for a date
-            if (string.Compare(constructorName, "Date", StringComparison.Ordinal) == 0)
-              WriteConstructorDate(reader);
-            else
-              WriteStartConstructor(reader.Value.ToString());
-            break;
-          case JsonToken.PropertyName:
-            WritePropertyName(reader.Value.ToString());
-            break;
-          case JsonToken.Comment:
-            WriteComment(reader.Value.ToString());
-            break;
-          case JsonToken.Integer:
-            WriteValue((long)reader.Value);
-            break;
-          case JsonToken.Float:
-            WriteValue((double)reader.Value);
-            break;
-          case JsonToken.String:
-            WriteValue(reader.Value.ToString());
-            break;
-          case JsonToken.Boolean:
-            WriteValue((bool)reader.Value);
-            break;
-          case JsonToken.Null:
-            WriteNull();
-            break;
-          case JsonToken.Undefined:
-            WriteUndefined();
-            break;
-          case JsonToken.EndObject:
-            WriteEndObject();
-            break;
-          case JsonToken.EndArray:
-            WriteEndArray();
-            break;
-          case JsonToken.EndConstructor:
-            WriteEndConstructor();
-            break;
-          case JsonToken.Date:
-            WriteValue((DateTime)reader.Value);
-            break;
-          case JsonToken.Raw:
-            WriteRawValue((string)reader.Value);
-            break;
-          case JsonToken.Bytes:
-            WriteValue((byte[])reader.Value);
-            break;
-          default:
-            throw MiscellaneousUtils.CreateArgumentOutOfRangeException("TokenType", reader.TokenType, "Unexpected token type.");
-        }
-      }
-      while (
-        // stop if we have reached the end of the token being read
-        initialDepth - 1 < reader.Depth - (IsEndToken(reader.TokenType) ? 1 : 0)
-        && reader.Read());
-    }
-
-    private void WriteConstructorDate(JsonReader reader)
-    {
-      if (!reader.Read())
-        throw new Exception("Unexpected end while reading date constructor.");
-      if (reader.TokenType != JsonToken.Integer)
-        throw new Exception("Unexpected token while reading date constructor. Expected Integer, got " + reader.TokenType);
-
-      long ticks = (long)reader.Value;
-      DateTime date = JsonConvert.ConvertJavaScriptTicksToDateTime(ticks);
-
-      if (!reader.Read())
-        throw new Exception("Unexpected end while reading date constructor.");
-      if (reader.TokenType != JsonToken.EndConstructor)
-        throw new Exception("Unexpected token while reading date constructor. Expected EndConstructor, got " + reader.TokenType);
-
-      WriteValue(date);
-    }
-
-    private bool IsEndToken(JsonToken token)
-    {
-      switch (token)
-      {
-        case JsonToken.EndObject:
-        case JsonToken.EndArray:
-        case JsonToken.EndConstructor:
-          return true;
-        default:
-          return false;
-      }
-    }
-
-    private bool IsStartToken(JsonToken token)
-    {
-      switch (token)
-      {
-        case JsonToken.StartObject:
-        case JsonToken.StartArray:
-        case JsonToken.StartConstructor:
-          return true;
-        default:
-          return false;
-      }
-    }
-
-    private void WriteEnd(JTokenType type)
-    {
-      switch (type)
-      {
-        case JTokenType.Object:
-          WriteEndObject();
-          break;
-        case JTokenType.Array:
-          WriteEndArray();
-          break;
-        case JTokenType.Constructor:
-          WriteEndConstructor();
-          break;
-        default:
-          throw new JsonWriterException("Unexpected type when writing end: " + type);
-      }
-    }
-
-    private void AutoCompleteAll()
-    {
-      while (_top > 0)
-      {
-        WriteEnd();
-      }
-    }
-
-    private JTokenType GetTypeForCloseToken(JsonToken token)
-    {
-      switch (token)
-      {
-        case JsonToken.EndObject:
-          return JTokenType.Object;
-        case JsonToken.EndArray:
-          return JTokenType.Array;
-        case JsonToken.EndConstructor:
-          return JTokenType.Constructor;
-        default:
-          throw new JsonWriterException("No type for token: " + token);
-      }
-    }
-
-    private JsonToken GetCloseTokenForType(JTokenType type)
-    {
-      switch (type)
-      {
-        case JTokenType.Object:
-          return JsonToken.EndObject;
-        case JTokenType.Array:
-          return JsonToken.EndArray;
-        case JTokenType.Constructor:
-          return JsonToken.EndConstructor;
-        default:
-          throw new JsonWriterException("No close token for type: " + type);
-      }
-    }
-
-    private void AutoCompleteClose(JsonToken tokenBeingClosed)
-    {
-      // write closing symbol and calculate new state
-
-      int levelsToComplete = 0;
-
-      for (int i = 0; i < _top; i++)
-      {
-        int currentLevel = _top - i;
-
-        if (_stack[currentLevel] == GetTypeForCloseToken(tokenBeingClosed))
-        {
-          levelsToComplete = i + 1;
-          break;
-        }
-      }
-
-      if (levelsToComplete == 0)
-        throw new JsonWriterException("No token to close.");
-
-      for (int i = 0; i < levelsToComplete; i++)
-      {
-        JsonToken token = GetCloseTokenForType(Pop());
-
-        if (_currentState != State.ObjectStart && _currentState != State.ArrayStart)
-          WriteIndent();
-
-        WriteEnd(token);
-      }
-
-      JTokenType currentLevelType = Peek();
-
-      switch (currentLevelType)
-      {
-        case JTokenType.Object:
-          _currentState = State.Object;
-          break;
-        case JTokenType.Array:
-          _currentState = State.Array;
-          break;
-        case JTokenType.Constructor:
-          _currentState = State.Array;
-          break;
-        case JTokenType.None:
-          _currentState = State.Start;
-          break;
-        default:
-          throw new JsonWriterException("Unknown JsonType: " + currentLevelType);
-      }
-    }
-
-    /// <summary>
-    /// Writes the specified end token.
-    /// </summary>
-    /// <param name="token">The end token to write.</param>
-    protected virtual void WriteEnd(JsonToken token)
-    {
-    }
-
-    /// <summary>
-    /// Writes indent characters.
-    /// </summary>
-    protected virtual void WriteIndent()
-    {
-    }
-
-    /// <summary>
-    /// Writes the JSON value delimiter.
-    /// </summary>
-    protected virtual void WriteValueDelimiter()
-    {
-    }
-
-    /// <summary>
-    /// Writes an indent space.
-    /// </summary>
-    protected virtual void WriteIndentSpace()
-    {
-    }
-
-    internal void AutoComplete(JsonToken tokenBeingWritten)
-    {
-      int token;
-
-      switch (tokenBeingWritten)
-      {
-        default:
-          token = (int)tokenBeingWritten;
-          break;
-        case JsonToken.Integer:
-        case JsonToken.Float:
-        case JsonToken.String:
-        case JsonToken.Boolean:
-        case JsonToken.Null:
-        case JsonToken.Undefined:
-        case JsonToken.Date:
-        case JsonToken.Bytes:
-          // a value is being written
-          token = 7;
-          break;
-      }
-
-      // gets new state based on the current state and what is being written
-      State newState = stateArray[token][(int)_currentState];
-
-      if (newState == State.Error)
-        throw new JsonWriterException("Token {0} in state {1} would result in an invalid JavaScript object.".FormatWith(CultureInfo.InvariantCulture, tokenBeingWritten.ToString(), _currentState.ToString()));
-
-      if ((_currentState == State.Object || _currentState == State.Array || _currentState == State.Constructor) && tokenBeingWritten != JsonToken.Comment)
-      {
-        WriteValueDelimiter();
-      }
-      else if (_currentState == State.Property)
-      {
-        if (_formatting == Formatting.Indented)
-          WriteIndentSpace();
-      }
-
-      WriteState writeState = WriteState;
-
-      // don't indent a property when it is the first token to be written (i.e. at the start)
-      if ((tokenBeingWritten == JsonToken.PropertyName && writeState != WriteState.Start) ||
-        writeState == WriteState.Array || writeState == WriteState.Constructor)
-      {
-        WriteIndent();
-      }
-
-      _currentState = newState;
-    }
-
-    #region WriteValue methods
-    /// <summary>
-    /// Writes a null value.
-    /// </summary>
-    public virtual void WriteNull()
-    {
-      AutoComplete(JsonToken.Null);
-    }
-
-    /// <summary>
-    /// Writes an undefined value.
-    /// </summary>
-    public virtual void WriteUndefined()
-    {
-      AutoComplete(JsonToken.Undefined);
-    }
-
-    /// <summary>
-    /// Writes raw JSON without changing the writer's state.
-    /// </summary>
-    /// <param name="json">The raw JSON to write.</param>
-    public virtual void WriteRaw(string json)
-    {
-    }
-
-    /// <summary>
-    /// Writes raw JSON where a value is expected and updates the writer's state.
-    /// </summary>
-    /// <param name="json">The raw JSON to write.</param>
-    public virtual void WriteRawValue(string json)
-    {
-      // hack. want writer to change state as if a value had been written
-      AutoComplete(JsonToken.Undefined);
-      WriteRaw(json);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="String"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="String"/> value to write.</param>
-    public virtual void WriteValue(string value)
-    {
-      AutoComplete(JsonToken.String);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Int32"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Int32"/> value to write.</param>
-    public virtual void WriteValue(int value)
-    {
-      AutoComplete(JsonToken.Integer);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="UInt32"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="UInt32"/> value to write.</param>
-    [CLSCompliant(false)]
-    public virtual void WriteValue(uint value)
-    {
-      AutoComplete(JsonToken.Integer);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Int64"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Int64"/> value to write.</param>
-    public virtual void WriteValue(long value)
-    {
-      AutoComplete(JsonToken.Integer);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="UInt64"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="UInt64"/> value to write.</param>
-    [CLSCompliant(false)]
-    public virtual void WriteValue(ulong value)
-    {
-      AutoComplete(JsonToken.Integer);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Single"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Single"/> value to write.</param>
-    public virtual void WriteValue(float value)
-    {
-      AutoComplete(JsonToken.Float);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Double"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Double"/> value to write.</param>
-    public virtual void WriteValue(double value)
-    {
-      AutoComplete(JsonToken.Float);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Boolean"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Boolean"/> value to write.</param>
-    public virtual void WriteValue(bool value)
-    {
-      AutoComplete(JsonToken.Boolean);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Int16"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Int16"/> value to write.</param>
-    public virtual void WriteValue(short value)
-    {
-      AutoComplete(JsonToken.Integer);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="UInt16"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="UInt16"/> value to write.</param>
-    [CLSCompliant(false)]
-    public virtual void WriteValue(ushort value)
-    {
-      AutoComplete(JsonToken.Integer);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Char"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Char"/> value to write.</param>
-    public virtual void WriteValue(char value)
-    {
-      AutoComplete(JsonToken.String);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Byte"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Byte"/> value to write.</param>
-    public virtual void WriteValue(byte value)
-    {
-      AutoComplete(JsonToken.Integer);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="SByte"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="SByte"/> value to write.</param>
-    [CLSCompliant(false)]
-    public virtual void WriteValue(sbyte value)
-    {
-      AutoComplete(JsonToken.Integer);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Decimal"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Decimal"/> value to write.</param>
-    public virtual void WriteValue(decimal value)
-    {
-      AutoComplete(JsonToken.Float);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="DateTime"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="DateTime"/> value to write.</param>
-    public virtual void WriteValue(DateTime value)
-    {
-      AutoComplete(JsonToken.Date);
-    }
-
-#if !PocketPC && !NET20
-    /// <summary>
-    /// Writes a <see cref="DateTimeOffset"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="DateTimeOffset"/> value to write.</param>
-    public virtual void WriteValue(DateTimeOffset value)
-    {
-      AutoComplete(JsonToken.Date);
-    }
-#endif
-
-    /// <summary>
-    /// Writes a <see cref="Nullable{Int32}"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Nullable{Int32}"/> value to write.</param>
-    public virtual void WriteValue(int? value)
-    {
-      if (value == null)
-        WriteNull();
-      else
-        WriteValue(value.Value);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Nullable{UInt32}"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Nullable{UInt32}"/> value to write.</param>
-    [CLSCompliant(false)]
-    public virtual void WriteValue(uint? value)
-    {
-      if (value == null)
-        WriteNull();
-      else
-        WriteValue(value.Value);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Nullable{Int64}"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Nullable{Int64}"/> value to write.</param>
-    public virtual void WriteValue(long? value)
-    {
-      if (value == null)
-        WriteNull();
-      else
-        WriteValue(value.Value);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Nullable{UInt64}"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Nullable{UInt64}"/> value to write.</param>
-    [CLSCompliant(false)]
-    public virtual void WriteValue(ulong? value)
-    {
-      if (value == null)
-        WriteNull();
-      else
-        WriteValue(value.Value);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Nullable{Single}"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Nullable{Single}"/> value to write.</param>
-    public virtual void WriteValue(float? value)
-    {
-      if (value == null)
-        WriteNull();
-      else
-        WriteValue(value.Value);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Nullable{Double}"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Nullable{Double}"/> value to write.</param>
-    public virtual void WriteValue(double? value)
-    {
-      if (value == null)
-        WriteNull();
-      else
-        WriteValue(value.Value);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Nullable{Boolean}"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Nullable{Boolean}"/> value to write.</param>
-    public virtual void WriteValue(bool? value)
-    {
-      if (value == null)
-        WriteNull();
-      else
-        WriteValue(value.Value);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Nullable{Int16}"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Nullable{Int16}"/> value to write.</param>
-    public virtual void WriteValue(short? value)
-    {
-      if (value == null)
-        WriteNull();
-      else
-        WriteValue(value.Value);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Nullable{UInt16}"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Nullable{UInt16}"/> value to write.</param>
-    [CLSCompliant(false)]
-    public virtual void WriteValue(ushort? value)
-    {
-      if (value == null)
-        WriteNull();
-      else
-        WriteValue(value.Value);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Nullable{Char}"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Nullable{Char}"/> value to write.</param>
-    public virtual void WriteValue(char? value)
-    {
-      if (value == null)
-        WriteNull();
-      else
-        WriteValue(value.Value);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Nullable{Byte}"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Nullable{Byte}"/> value to write.</param>
-    public virtual void WriteValue(byte? value)
-    {
-      if (value == null)
-        WriteNull();
-      else
-        WriteValue(value.Value);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Nullable{SByte}"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Nullable{SByte}"/> value to write.</param>
-    [CLSCompliant(false)]
-    public virtual void WriteValue(sbyte? value)
-    {
-      if (value == null)
-        WriteNull();
-      else
-        WriteValue(value.Value);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Nullable{Decimal}"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Nullable{Decimal}"/> value to write.</param>
-    public virtual void WriteValue(decimal? value)
-    {
-      if (value == null)
-        WriteNull();
-      else
-        WriteValue(value.Value);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Nullable{DateTime}"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Nullable{DateTime}"/> value to write.</param>
-    public virtual void WriteValue(DateTime? value)
-    {
-      if (value == null)
-        WriteNull();
-      else
-        WriteValue(value.Value);
-    }
-
-#if !PocketPC && !NET20
-    /// <summary>
-    /// Writes a <see cref="Nullable{DateTimeOffset}"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Nullable{DateTimeOffset}"/> value to write.</param>
-    public virtual void WriteValue(DateTimeOffset? value)
-    {
-      if (value == null)
-        WriteNull();
-      else
-        WriteValue(value.Value);
-    }
-#endif
-
-    /// <summary>
-    /// Writes a <see cref="T:Byte[]"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="T:Byte[]"/> value to write.</param>
-    public virtual void WriteValue(byte[] value)
-    {
-      if (value == null)
-        WriteNull();
-      else
-        AutoComplete(JsonToken.Bytes);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Object"/> value.
-    /// An error will raised if the value cannot be written as a single JSON token.
-    /// </summary>
-    /// <param name="value">The <see cref="Object"/> value to write.</param>
-    public virtual void WriteValue(object value)
-    {
-      if (value == null)
-      {
-        WriteNull();
-        return;
-      }
-      else if (value is IConvertible)
-      {
-        IConvertible convertible = value as IConvertible;
-
-        switch (convertible.GetTypeCode())
-        {
-          case TypeCode.String:
-            WriteValue(convertible.ToString(CultureInfo.InvariantCulture));
-            return;
-          case TypeCode.Char:
-            WriteValue(convertible.ToChar(CultureInfo.InvariantCulture));
-            return;
-          case TypeCode.Boolean:
-            WriteValue(convertible.ToBoolean(CultureInfo.InvariantCulture));
-            return;
-          case TypeCode.SByte:
-            WriteValue(convertible.ToSByte(CultureInfo.InvariantCulture));
-            return;
-          case TypeCode.Int16:
-            WriteValue(convertible.ToInt16(CultureInfo.InvariantCulture));
-            return;
-          case TypeCode.UInt16:
-            WriteValue(convertible.ToUInt16(CultureInfo.InvariantCulture));
-            return;
-          case TypeCode.Int32:
-            WriteValue(convertible.ToInt32(CultureInfo.InvariantCulture));
-            return;
-          case TypeCode.Byte:
-            WriteValue(convertible.ToByte(CultureInfo.InvariantCulture));
-            return;
-          case TypeCode.UInt32:
-            WriteValue(convertible.ToUInt32(CultureInfo.InvariantCulture));
-            return;
-          case TypeCode.Int64:
-            WriteValue(convertible.ToInt64(CultureInfo.InvariantCulture));
-            return;
-          case TypeCode.UInt64:
-            WriteValue(convertible.ToUInt64(CultureInfo.InvariantCulture));
-            return;
-          case TypeCode.Single:
-            WriteValue(convertible.ToSingle(CultureInfo.InvariantCulture));
-            return;
-          case TypeCode.Double:
-            WriteValue(convertible.ToDouble(CultureInfo.InvariantCulture));
-            return;
-          case TypeCode.DateTime:
-            WriteValue(convertible.ToDateTime(CultureInfo.InvariantCulture));
-            return;
-          case TypeCode.Decimal:
-            WriteValue(convertible.ToDecimal(CultureInfo.InvariantCulture));
-            return;
-          case TypeCode.DBNull:
-            WriteNull();
-            return;
-        }
-      }
-#if !PocketPC && !NET20
-      else if (value is DateTimeOffset)
-      {
-        WriteValue((DateTimeOffset)value);
-        return;
-      }
-#endif
-      else if (value is byte[])
-      {
-        WriteValue((byte[])value);
-        return;
-      }
-
-      throw new ArgumentException("Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType()));
-    }
-    #endregion
-
-    /// <summary>
-    /// Writes out a comment <code>/*...*/</code> containing the specified text. 
-    /// </summary>
-    /// <param name="text">Text to place inside the comment.</param>
-    public virtual void WriteComment(string text)
-    {
-      AutoComplete(JsonToken.Comment);
-    }
-
-    /// <summary>
-    /// Writes out the given white space.
-    /// </summary>
-    /// <param name="ws">The string of white space characters.</param>
-    public virtual void WriteWhitespace(string ws)
-    {
-      if (ws != null)
-      {
-        if (!StringUtils.IsWhiteSpace(ws))
-          throw new JsonWriterException("Only white space characters should be used.");
-      }
-    }
-
-
-    void IDisposable.Dispose()
-    {
-      Dispose(true);
-    }
-
-    private void Dispose(bool disposing)
-    {
-      if (WriteState != WriteState.Closed)
-        Close();
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using Newtonsoft.Json.Utilities;
+using System.Globalization;
+#if NETFX_CORE
+using IConvertible = Newtonsoft.Json.Utilities.Convertible;
+#endif
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#else
+using System.Linq;
+#endif
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Represents a writer that provides a fast, non-cached, forward-only way of generating Json data.
+  /// </summary>
+  public abstract class JsonWriter : IDisposable
+  {
+    internal enum State
+    {
+      Start,
+      Property,
+      ObjectStart,
+      Object,
+      ArrayStart,
+      Array,
+      ConstructorStart,
+      Constructor,
+      Bytes,
+      Closed,
+      Error
+    }
+
+    // array that gives a new state based on the current state an the token being written
+    private static readonly State[][] StateArray;
+
+    internal static readonly State[][] StateArrayTempate = new[] {
+//                                      Start                   PropertyName            ObjectStart         Object            ArrayStart              Array                   ConstructorStart        Constructor             Closed          Error
+//                        
+/* None                        */new[]{ State.Error,            State.Error,            State.Error,        State.Error,      State.Error,            State.Error,            State.Error,            State.Error,            State.Error,    State.Error },
+/* StartObject                 */new[]{ State.ObjectStart,      State.ObjectStart,      State.Error,        State.Error,      State.ObjectStart,      State.ObjectStart,      State.ObjectStart,      State.ObjectStart,      State.Error,    State.Error },
+/* StartArray                  */new[]{ State.ArrayStart,       State.ArrayStart,       State.Error,        State.Error,      State.ArrayStart,       State.ArrayStart,       State.ArrayStart,       State.ArrayStart,       State.Error,    State.Error },
+/* StartConstructor            */new[]{ State.ConstructorStart, State.ConstructorStart, State.Error,        State.Error,      State.ConstructorStart, State.ConstructorStart, State.ConstructorStart, State.ConstructorStart, State.Error,    State.Error },
+/* StartProperty               */new[]{ State.Property,         State.Error,            State.Property,     State.Property,   State.Error,            State.Error,            State.Error,            State.Error,            State.Error,    State.Error },
+/* Comment                     */new[]{ State.Start,            State.Property,         State.ObjectStart,  State.Object,     State.ArrayStart,       State.Array,            State.Constructor,      State.Constructor,      State.Error,    State.Error },
+/* Raw                         */new[]{ State.Start,            State.Property,         State.ObjectStart,  State.Object,     State.ArrayStart,       State.Array,            State.Constructor,      State.Constructor,      State.Error,    State.Error },
+/* Value (this will be copied) */new[]{ State.Start,            State.Object,           State.Error,        State.Error,      State.Array,            State.Array,            State.Constructor,      State.Constructor,      State.Error,    State.Error }
+		};
+
+    internal static State[][] BuildStateArray()
+    {
+      var allStates = StateArrayTempate.ToList();
+      var errorStates = StateArrayTempate[0];
+      var valueStates = StateArrayTempate[7];
+
+      foreach (JsonToken valueToken in EnumUtils.GetValues(typeof(JsonToken)))
+      {
+        if (allStates.Count <= (int)valueToken)
+        {
+          switch (valueToken)
+          {
+            case JsonToken.Integer:
+            case JsonToken.Float:
+            case JsonToken.String:
+            case JsonToken.Boolean:
+            case JsonToken.Null:
+            case JsonToken.Undefined:
+            case JsonToken.Date:
+            case JsonToken.Bytes:
+              allStates.Add(valueStates);
+              break;
+            default:
+              allStates.Add(errorStates);
+              break;
+          }
+        }
+      }
+
+      return allStates.ToArray();
+    }
+
+    static JsonWriter()
+    {
+      StateArray = BuildStateArray();
+    }
+
+    private readonly List<JsonPosition> _stack;
+    private JsonPosition _currentPosition;
+    private State _currentState;
+    private Formatting _formatting;
+
+    /// <summary>
+    /// Gets or sets a value indicating whether the underlying stream or
+    /// <see cref="TextReader"/> should be closed when the writer is closed.
+    /// </summary>
+    /// <value>
+    /// true to close the underlying stream or <see cref="TextReader"/> when
+    /// the writer is closed; otherwise false. The default is true.
+    /// </value>
+    public bool CloseOutput { get; set; }
+
+    /// <summary>
+    /// Gets the top.
+    /// </summary>
+    /// <value>The top.</value>
+    protected internal int Top
+    {
+      get
+      {
+        int depth = _stack.Count;
+        if (Peek() != JsonContainerType.None)
+          depth++;
+
+        return depth;
+      }
+    }
+
+    internal string ContainerPath
+    {
+      get
+      {
+        if (_currentPosition.Type == JsonContainerType.None)
+          return string.Empty;
+
+        IEnumerable<JsonPosition> positions = (_currentPosition.InsideContainer())
+          ? _stack
+          : _stack.Concat(new[] { _currentPosition });
+
+        return JsonPosition.BuildPath(positions);
+      }
+    }
+    
+    /// <summary>
+    /// Gets the state of the writer.
+    /// </summary>
+    public WriteState WriteState
+    {
+      get
+      {
+        switch (_currentState)
+        {
+          case State.Error:
+            return WriteState.Error;
+          case State.Closed:
+            return WriteState.Closed;
+          case State.Object:
+          case State.ObjectStart:
+            return WriteState.Object;
+          case State.Array:
+          case State.ArrayStart:
+            return WriteState.Array;
+          case State.Constructor:
+          case State.ConstructorStart:
+            return WriteState.Constructor;
+          case State.Property:
+            return WriteState.Property;
+          case State.Start:
+            return WriteState.Start;
+          default:
+            throw JsonWriterException.Create(this, "Invalid state: " + _currentState, null);
+        }
+      }
+    }
+
+    /// <summary>
+    /// Gets the path of the writer. 
+    /// </summary>
+    public string Path
+    {
+      get
+      {
+        if (_currentPosition.Type == JsonContainerType.None)
+          return string.Empty;
+
+        return JsonPosition.BuildPath(_stack.Concat(new[] { _currentPosition }));
+      }
+    }
+
+    private DateFormatHandling _dateFormatHandling;
+    private DateTimeZoneHandling _dateTimeZoneHandling;
+
+    /// <summary>
+    /// Indicates how JSON text output is formatted.
+    /// </summary>
+    public Formatting Formatting
+    {
+      get { return _formatting; }
+      set { _formatting = value; }
+    }
+
+    /// <summary>
+    /// Get or set how dates are written to JSON text.
+    /// </summary>
+    public DateFormatHandling DateFormatHandling
+    {
+      get { return _dateFormatHandling; }
+      set { _dateFormatHandling = value; }
+    }
+
+    /// <summary>
+    /// Get or set how <see cref="DateTime"/> time zones are handling when writing JSON.
+    /// </summary>
+    public DateTimeZoneHandling DateTimeZoneHandling
+    {
+      get { return _dateTimeZoneHandling; }
+      set { _dateTimeZoneHandling = value; }
+    }
+
+    /// <summary>
+    /// Creates an instance of the <c>JsonWriter</c> class. 
+    /// </summary>
+    protected JsonWriter()
+    {
+      _stack = new List<JsonPosition>(4);
+      _currentState = State.Start;
+      _formatting = Formatting.None;
+      _dateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind;
+
+      CloseOutput = true;
+    }
+
+    private void UpdateScopeWithFinishedValue()
+    {
+      if (_currentPosition.Type == JsonContainerType.Array
+        || _currentPosition.Type == JsonContainerType.Constructor)
+      {
+        if (_currentPosition.Position == null)
+          _currentPosition.Position = 0;
+        else
+          _currentPosition.Position++;
+      }
+    }
+
+    private void Push(JsonContainerType value)
+    {
+      UpdateScopeWithFinishedValue();
+
+      if (_currentPosition.Type == JsonContainerType.None)
+      {
+        _currentPosition.Type = value;
+      }
+      else
+      {
+        _stack.Add(_currentPosition);
+        var state = new JsonPosition
+        {
+          Type = value
+        };
+        _currentPosition = state;
+      }
+    }
+
+    private JsonContainerType Pop()
+    {
+      JsonPosition oldPosition;
+      if (_stack.Count > 0)
+      {
+        oldPosition = _currentPosition;
+        _currentPosition = _stack[_stack.Count - 1];
+        _stack.RemoveAt(_stack.Count - 1);
+      }
+      else
+      {
+        oldPosition = _currentPosition;
+        _currentPosition = new JsonPosition();
+      }
+
+      return oldPosition.Type;
+    }
+
+    private JsonContainerType Peek()
+    {
+      return _currentPosition.Type;
+    }
+
+    /// <summary>
+    /// Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream.
+    /// </summary>
+    public abstract void Flush();
+
+    /// <summary>
+    /// Closes this stream and the underlying stream.
+    /// </summary>
+    public virtual void Close()
+    {
+      AutoCompleteAll();
+    }
+
+    /// <summary>
+    /// Writes the beginning of a Json object.
+    /// </summary>
+    public virtual void WriteStartObject()
+    {
+      AutoComplete(JsonToken.StartObject);
+      Push(JsonContainerType.Object);
+    }
+
+    /// <summary>
+    /// Writes the end of a Json object.
+    /// </summary>
+    public virtual void WriteEndObject()
+    {
+      AutoCompleteClose(JsonToken.EndObject);
+    }
+
+    /// <summary>
+    /// Writes the beginning of a Json array.
+    /// </summary>
+    public virtual void WriteStartArray()
+    {
+      AutoComplete(JsonToken.StartArray);
+      Push(JsonContainerType.Array);
+    }
+
+    /// <summary>
+    /// Writes the end of an array.
+    /// </summary>
+    public virtual void WriteEndArray()
+    {
+      AutoCompleteClose(JsonToken.EndArray);
+    }
+
+    /// <summary>
+    /// Writes the start of a constructor with the given name.
+    /// </summary>
+    /// <param name="name">The name of the constructor.</param>
+    public virtual void WriteStartConstructor(string name)
+    {
+      AutoComplete(JsonToken.StartConstructor);
+      Push(JsonContainerType.Constructor);
+    }
+
+    /// <summary>
+    /// Writes the end constructor.
+    /// </summary>
+    public virtual void WriteEndConstructor()
+    {
+      AutoCompleteClose(JsonToken.EndConstructor);
+    }
+
+    /// <summary>
+    /// Writes the property name of a name/value pair on a Json object.
+    /// </summary>
+    /// <param name="name">The name of the property.</param>
+    public virtual void WritePropertyName(string name)
+    {
+      _currentPosition.PropertyName = name;
+      AutoComplete(JsonToken.PropertyName);
+    }
+
+    /// <summary>
+    /// Writes the end of the current Json object or array.
+    /// </summary>
+    public virtual void WriteEnd()
+    {
+      WriteEnd(Peek());
+    }
+
+    /// <summary>
+    /// Writes the current <see cref="JsonReader"/> token.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> to read the token from.</param>
+    public void WriteToken(JsonReader reader)
+    {
+      ValidationUtils.ArgumentNotNull(reader, "reader");
+
+      int initialDepth;
+
+      if (reader.TokenType == JsonToken.None)
+        initialDepth = -1;
+      else if (!IsStartToken(reader.TokenType))
+        initialDepth = reader.Depth + 1;
+      else
+        initialDepth = reader.Depth;
+
+      WriteToken(reader, initialDepth);
+    }
+
+    internal void WriteToken(JsonReader reader, int initialDepth)
+    {
+      do
+      {
+        switch (reader.TokenType)
+        {
+          case JsonToken.None:
+            // read to next
+            break;
+          case JsonToken.StartObject:
+            WriteStartObject();
+            break;
+          case JsonToken.StartArray:
+            WriteStartArray();
+            break;
+          case JsonToken.StartConstructor:
+            string constructorName = reader.Value.ToString();
+            // write a JValue date when the constructor is for a date
+            if (string.Equals(constructorName, "Date", StringComparison.Ordinal))
+              WriteConstructorDate(reader);
+            else
+              WriteStartConstructor(reader.Value.ToString());
+            break;
+          case JsonToken.PropertyName:
+            WritePropertyName(reader.Value.ToString());
+            break;
+          case JsonToken.Comment:
+            WriteComment(reader.Value.ToString());
+            break;
+          case JsonToken.Integer:
+            WriteValue(Convert.ToInt64(reader.Value, CultureInfo.InvariantCulture));
+            break;
+          case JsonToken.Float:
+            WriteValue(Convert.ToDouble(reader.Value, CultureInfo.InvariantCulture));
+            break;
+          case JsonToken.String:
+            WriteValue(reader.Value.ToString());
+            break;
+          case JsonToken.Boolean:
+            WriteValue(Convert.ToBoolean(reader.Value, CultureInfo.InvariantCulture));
+            break;
+          case JsonToken.Null:
+            WriteNull();
+            break;
+          case JsonToken.Undefined:
+            WriteUndefined();
+            break;
+          case JsonToken.EndObject:
+            WriteEndObject();
+            break;
+          case JsonToken.EndArray:
+            WriteEndArray();
+            break;
+          case JsonToken.EndConstructor:
+            WriteEndConstructor();
+            break;
+          case JsonToken.Date:
+            WriteValue((DateTime)reader.Value);
+            break;
+          case JsonToken.Raw:
+            WriteRawValue((string)reader.Value);
+            break;
+          case JsonToken.Bytes:
+            WriteValue((byte[])reader.Value);
+            break;
+          default:
+            throw MiscellaneousUtils.CreateArgumentOutOfRangeException("TokenType", reader.TokenType, "Unexpected token type.");
+        }
+      }
+      while (
+        // stop if we have reached the end of the token being read
+        initialDepth - 1 < reader.Depth - (IsEndToken(reader.TokenType) ? 1 : 0)
+        && reader.Read());
+    }
+
+    private void WriteConstructorDate(JsonReader reader)
+    {
+      if (!reader.Read())
+        throw JsonWriterException.Create(this, "Unexpected end when reading date constructor.", null);
+      if (reader.TokenType != JsonToken.Integer)
+        throw JsonWriterException.Create(this, "Unexpected token when reading date constructor. Expected Integer, got " + reader.TokenType, null);
+
+      long ticks = (long)reader.Value;
+      DateTime date = JsonConvert.ConvertJavaScriptTicksToDateTime(ticks);
+
+      if (!reader.Read())
+        throw JsonWriterException.Create(this, "Unexpected end when reading date constructor.", null);
+      if (reader.TokenType != JsonToken.EndConstructor)
+        throw JsonWriterException.Create(this, "Unexpected token when reading date constructor. Expected EndConstructor, got " + reader.TokenType, null);
+
+      WriteValue(date);
+    }
+
+    private bool IsEndToken(JsonToken token)
+    {
+      switch (token)
+      {
+        case JsonToken.EndObject:
+        case JsonToken.EndArray:
+        case JsonToken.EndConstructor:
+          return true;
+        default:
+          return false;
+      }
+    }
+
+    private bool IsStartToken(JsonToken token)
+    {
+      switch (token)
+      {
+        case JsonToken.StartObject:
+        case JsonToken.StartArray:
+        case JsonToken.StartConstructor:
+          return true;
+        default:
+          return false;
+      }
+    }
+
+    private void WriteEnd(JsonContainerType type)
+    {
+      switch (type)
+      {
+        case JsonContainerType.Object:
+          WriteEndObject();
+          break;
+        case JsonContainerType.Array:
+          WriteEndArray();
+          break;
+        case JsonContainerType.Constructor:
+          WriteEndConstructor();
+          break;
+        default:
+          throw JsonWriterException.Create(this, "Unexpected type when writing end: " + type, null);
+      }
+    }
+
+    private void AutoCompleteAll()
+    {
+      while (Top > 0)
+      {
+        WriteEnd();
+      }
+    }
+
+    private JsonContainerType GetTypeForCloseToken(JsonToken token)
+    {
+      switch (token)
+      {
+        case JsonToken.EndObject:
+          return JsonContainerType.Object;
+        case JsonToken.EndArray:
+          return JsonContainerType.Array;
+        case JsonToken.EndConstructor:
+          return JsonContainerType.Constructor;
+        default:
+          throw JsonWriterException.Create(this, "No type for token: " + token, null);
+      }
+    }
+
+    private JsonToken GetCloseTokenForType(JsonContainerType type)
+    {
+      switch (type)
+      {
+        case JsonContainerType.Object:
+          return JsonToken.EndObject;
+        case JsonContainerType.Array:
+          return JsonToken.EndArray;
+        case JsonContainerType.Constructor:
+          return JsonToken.EndConstructor;
+        default:
+          throw JsonWriterException.Create(this, "No close token for type: " + type, null);
+      }
+    }
+
+    private void AutoCompleteClose(JsonToken tokenBeingClosed)
+    {
+      // write closing symbol and calculate new state
+      int levelsToComplete = 0;
+      JsonContainerType type = GetTypeForCloseToken(tokenBeingClosed);
+
+      if (_currentPosition.Type == type)
+      {
+        levelsToComplete = 1;
+      }
+      else
+      {
+        int top = Top - 2;
+        for (int i = top; i >= 0; i--)
+        {
+          int currentLevel = top - i;
+
+          if (_stack[currentLevel].Type == type)
+          {
+            levelsToComplete = i + 2;
+            break;
+          }
+        }
+      }
+
+      if (levelsToComplete == 0)
+        throw JsonWriterException.Create(this, "No token to close.", null);
+
+      for (int i = 0; i < levelsToComplete; i++)
+      {
+        JsonToken token = GetCloseTokenForType(Pop());
+
+        if (_currentState == State.Property)
+          WriteNull();
+
+        if (_formatting == Formatting.Indented)
+        {
+          if (_currentState != State.ObjectStart && _currentState != State.ArrayStart)
+            WriteIndent();
+        }
+
+        WriteEnd(token);
+
+        JsonContainerType currentLevelType = Peek();
+
+        switch (currentLevelType)
+        {
+          case JsonContainerType.Object:
+            _currentState = State.Object;
+            break;
+          case JsonContainerType.Array:
+            _currentState = State.Array;
+            break;
+          case JsonContainerType.Constructor:
+            _currentState = State.Array;
+            break;
+          case JsonContainerType.None:
+            _currentState = State.Start;
+            break;
+          default:
+            throw JsonWriterException.Create(this, "Unknown JsonType: " + currentLevelType, null);
+        }
+      }
+    }
+
+    /// <summary>
+    /// Writes the specified end token.
+    /// </summary>
+    /// <param name="token">The end token to write.</param>
+    protected virtual void WriteEnd(JsonToken token)
+    {
+    }
+
+    /// <summary>
+    /// Writes indent characters.
+    /// </summary>
+    protected virtual void WriteIndent()
+    {
+    }
+
+    /// <summary>
+    /// Writes the JSON value delimiter.
+    /// </summary>
+    protected virtual void WriteValueDelimiter()
+    {
+    }
+
+    /// <summary>
+    /// Writes an indent space.
+    /// </summary>
+    protected virtual void WriteIndentSpace()
+    {
+    }
+
+    internal void AutoComplete(JsonToken tokenBeingWritten)
+    {
+      if (tokenBeingWritten != JsonToken.StartObject
+        && tokenBeingWritten != JsonToken.StartArray
+        && tokenBeingWritten != JsonToken.StartConstructor)
+        UpdateScopeWithFinishedValue();
+
+      // gets new state based on the current state and what is being written
+      State newState = StateArray[(int)tokenBeingWritten][(int)_currentState];
+
+      if (newState == State.Error)
+        throw JsonWriterException.Create(this, "Token {0} in state {1} would result in an invalid JSON object.".FormatWith(CultureInfo.InvariantCulture, tokenBeingWritten.ToString(), _currentState.ToString()), null);
+
+      if ((_currentState == State.Object || _currentState == State.Array || _currentState == State.Constructor) && tokenBeingWritten != JsonToken.Comment)
+      {
+        WriteValueDelimiter();
+      }
+      else if (_currentState == State.Property)
+      {
+        if (_formatting == Formatting.Indented)
+          WriteIndentSpace();
+      }
+
+      if (_formatting == Formatting.Indented)
+      {
+        WriteState writeState = WriteState;
+
+        // don't indent a property when it is the first token to be written (i.e. at the start)
+        if ((tokenBeingWritten == JsonToken.PropertyName && writeState != WriteState.Start) ||
+            writeState == WriteState.Array || writeState == WriteState.Constructor)
+        {
+          WriteIndent();
+        }
+      }
+
+      _currentState = newState;
+    }
+
+    #region WriteValue methods
+    /// <summary>
+    /// Writes a null value.
+    /// </summary>
+    public virtual void WriteNull()
+    {
+      AutoComplete(JsonToken.Null);
+    }
+
+    /// <summary>
+    /// Writes an undefined value.
+    /// </summary>
+    public virtual void WriteUndefined()
+    {
+      AutoComplete(JsonToken.Undefined);
+    }
+
+    /// <summary>
+    /// Writes raw JSON without changing the writer's state.
+    /// </summary>
+    /// <param name="json">The raw JSON to write.</param>
+    public virtual void WriteRaw(string json)
+    {
+    }
+
+    /// <summary>
+    /// Writes raw JSON where a value is expected and updates the writer's state.
+    /// </summary>
+    /// <param name="json">The raw JSON to write.</param>
+    public virtual void WriteRawValue(string json)
+    {
+      // hack. want writer to change state as if a value had been written
+      AutoComplete(JsonToken.Undefined);
+      WriteRaw(json);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="String"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="String"/> value to write.</param>
+    public virtual void WriteValue(string value)
+    {
+      AutoComplete(JsonToken.String);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Int32"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Int32"/> value to write.</param>
+    public virtual void WriteValue(int value)
+    {
+      AutoComplete(JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="UInt32"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="UInt32"/> value to write.</param>
+    [CLSCompliant(false)]
+    public virtual void WriteValue(uint value)
+    {
+      AutoComplete(JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Int64"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Int64"/> value to write.</param>
+    public virtual void WriteValue(long value)
+    {
+      AutoComplete(JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="UInt64"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="UInt64"/> value to write.</param>
+    [CLSCompliant(false)]
+    public virtual void WriteValue(ulong value)
+    {
+      AutoComplete(JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Single"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Single"/> value to write.</param>
+    public virtual void WriteValue(float value)
+    {
+      AutoComplete(JsonToken.Float);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Double"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Double"/> value to write.</param>
+    public virtual void WriteValue(double value)
+    {
+      AutoComplete(JsonToken.Float);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Boolean"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Boolean"/> value to write.</param>
+    public virtual void WriteValue(bool value)
+    {
+      AutoComplete(JsonToken.Boolean);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Int16"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Int16"/> value to write.</param>
+    public virtual void WriteValue(short value)
+    {
+      AutoComplete(JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="UInt16"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="UInt16"/> value to write.</param>
+    [CLSCompliant(false)]
+    public virtual void WriteValue(ushort value)
+    {
+      AutoComplete(JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Char"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Char"/> value to write.</param>
+    public virtual void WriteValue(char value)
+    {
+      AutoComplete(JsonToken.String);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Byte"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Byte"/> value to write.</param>
+    public virtual void WriteValue(byte value)
+    {
+      AutoComplete(JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="SByte"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="SByte"/> value to write.</param>
+    [CLSCompliant(false)]
+    public virtual void WriteValue(sbyte value)
+    {
+      AutoComplete(JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Decimal"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Decimal"/> value to write.</param>
+    public virtual void WriteValue(decimal value)
+    {
+      AutoComplete(JsonToken.Float);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="DateTime"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="DateTime"/> value to write.</param>
+    public virtual void WriteValue(DateTime value)
+    {
+      AutoComplete(JsonToken.Date);
+    }
+
+#if !PocketPC && !NET20
+    /// <summary>
+    /// Writes a <see cref="DateTimeOffset"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="DateTimeOffset"/> value to write.</param>
+    public virtual void WriteValue(DateTimeOffset value)
+    {
+      AutoComplete(JsonToken.Date);
+    }
+#endif
+
+    /// <summary>
+    /// Writes a <see cref="Guid"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Guid"/> value to write.</param>
+    public virtual void WriteValue(Guid value)
+    {
+      AutoComplete(JsonToken.String);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="TimeSpan"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="TimeSpan"/> value to write.</param>
+    public virtual void WriteValue(TimeSpan value)
+    {
+      AutoComplete(JsonToken.String);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Nullable{Int32}"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Nullable{Int32}"/> value to write.</param>
+    public virtual void WriteValue(int? value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        WriteValue(value.Value);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Nullable{UInt32}"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Nullable{UInt32}"/> value to write.</param>
+    [CLSCompliant(false)]
+    public virtual void WriteValue(uint? value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        WriteValue(value.Value);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Nullable{Int64}"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Nullable{Int64}"/> value to write.</param>
+    public virtual void WriteValue(long? value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        WriteValue(value.Value);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Nullable{UInt64}"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Nullable{UInt64}"/> value to write.</param>
+    [CLSCompliant(false)]
+    public virtual void WriteValue(ulong? value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        WriteValue(value.Value);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Nullable{Single}"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Nullable{Single}"/> value to write.</param>
+    public virtual void WriteValue(float? value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        WriteValue(value.Value);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Nullable{Double}"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Nullable{Double}"/> value to write.</param>
+    public virtual void WriteValue(double? value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        WriteValue(value.Value);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Nullable{Boolean}"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Nullable{Boolean}"/> value to write.</param>
+    public virtual void WriteValue(bool? value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        WriteValue(value.Value);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Nullable{Int16}"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Nullable{Int16}"/> value to write.</param>
+    public virtual void WriteValue(short? value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        WriteValue(value.Value);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Nullable{UInt16}"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Nullable{UInt16}"/> value to write.</param>
+    [CLSCompliant(false)]
+    public virtual void WriteValue(ushort? value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        WriteValue(value.Value);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Nullable{Char}"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Nullable{Char}"/> value to write.</param>
+    public virtual void WriteValue(char? value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        WriteValue(value.Value);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Nullable{Byte}"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Nullable{Byte}"/> value to write.</param>
+    public virtual void WriteValue(byte? value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        WriteValue(value.Value);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Nullable{SByte}"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Nullable{SByte}"/> value to write.</param>
+    [CLSCompliant(false)]
+    public virtual void WriteValue(sbyte? value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        WriteValue(value.Value);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Nullable{Decimal}"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Nullable{Decimal}"/> value to write.</param>
+    public virtual void WriteValue(decimal? value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        WriteValue(value.Value);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Nullable{DateTime}"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Nullable{DateTime}"/> value to write.</param>
+    public virtual void WriteValue(DateTime? value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        WriteValue(value.Value);
+    }
+
+#if !PocketPC && !NET20
+    /// <summary>
+    /// Writes a <see cref="Nullable{DateTimeOffset}"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Nullable{DateTimeOffset}"/> value to write.</param>
+    public virtual void WriteValue(DateTimeOffset? value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        WriteValue(value.Value);
+    }
+#endif
+
+    /// <summary>
+    /// Writes a <see cref="Nullable{Guid}"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Nullable{Guid}"/> value to write.</param>
+    public virtual void WriteValue(Guid? value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        WriteValue(value.Value);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Nullable{TimeSpan}"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Nullable{TimeSpan}"/> value to write.</param>
+    public virtual void WriteValue(TimeSpan? value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        WriteValue(value.Value);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="T:Byte[]"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="T:Byte[]"/> value to write.</param>
+    public virtual void WriteValue(byte[] value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        AutoComplete(JsonToken.Bytes);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Uri"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Uri"/> value to write.</param>
+    public virtual void WriteValue(Uri value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        AutoComplete(JsonToken.String);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Object"/> value.
+    /// An error will raised if the value cannot be written as a single JSON token.
+    /// </summary>
+    /// <param name="value">The <see cref="Object"/> value to write.</param>
+    public virtual void WriteValue(object value)
+    {
+      if (value == null)
+      {
+        WriteNull();
+        return;
+      }
+      else if (ConvertUtils.IsConvertible(value))
+      {
+        IConvertible convertible = ConvertUtils.ToConvertible(value);
+
+        switch (convertible.GetTypeCode())
+        {
+          case TypeCode.String:
+            WriteValue(convertible.ToString(CultureInfo.InvariantCulture));
+            return;
+          case TypeCode.Char:
+            WriteValue(convertible.ToChar(CultureInfo.InvariantCulture));
+            return;
+          case TypeCode.Boolean:
+            WriteValue(convertible.ToBoolean(CultureInfo.InvariantCulture));
+            return;
+          case TypeCode.SByte:
+            WriteValue(convertible.ToSByte(CultureInfo.InvariantCulture));
+            return;
+          case TypeCode.Int16:
+            WriteValue(convertible.ToInt16(CultureInfo.InvariantCulture));
+            return;
+          case TypeCode.UInt16:
+            WriteValue(convertible.ToUInt16(CultureInfo.InvariantCulture));
+            return;
+          case TypeCode.Int32:
+            WriteValue(convertible.ToInt32(CultureInfo.InvariantCulture));
+            return;
+          case TypeCode.Byte:
+            WriteValue(convertible.ToByte(CultureInfo.InvariantCulture));
+            return;
+          case TypeCode.UInt32:
+            WriteValue(convertible.ToUInt32(CultureInfo.InvariantCulture));
+            return;
+          case TypeCode.Int64:
+            WriteValue(convertible.ToInt64(CultureInfo.InvariantCulture));
+            return;
+          case TypeCode.UInt64:
+            WriteValue(convertible.ToUInt64(CultureInfo.InvariantCulture));
+            return;
+          case TypeCode.Single:
+            WriteValue(convertible.ToSingle(CultureInfo.InvariantCulture));
+            return;
+          case TypeCode.Double:
+            WriteValue(convertible.ToDouble(CultureInfo.InvariantCulture));
+            return;
+          case TypeCode.DateTime:
+            WriteValue(convertible.ToDateTime(CultureInfo.InvariantCulture));
+            return;
+          case TypeCode.Decimal:
+            WriteValue(convertible.ToDecimal(CultureInfo.InvariantCulture));
+            return;
+#if !(NETFX_CORE || PORTABLE)
+          case TypeCode.DBNull:
+            WriteNull();
+            return;
+#endif
+        }
+      }
+#if !PocketPC && !NET20
+      else if (value is DateTimeOffset)
+      {
+        WriteValue((DateTimeOffset)value);
+        return;
+      }
+#endif
+      else if (value is byte[])
+      {
+        WriteValue((byte[])value);
+        return;
+      }
+      else if (value is Guid)
+      {
+        WriteValue((Guid)value);
+        return;
+      }
+      else if (value is Uri)
+      {
+        WriteValue((Uri)value);
+        return;
+      }
+      else if (value is TimeSpan)
+      {
+        WriteValue((TimeSpan)value);
+        return;
+      }
+
+      throw JsonWriterException.Create(this, "Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType()), null);
+    }
+    #endregion
+
+    /// <summary>
+    /// Writes out a comment <code>/*...*/</code> containing the specified text. 
+    /// </summary>
+    /// <param name="text">Text to place inside the comment.</param>
+    public virtual void WriteComment(string text)
+    {
+      AutoComplete(JsonToken.Comment);
+    }
+
+    /// <summary>
+    /// Writes out the given white space.
+    /// </summary>
+    /// <param name="ws">The string of white space characters.</param>
+    public virtual void WriteWhitespace(string ws)
+    {
+      if (ws != null)
+      {
+        if (!StringUtils.IsWhiteSpace(ws))
+          throw JsonWriterException.Create(this, "Only white space characters should be used.", null);
+      }
+    }
+
+
+    void IDisposable.Dispose()
+    {
+      Dispose(true);
+    }
+
+    private void Dispose(bool disposing)
+    {
+      if (_currentState != State.Closed)
+        Close();
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonWriterException.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonWriterException.cs
index bc43cd3..4f614b8 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonWriterException.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/JsonWriterException.cs
@@ -1,65 +1,107 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace Newtonsoft.Json
-{
-  /// <summary>
-  /// The exception thrown when an error occurs while reading Json text.
-  /// </summary>
-  public class JsonWriterException : Exception
-  {
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonWriterException"/> class.
-    /// </summary>
-    public JsonWriterException()
-    {
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonWriterException"/> class
-    /// with a specified error message.
-    /// </summary>
-    /// <param name="message">The error message that explains the reason for the exception.</param>
-    public JsonWriterException(string message)
-      : base(message)
-    {
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonWriterException"/> class
-    /// with a specified error message and a reference to the inner exception that is the cause of this exception.
-    /// </summary>
-    /// <param name="message">The error message that explains the reason for the exception.</param>
-    /// <param name="innerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
-    public JsonWriterException(string message, Exception innerException)
-      : base(message, innerException)
-    {
-    }
-  }
-}
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Text;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// The exception thrown when an error occurs while reading Json text.
+  /// </summary>
+#if !(SILVERLIGHT || WINDOWS_PHONE || NETFX_CORE || PORTABLE)
+  [Serializable]
+#endif
+  public class JsonWriterException : JsonException
+  {
+    /// <summary>
+    /// Gets the path to the JSON where the error occurred.
+    /// </summary>
+    /// <value>The path to the JSON where the error occurred.</value>
+    public string Path { get; private set; }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonWriterException"/> class.
+    /// </summary>
+    public JsonWriterException()
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonWriterException"/> class
+    /// with a specified error message.
+    /// </summary>
+    /// <param name="message">The error message that explains the reason for the exception.</param>
+    public JsonWriterException(string message)
+      : base(message)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonWriterException"/> class
+    /// with a specified error message and a reference to the inner exception that is the cause of this exception.
+    /// </summary>
+    /// <param name="message">The error message that explains the reason for the exception.</param>
+    /// <param name="innerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
+    public JsonWriterException(string message, Exception innerException)
+      : base(message, innerException)
+    {
+    }
+
+#if !(WINDOWS_PHONE || SILVERLIGHT || NETFX_CORE || PORTABLE)
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonWriterException"/> class.
+    /// </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 null. </exception>
+    /// <exception cref="T:System.Runtime.Serialization.SerializationException">The class name is null or <see cref="P:System.Exception.HResult"/> is zero (0). </exception>
+    public JsonWriterException(SerializationInfo info, StreamingContext context)
+      : base(info, context)
+    {
+    }
+#endif
+
+    internal JsonWriterException(string message, Exception innerException, string path)
+      : base(message, innerException)
+    {
+      Path = path;
+    }
+
+    internal static JsonWriterException Create(JsonWriter writer, string message, Exception ex)
+    {
+      return Create(writer.ContainerPath, message, ex);
+    }
+
+    internal static JsonWriterException Create(string path, string message, Exception ex)
+    {
+      message = FormatExceptionMessage(null, path, message);
+
+      return new JsonWriterException(message, ex, path);
+    }
+  }
+}
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/ComponentModel/JPropertyDescriptor.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/ComponentModel/JPropertyDescriptor.cs
deleted file mode 100644
index 4f5cff4..0000000
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/ComponentModel/JPropertyDescriptor.cs
+++ /dev/null
@@ -1,175 +0,0 @@
-#region License
-// 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.
-#endregion
-
-#if !SILVERLIGHT
-using System;
-using System.ComponentModel;
-using Newtonsoft.Json.Utilities;
-
-namespace Newtonsoft.Json.Linq.ComponentModel
-{
-  /// <summary>
-  /// Represents a view of a <see cref="JProperty"/>.
-  /// </summary>
-  public class JPropertyDescriptor : PropertyDescriptor
-  {
-    private readonly Type _propertyType;
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JPropertyDescriptor"/> class.
-    /// </summary>
-    /// <param name="name">The name.</param>
-    /// <param name="propertyType">Type of the property.</param>
-    public JPropertyDescriptor(string name, Type propertyType)
-      : base(name, null)
-    {
-      ValidationUtils.ArgumentNotNull(name, "name");
-      ValidationUtils.ArgumentNotNull(propertyType, "propertyType");
-
-      _propertyType = propertyType;
-    }
-
-    private static JObject CastInstance(object instance)
-    {
-      return (JObject)instance;
-    }
-
-    /// <summary>
-    /// When overridden in a derived class, returns whether resetting an object changes its value.
-    /// </summary>
-    /// <returns>
-    /// true if resetting the component changes its value; otherwise, false.
-    /// </returns>
-    /// <param name="component">The component to test for reset capability. 
-    ///                 </param>
-    public override bool CanResetValue(object component)
-    {
-      return false;
-    }
-
-    /// <summary>
-    /// When overridden in a derived class, gets the current value of the property on a component.
-    /// </summary>
-    /// <returns>
-    /// The value of a property for a given component.
-    /// </returns>
-    /// <param name="component">The component with the property for which to retrieve the value. 
-    ///                 </param>
-    public override object GetValue(object component)
-    {
-      JToken token = CastInstance(component)[Name];
-      //if (token is JValue)
-      //  return ((JValue) token).Value;
-
-      return token;
-    }
-
-    /// <summary>
-    /// When overridden in a derived class, resets the value for this property of the component to the default value.
-    /// </summary>
-    /// <param name="component">The component with the property value that is to be reset to the default value. 
-    ///                 </param>
-    public override void ResetValue(object component)
-    {
-    }
-
-    /// <summary>
-    /// When overridden in a derived class, sets the value of the component to a different value.
-    /// </summary>
-    /// <param name="component">The component with the property value that is to be set. 
-    ///                 </param><param name="value">The new value. 
-    ///                 </param>
-    public override void SetValue(object component, object value)
-    {
-      JToken token = (value is JToken) ? (JToken) value : new JValue(value);
-
-      CastInstance(component)[Name] = token;
-    }
-
-    /// <summary>
-    /// When overridden in a derived class, determines a value indicating whether the value of this property needs to be persisted.
-    /// </summary>
-    /// <returns>
-    /// true if the property should be persisted; otherwise, false.
-    /// </returns>
-    /// <param name="component">The component with the property to be examined for persistence. 
-    ///                 </param>
-    public override bool ShouldSerializeValue(object component)
-    {
-      return false;
-    }
-
-    /// <summary>
-    /// When overridden in a derived class, gets the type of the component this property is bound to.
-    /// </summary>
-    /// <returns>
-    /// A <see cref="T:System.Type"/> that represents the type of component this property is bound to. When the <see cref="M:System.ComponentModel.PropertyDescriptor.GetValue(System.Object)"/> or <see cref="M:System.ComponentModel.PropertyDescriptor.SetValue(System.Object,System.Object)"/> methods are invoked, the object specified might be an instance of this type.
-    /// </returns>
-    public override Type ComponentType
-    {
-      get { return typeof(JObject); }
-    }
-
-    /// <summary>
-    /// When overridden in a derived class, gets a value indicating whether this property is read-only.
-    /// </summary>
-    /// <returns>
-    /// true if the property is read-only; otherwise, false.
-    /// </returns>
-    public override bool IsReadOnly
-    {
-      get { return false; }
-    }
-
-    /// <summary>
-    /// When overridden in a derived class, gets the type of the property.
-    /// </summary>
-    /// <returns>
-    /// A <see cref="T:System.Type"/> that represents the type of the property.
-    /// </returns>
-    public override Type PropertyType
-    {
-      get { return _propertyType; }
-    }
-
-    /// <summary>
-    /// Gets the hash code for the name of the member.
-    /// </summary>
-    /// <value></value>
-    /// <returns>
-    /// The hash code for the name of the member.
-    /// </returns>
-    protected override int NameHashCode
-    {
-      get
-      {
-        // override property to fix up an error in its documentation
-        int nameHashCode = base.NameHashCode;
-        return nameHashCode;
-      }
-    }
-  }
-}
-#endif
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/ComponentModel/JTypeDescriptionProvider.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/ComponentModel/JTypeDescriptionProvider.cs
deleted file mode 100644
index c5f5fc1..0000000
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/ComponentModel/JTypeDescriptionProvider.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-#region License
-// 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.
-#endregion
-
-#if !PocketPC && !SILVERLIGHT
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Linq;
-using System.Text;
-
-namespace Newtonsoft.Json.Linq.ComponentModel
-{
-  internal class JTypeDescriptionProvider : TypeDescriptionProvider
-  {
-    public override ICustomTypeDescriptor GetTypeDescriptor(Type type, object instance)
-    {
-      JObject o = instance as JObject;
-      if (o != null)
-        return new JTypeDescriptor(o);
-      
-      return base.GetTypeDescriptor(type, instance);
-    }
-  }
-}
-#endif
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/ComponentModel/JTypeDescriptor.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/ComponentModel/JTypeDescriptor.cs
deleted file mode 100644
index 604e9b9..0000000
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/ComponentModel/JTypeDescriptor.cs
+++ /dev/null
@@ -1,209 +0,0 @@
-#region License
-// 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.
-#endregion
-
-#if !SILVERLIGHT
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using Newtonsoft.Json.Utilities;
-
-namespace Newtonsoft.Json.Linq.ComponentModel
-{
-  /// <summary>
-  /// Represents a view of a <see cref="JObject"/>.
-  /// </summary>
-  public class JTypeDescriptor : ICustomTypeDescriptor
-  {
-    private readonly JObject _value;
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JTypeDescriptor"/> class.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    public JTypeDescriptor(JObject value)
-    {
-      ValidationUtils.ArgumentNotNull(value, "value");
-      _value = value;
-    }
-
-    /// <summary>
-    /// Returns the properties for this instance of a component.
-    /// </summary>
-    /// <returns>
-    /// A <see cref="T:System.ComponentModel.PropertyDescriptorCollection"/> that represents the properties for this component instance.
-    /// </returns>
-    public virtual PropertyDescriptorCollection GetProperties()
-    {
-      return GetProperties(null);
-    }
-
-    private static Type GetTokenPropertyType(JToken token)
-    {
-      if (token is JValue)
-      {
-        JValue v = (JValue) token;
-        return (v.Value != null) ? v.Value.GetType() : typeof (object);
-      }
-
-      return token.GetType();
-    }
-
-    /// <summary>
-    /// Returns the properties for this instance of a component using the attribute array as a filter.
-    /// </summary>
-    /// <param name="attributes">An array of type <see cref="T:System.Attribute"/> that is used as a filter.</param>
-    /// <returns>
-    /// A <see cref="T:System.ComponentModel.PropertyDescriptorCollection"/> that represents the filtered properties for this component instance.
-    /// </returns>
-    public virtual PropertyDescriptorCollection GetProperties(Attribute[] attributes)
-    {
-      PropertyDescriptorCollection descriptors = new PropertyDescriptorCollection(null);
-
-      if (_value != null)
-      {
-        foreach (KeyValuePair<string, JToken> propertyValue in _value)
-        {
-          descriptors.Add(new JPropertyDescriptor(propertyValue.Key, GetTokenPropertyType(propertyValue.Value)));
-        }
-      }
-
-      return descriptors;
-    }
-
-    /// <summary>
-    /// Returns a collection of custom attributes for this instance of a component.
-    /// </summary>
-    /// <returns>
-    /// An <see cref="T:System.ComponentModel.AttributeCollection"/> containing the attributes for this object.
-    /// </returns>
-    public AttributeCollection GetAttributes()
-    {
-      return AttributeCollection.Empty;
-    }
-
-    /// <summary>
-    /// Returns the class name of this instance of a component.
-    /// </summary>
-    /// <returns>
-    /// The class name of the object, or null if the class does not have a name.
-    /// </returns>
-    public string GetClassName()
-    {
-      return null;
-    }
-
-    /// <summary>
-    /// Returns the name of this instance of a component.
-    /// </summary>
-    /// <returns>
-    /// The name of the object, or null if the object does not have a name.
-    /// </returns>
-    public string GetComponentName()
-    {
-      return null;
-    }
-
-    /// <summary>
-    /// Returns a type converter for this instance of a component.
-    /// </summary>
-    /// <returns>
-    /// A <see cref="T:System.ComponentModel.TypeConverter"/> that is the converter for this object, or null if there is no <see cref="T:System.ComponentModel.TypeConverter"/> for this object.
-    /// </returns>
-    public TypeConverter GetConverter()
-    {
-      return new TypeConverter();
-    }
-
-    /// <summary>
-    /// Returns the default event for this instance of a component.
-    /// </summary>
-    /// <returns>
-    /// An <see cref="T:System.ComponentModel.EventDescriptor"/> that represents the default event for this object, or null if this object does not have events.
-    /// </returns>
-    public EventDescriptor GetDefaultEvent()
-    {
-      return null;
-    }
-
-    /// <summary>
-    /// Returns the default property for this instance of a component.
-    /// </summary>
-    /// <returns>
-    /// A <see cref="T:System.ComponentModel.PropertyDescriptor"/> that represents the default property for this object, or null if this object does not have properties.
-    /// </returns>
-    public PropertyDescriptor GetDefaultProperty()
-    {
-      return null;
-    }
-
-    /// <summary>
-    /// Returns an editor of the specified type for this instance of a component.
-    /// </summary>
-    /// <param name="editorBaseType">A <see cref="T:System.Type"/> that represents the editor for this object.</param>
-    /// <returns>
-    /// An <see cref="T:System.Object"/> of the specified type that is the editor for this object, or null if the editor cannot be found.
-    /// </returns>
-    public object GetEditor(Type editorBaseType)
-    {
-      return null;
-    }
-
-    /// <summary>
-    /// Returns the events for this instance of a component using the specified attribute array as a filter.
-    /// </summary>
-    /// <param name="attributes">An array of type <see cref="T:System.Attribute"/> that is used as a filter.</param>
-    /// <returns>
-    /// An <see cref="T:System.ComponentModel.EventDescriptorCollection"/> that represents the filtered events for this component instance.
-    /// </returns>
-    public EventDescriptorCollection GetEvents(Attribute[] attributes)
-    {
-      return EventDescriptorCollection.Empty;
-    }
-
-    /// <summary>
-    /// Returns the events for this instance of a component.
-    /// </summary>
-    /// <returns>
-    /// An <see cref="T:System.ComponentModel.EventDescriptorCollection"/> that represents the events for this component instance.
-    /// </returns>
-    public EventDescriptorCollection GetEvents()
-    {
-      return EventDescriptorCollection.Empty;
-    }
-
-    /// <summary>
-    /// Returns an object that contains the property described by the specified property descriptor.
-    /// </summary>
-    /// <param name="pd">A <see cref="T:System.ComponentModel.PropertyDescriptor"/> that represents the property whose owner is to be found.</param>
-    /// <returns>
-    /// An <see cref="T:System.Object"/> that represents the owner of the specified property.
-    /// </returns>
-    public object GetPropertyOwner(PropertyDescriptor pd)
-    {
-      return null;
-    }
-  }
-}
-#endif
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/Extensions.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/Extensions.cs
index 716c5c3..3942461 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/Extensions.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/Extensions.cs
@@ -1,316 +1,311 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Newtonsoft.Json.Utilities;
-using System.Collections;
-using System.Globalization;
-
-namespace Newtonsoft.Json.Linq
-{
-  /// <summary>
-  /// Contains the LINQ to JSON extension methods.
-  /// </summary>
-  public static class Extensions
-  {
-    /// <summary>
-    /// Returns a collection of tokens that contains the ancestors of every token in the source collection.
-    /// </summary>
-    /// <typeparam name="T">The type of the objects in source, constrained to <see cref="JToken"/>.</typeparam>
-    /// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
-    /// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the ancestors of every node in the source collection.</returns>
-    public static IJEnumerable<JToken> Ancestors<T>(this IEnumerable<T> source) where T : JToken
-    {
-      ValidationUtils.ArgumentNotNull(source, "source");
-
-      return source.SelectMany(j => j.Ancestors()).AsJEnumerable();
-    }
-
-    //TODO
-    //public static IEnumerable<JObject> AncestorsAndSelf<T>(this IEnumerable<T> source) where T : JObject
-    //{
-    //  ValidationUtils.ArgumentNotNull(source, "source");
-
-    //  return source.SelectMany(j => j.AncestorsAndSelf());
-    //}
-
-    /// <summary>
-    /// Returns a collection of tokens that contains the descendants of every token in the source collection.
-    /// </summary>
-    /// <typeparam name="T">The type of the objects in source, constrained to <see cref="JContainer"/>.</typeparam>
-    /// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
-    /// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the descendants of every node in the source collection.</returns>
-    public static IJEnumerable<JToken> Descendants<T>(this IEnumerable<T> source) where T : JContainer
-    {
-      ValidationUtils.ArgumentNotNull(source, "source");
-
-      return source.SelectMany(j => j.Descendants()).AsJEnumerable();
-    }
-
-    //TODO
-    //public static IEnumerable<JObject> DescendantsAndSelf<T>(this IEnumerable<T> source) where T : JContainer
-    //{
-    //  ValidationUtils.ArgumentNotNull(source, "source");
-
-    //  return source.SelectMany(j => j.DescendantsAndSelf());
-    //}
-
-    /// <summary>
-    /// Returns a collection of child properties of every object in the source collection.
-    /// </summary>
-    /// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JObject"/> that contains the source collection.</param>
-    /// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JProperty"/> that contains the properties of every object in the source collection.</returns>
-    public static IJEnumerable<JProperty> Properties(this IEnumerable<JObject> source)
-    {
-      ValidationUtils.ArgumentNotNull(source, "source");
-
-      return source.SelectMany(d => d.Properties()).AsJEnumerable();
-    }
-
-    /// <summary>
-    /// Returns a collection of child values of every object in the source collection with the given key.
-    /// </summary>
-    /// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
-    /// <param name="key">The token key.</param>
-    /// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the values of every node in the source collection with the given key.</returns>
-    public static IJEnumerable<JToken> Values(this IEnumerable<JToken> source, object key)
-    {
-      return Values<JToken, JToken>(source, key).AsJEnumerable();
-    }
-
-    /// <summary>
-    /// Returns a collection of child values of every object in the source collection.
-    /// </summary>
-    /// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
-    /// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the values of every node in the source collection.</returns>
-    public static IJEnumerable<JToken> Values(this IEnumerable<JToken> source)
-    {
-      return source.Values(null);
-    }
-
-    /// <summary>
-    /// Returns a collection of converted child values of every object in the source collection with the given key.
-    /// </summary>
-    /// <typeparam name="U">The type to convert the values to.</typeparam>
-    /// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
-    /// <param name="key">The token key.</param>
-    /// <returns>An <see cref="IEnumerable{T}"/> that contains the converted values of every node in the source collection with the given key.</returns>
-    public static IEnumerable<U> Values<U>(this IEnumerable<JToken> source, object key)
-    {
-      return Values<JToken, U>(source, key);
-    }
-
-    /// <summary>
-    /// Returns a collection of converted child values of every object in the source collection.
-    /// </summary>
-    /// <typeparam name="U">The type to convert the values to.</typeparam>
-    /// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
-    /// <returns>An <see cref="IEnumerable{T}"/> that contains the converted values of every node in the source collection.</returns>
-    public static IEnumerable<U> Values<U>(this IEnumerable<JToken> source)
-    {
-      return Values<JToken, U>(source, null);
-    }
-
-    /// <summary>
-    /// Converts the value.
-    /// </summary>
-    /// <typeparam name="U">The type to convert the value to.</typeparam>
-    /// <param name="value">A <see cref="JToken"/> cast as a <see cref="IEnumerable{T}"/> of <see cref="JToken"/>.</param>
-    /// <returns>A converted value.</returns>
-    public static U Value<U>(this IEnumerable<JToken> value)
-    {
-      return value.Value<JToken, U>();
-    }
-
-    /// <summary>
-    /// Converts the value.
-    /// </summary>
-    /// <typeparam name="T">The source collection type.</typeparam>
-    /// <typeparam name="U">The type to convert the value to.</typeparam>
-    /// <param name="value">A <see cref="JToken"/> cast as a <see cref="IEnumerable{T}"/> of <see cref="JToken"/>.</param>
-    /// <returns>A converted value.</returns>
-    public static U Value<T, U>(this IEnumerable<T> value) where T : JToken
-    {
-      ValidationUtils.ArgumentNotNull(value, "source");
-
-      JToken token = value as JToken;
-      if (token == null)
-        throw new ArgumentException("Source value must be a JToken.");
-
-      return token.Convert<JToken, U>();
-    }
-
-
-    internal static IEnumerable<U> Values<T, U>(this IEnumerable<T> source, object key) where T : JToken
-    {
-      ValidationUtils.ArgumentNotNull(source, "source");
-
-      foreach (JToken token in source)
-      {
-        if (key == null)
-        {
-          if (token is JValue)
-          {
-            yield return Convert<JValue, U>((JValue)token);
-          }
-          else
-          {
-            foreach (JToken t in token.Children())
-            {
-              yield return t.Convert<JToken, U>(); ;
-            }
-          }
-        }
-        else
-        {
-          JToken value = token[key];
-          if (value != null)
-            yield return value.Convert<JToken, U>();
-        }
-      }
-
-      yield break;
-    }
-
-    //TODO
-    //public static IEnumerable<T> InDocumentOrder<T>(this IEnumerable<T> source) where T : JObject;
-
-    //public static IEnumerable<JToken> Children<T>(this IEnumerable<T> source) where T : JToken
-    //{
-    //  ValidationUtils.ArgumentNotNull(source, "source");
-
-    //  return source.SelectMany(c => c.Children());
-    //}
-
-    /// <summary>
-    /// Returns a collection of child tokens of every array in the source collection.
-    /// </summary>
-    /// <typeparam name="T">The source collection type.</typeparam>
-    /// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
-    /// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the values of every node in the source collection.</returns>
-    public static IJEnumerable<JToken> Children<T>(this IEnumerable<T> source) where T : JToken
-    {
-      return Children<T, JToken>(source).AsJEnumerable();
-    }
-
-    /// <summary>
-    /// Returns a collection of converted child tokens of every array in the source collection.
-    /// </summary>
-    /// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
-    /// <typeparam name="U">The type to convert the values to.</typeparam>
-    /// <typeparam name="T">The source collection type.</typeparam>
-    /// <returns>An <see cref="IEnumerable{T}"/> that contains the converted values of every node in the source collection.</returns>
-    public static IEnumerable<U> Children<T, U>(this IEnumerable<T> source) where T : JToken
-    {
-      ValidationUtils.ArgumentNotNull(source, "source");
-
-      return source.SelectMany(c => c.Children()).Convert<JToken, U>();
-    }
-
-    internal static IEnumerable<U> Convert<T, U>(this IEnumerable<T> source) where T : JToken
-    {
-      ValidationUtils.ArgumentNotNull(source, "source");
-
-      bool cast = typeof(JToken).IsAssignableFrom(typeof(U));
-
-      foreach (JToken token in source)
-      {
-        yield return Convert<JToken, U>(token, cast);
-      }
-    }
-
-    internal static U Convert<T, U>(this T token) where T : JToken
-    {
-      bool cast = typeof(JToken).IsAssignableFrom(typeof(U));
-
-      return Convert<T, U>(token, cast);
-    }
-
-    internal static U Convert<T, U>(this T token, bool cast) where T : JToken
-    {
-      if (cast)
-      {
-        // HACK
-        return (U)(object)token;
-      }
-      else
-      {
-        if (token == null)
-          return default(U);
-
-        JValue value = token as JValue;
-        if (value == null)
-          throw new InvalidCastException("Cannot cast {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, token.GetType(), typeof(T)));
-
-        if (value.Value is U)
-          return (U)value.Value;
-
-        Type targetType = typeof(U);
-
-        if (ReflectionUtils.IsNullableType(targetType))
-        {
-          if (value.Value == null)
-            return default(U);
-
-          targetType = Nullable.GetUnderlyingType(targetType);
-        }
-
-        return (U)System.Convert.ChangeType(value.Value, targetType, CultureInfo.InvariantCulture);
-      }
-    }
-
-    //TODO
-    //public static void Remove<T>(this IEnumerable<T> source) where T : JContainer;
-
-    /// <summary>
-    /// Returns the input typed as <see cref="IJEnumerable{T}"/>.
-    /// </summary>
-    /// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
-    /// <returns>The input typed as <see cref="IJEnumerable{T}"/>.</returns>
-    public static IJEnumerable<JToken> AsJEnumerable(this IEnumerable<JToken> source)
-    {
-      return source.AsJEnumerable<JToken>();
-    }
-
-    /// <summary>
-    /// Returns the input typed as <see cref="IJEnumerable{T}"/>.
-    /// </summary>
-    /// <typeparam name="T">The source collection type.</typeparam>
-    /// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
-    /// <returns>The input typed as <see cref="IJEnumerable{T}"/>.</returns>
-    public static IJEnumerable<T> AsJEnumerable<T>(this IEnumerable<T> source) where T : JToken
-    {
-      if (source == null)
-        return null;
-      else if (source is IJEnumerable<T>)
-        return (IJEnumerable<T>)source;
-      else
-        return new JEnumerable<T>(source);
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using Newtonsoft.Json.Utilities;
+using System.Globalization;
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#else
+using System.Linq;
+#endif
+
+namespace Newtonsoft.Json.Linq
+{
+  /// <summary>
+  /// Contains the LINQ to JSON extension methods.
+  /// </summary>
+  public static class Extensions
+  {
+    /// <summary>
+    /// Returns a collection of tokens that contains the ancestors of every token in the source collection.
+    /// </summary>
+    /// <typeparam name="T">The type of the objects in source, constrained to <see cref="JToken"/>.</typeparam>
+    /// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
+    /// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the ancestors of every node in the source collection.</returns>
+    public static IJEnumerable<JToken> Ancestors<T>(this IEnumerable<T> source) where T : JToken
+    {
+      ValidationUtils.ArgumentNotNull(source, "source");
+
+      return source.SelectMany(j => j.Ancestors()).AsJEnumerable();
+    }
+
+    //TODO
+    //public static IEnumerable<JObject> AncestorsAndSelf<T>(this IEnumerable<T> source) where T : JObject
+    //{
+    //  ValidationUtils.ArgumentNotNull(source, "source");
+
+    //  return source.SelectMany(j => j.AncestorsAndSelf());
+    //}
+
+    /// <summary>
+    /// Returns a collection of tokens that contains the descendants of every token in the source collection.
+    /// </summary>
+    /// <typeparam name="T">The type of the objects in source, constrained to <see cref="JContainer"/>.</typeparam>
+    /// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
+    /// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the descendants of every node in the source collection.</returns>
+    public static IJEnumerable<JToken> Descendants<T>(this IEnumerable<T> source) where T : JContainer
+    {
+      ValidationUtils.ArgumentNotNull(source, "source");
+
+      return source.SelectMany(j => j.Descendants()).AsJEnumerable();
+    }
+
+    //TODO
+    //public static IEnumerable<JObject> DescendantsAndSelf<T>(this IEnumerable<T> source) where T : JContainer
+    //{
+    //  ValidationUtils.ArgumentNotNull(source, "source");
+
+    //  return source.SelectMany(j => j.DescendantsAndSelf());
+    //}
+
+    /// <summary>
+    /// Returns a collection of child properties of every object in the source collection.
+    /// </summary>
+    /// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JObject"/> that contains the source collection.</param>
+    /// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JProperty"/> that contains the properties of every object in the source collection.</returns>
+    public static IJEnumerable<JProperty> Properties(this IEnumerable<JObject> source)
+    {
+      ValidationUtils.ArgumentNotNull(source, "source");
+
+      return source.SelectMany(d => d.Properties()).AsJEnumerable();
+    }
+
+    /// <summary>
+    /// Returns a collection of child values of every object in the source collection with the given key.
+    /// </summary>
+    /// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
+    /// <param name="key">The token key.</param>
+    /// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the values of every node in the source collection with the given key.</returns>
+    public static IJEnumerable<JToken> Values(this IEnumerable<JToken> source, object key)
+    {
+      return Values<JToken, JToken>(source, key).AsJEnumerable();
+    }
+
+    /// <summary>
+    /// Returns a collection of child values of every object in the source collection.
+    /// </summary>
+    /// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
+    /// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the values of every node in the source collection.</returns>
+    public static IJEnumerable<JToken> Values(this IEnumerable<JToken> source)
+    {
+      return source.Values(null);
+    }
+
+    /// <summary>
+    /// Returns a collection of converted child values of every object in the source collection with the given key.
+    /// </summary>
+    /// <typeparam name="U">The type to convert the values to.</typeparam>
+    /// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
+    /// <param name="key">The token key.</param>
+    /// <returns>An <see cref="IEnumerable{T}"/> that contains the converted values of every node in the source collection with the given key.</returns>
+    public static IEnumerable<U> Values<U>(this IEnumerable<JToken> source, object key)
+    {
+      return Values<JToken, U>(source, key);
+    }
+
+    /// <summary>
+    /// Returns a collection of converted child values of every object in the source collection.
+    /// </summary>
+    /// <typeparam name="U">The type to convert the values to.</typeparam>
+    /// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
+    /// <returns>An <see cref="IEnumerable{T}"/> that contains the converted values of every node in the source collection.</returns>
+    public static IEnumerable<U> Values<U>(this IEnumerable<JToken> source)
+    {
+      return Values<JToken, U>(source, null);
+    }
+
+    /// <summary>
+    /// Converts the value.
+    /// </summary>
+    /// <typeparam name="U">The type to convert the value to.</typeparam>
+    /// <param name="value">A <see cref="JToken"/> cast as a <see cref="IEnumerable{T}"/> of <see cref="JToken"/>.</param>
+    /// <returns>A converted value.</returns>
+    public static U Value<U>(this IEnumerable<JToken> value)
+    {
+      return value.Value<JToken, U>();
+    }
+
+    /// <summary>
+    /// Converts the value.
+    /// </summary>
+    /// <typeparam name="T">The source collection type.</typeparam>
+    /// <typeparam name="U">The type to convert the value to.</typeparam>
+    /// <param name="value">A <see cref="JToken"/> cast as a <see cref="IEnumerable{T}"/> of <see cref="JToken"/>.</param>
+    /// <returns>A converted value.</returns>
+    public static U Value<T, U>(this IEnumerable<T> value) where T : JToken
+    {
+      ValidationUtils.ArgumentNotNull(value, "source");
+
+      JToken token = value as JToken;
+      if (token == null)
+        throw new ArgumentException("Source value must be a JToken.");
+
+      return token.Convert<JToken, U>();
+    }
+
+
+    internal static IEnumerable<U> Values<T, U>(this IEnumerable<T> source, object key) where T : JToken
+    {
+      ValidationUtils.ArgumentNotNull(source, "source");
+
+      foreach (JToken token in source)
+      {
+        if (key == null)
+        {
+          if (token is JValue)
+          {
+            yield return Convert<JValue, U>((JValue)token);
+          }
+          else
+          {
+            foreach (JToken t in token.Children())
+            {
+              yield return t.Convert<JToken, U>();
+            }
+          }
+        }
+        else
+        {
+          JToken value = token[key];
+          if (value != null)
+            yield return value.Convert<JToken, U>();
+        }
+      }
+
+      yield break;
+    }
+
+    //TODO
+    //public static IEnumerable<T> InDocumentOrder<T>(this IEnumerable<T> source) where T : JObject;
+
+    //public static IEnumerable<JToken> Children<T>(this IEnumerable<T> source) where T : JToken
+    //{
+    //  ValidationUtils.ArgumentNotNull(source, "source");
+
+    //  return source.SelectMany(c => c.Children());
+    //}
+
+    /// <summary>
+    /// Returns a collection of child tokens of every array in the source collection.
+    /// </summary>
+    /// <typeparam name="T">The source collection type.</typeparam>
+    /// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
+    /// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the values of every node in the source collection.</returns>
+    public static IJEnumerable<JToken> Children<T>(this IEnumerable<T> source) where T : JToken
+    {
+      return Children<T, JToken>(source).AsJEnumerable();
+    }
+
+    /// <summary>
+    /// Returns a collection of converted child tokens of every array in the source collection.
+    /// </summary>
+    /// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
+    /// <typeparam name="U">The type to convert the values to.</typeparam>
+    /// <typeparam name="T">The source collection type.</typeparam>
+    /// <returns>An <see cref="IEnumerable{T}"/> that contains the converted values of every node in the source collection.</returns>
+    public static IEnumerable<U> Children<T, U>(this IEnumerable<T> source) where T : JToken
+    {
+      ValidationUtils.ArgumentNotNull(source, "source");
+
+      return source.SelectMany(c => c.Children()).Convert<JToken, U>();
+    }
+
+    internal static IEnumerable<U> Convert<T, U>(this IEnumerable<T> source) where T : JToken
+    {
+      ValidationUtils.ArgumentNotNull(source, "source");
+
+      foreach (T token in source)
+      {
+        yield return Convert<JToken, U>(token);
+      }
+    }
+
+    internal static U Convert<T, U>(this T token) where T : JToken
+    {
+      if (token == null)
+        return default(U);
+
+      if (token is U
+        // don't want to cast JValue to its interfaces, want to get the internal value
+        && typeof(U) != typeof(IComparable) && typeof(U) != typeof(IFormattable))
+      {
+        // HACK
+        return (U)(object)token;
+      }
+      else
+      {
+        JValue value = token as JValue;
+        if (value == null)
+          throw new InvalidCastException("Cannot cast {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, token.GetType(), typeof(T)));
+
+        if (value.Value is U)
+          return (U)value.Value;
+
+        Type targetType = typeof(U);
+
+        if (ReflectionUtils.IsNullableType(targetType))
+        {
+          if (value.Value == null)
+            return default(U);
+
+          targetType = Nullable.GetUnderlyingType(targetType);
+        }
+
+        return (U)System.Convert.ChangeType(value.Value, targetType, CultureInfo.InvariantCulture);
+      }
+    }
+
+    //TODO
+    //public static void Remove<T>(this IEnumerable<T> source) where T : JContainer;
+
+    /// <summary>
+    /// Returns the input typed as <see cref="IJEnumerable{T}"/>.
+    /// </summary>
+    /// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
+    /// <returns>The input typed as <see cref="IJEnumerable{T}"/>.</returns>
+    public static IJEnumerable<JToken> AsJEnumerable(this IEnumerable<JToken> source)
+    {
+      return source.AsJEnumerable<JToken>();
+    }
+
+    /// <summary>
+    /// Returns the input typed as <see cref="IJEnumerable{T}"/>.
+    /// </summary>
+    /// <typeparam name="T">The source collection type.</typeparam>
+    /// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
+    /// <returns>The input typed as <see cref="IJEnumerable{T}"/>.</returns>
+    public static IJEnumerable<T> AsJEnumerable<T>(this IEnumerable<T> source) where T : JToken
+    {
+      if (source == null)
+        return null;
+      else if (source is IJEnumerable<T>)
+        return (IJEnumerable<T>)source;
+      else
+        return new JEnumerable<T>(source);
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/IJEnumerable.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/IJEnumerable.cs
index a758fcb..d33faf4 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/IJEnumerable.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/IJEnumerable.cs
@@ -1,20 +1,46 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Newtonsoft.Json.Linq
-{
-  /// <summary>
-  /// Represents a collection of <see cref="JToken"/> objects.
-  /// </summary>
-  /// <typeparam name="T">The type of token</typeparam>
-  public interface IJEnumerable<T> : IEnumerable<T> where T : JToken
-  {
-    /// <summary>
-    /// Gets the <see cref="IJEnumerable{JToken}"/> with the specified key.
-    /// </summary>
-    /// <value></value>
-    IJEnumerable<JToken> this[object key] { get; }
-  }
+#region License
+// 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.
+#endregion
+
+using System.Collections.Generic;
+
+namespace Newtonsoft.Json.Linq
+{
+  /// <summary>
+  /// Represents a collection of <see cref="JToken"/> objects.
+  /// </summary>
+  /// <typeparam name="T">The type of token</typeparam>
+  public interface IJEnumerable<
+#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE)
+    out
+#endif
+    T> : IEnumerable<T> where T : JToken
+  {
+    /// <summary>
+    /// Gets the <see cref="IJEnumerable{JToken}"/> with the specified key.
+    /// </summary>
+    /// <value></value>
+    IJEnumerable<JToken> this[object key] { get; }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JArray.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JArray.cs
index 82708cc..d91254f 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JArray.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JArray.cs
@@ -1,327 +1,339 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Linq;
-using System.Text;
-using Newtonsoft.Json.Utilities;
-using System.IO;
-using System.Globalization;
-
-namespace Newtonsoft.Json.Linq
-{
-  /// <summary>
-  /// Represents a JSON array.
-  /// </summary>
-  public class JArray : JContainer, IList<JToken>
-  {
-    /// <summary>
-    /// Gets the node type for this <see cref="JToken"/>.
-    /// </summary>
-    /// <value>The type.</value>
-    public override JTokenType Type
-    {
-      get { return JTokenType.Array; }
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JArray"/> class.
-    /// </summary>
-    public JArray()
-    {
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JArray"/> class from another <see cref="JArray"/> object.
-    /// </summary>
-    /// <param name="other">A <see cref="JArray"/> object to copy from.</param>
-    public JArray(JArray other)
-      : base(other)
-    {
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JArray"/> class with the specified content.
-    /// </summary>
-    /// <param name="content">The contents of the array.</param>
-    public JArray(params object[] content)
-      : this((object)content)
-    {
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JArray"/> class with the specified content.
-    /// </summary>
-    /// <param name="content">The contents of the array.</param>
-    public JArray(object content)
-    {
-      Add(content);
-    }
-
-    internal override bool DeepEquals(JToken node)
-    {
-      JArray t = node as JArray;
-      return (t != null && ContentsEqual(t));
-    }
-
-    internal override JToken CloneToken()
-    {
-      return new JArray(this);
-    }
-
-    /// <summary>
-    /// Loads an <see cref="JArray"/> from a <see cref="JsonReader"/>. 
-    /// </summary>
-    /// <param name="reader">A <see cref="JsonReader"/> that will be read for the content of the <see cref="JArray"/>.</param>
-    /// <returns>A <see cref="JArray"/> that contains the JSON that was read from the specified <see cref="JsonReader"/>.</returns>
-    public static JArray Load(JsonReader reader)
-    {
-      if (reader.TokenType == JsonToken.None)
-      {
-        if (!reader.Read())
-          throw new Exception("Error reading JArray from JsonReader.");
-      }
-      if (reader.TokenType != JsonToken.StartArray)
-        throw new Exception("Error reading JArray from JsonReader. Current JsonReader item is not an array: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
-
-      JArray a = new JArray();
-      a.SetLineInfo(reader as IJsonLineInfo);
-
-      if (!reader.Read())
-        throw new Exception("Error reading JArray from JsonReader.");
-
-      a.ReadContentFrom(reader);
-
-      return a;
-    }
-
-    /// <summary>
-    /// Load a <see cref="JArray"/> from a string that contains JSON.
-    /// </summary>
-    /// <param name="json">A <see cref="String"/> that contains JSON.</param>
-    /// <returns>A <see cref="JArray"/> populated from the string that contains JSON.</returns>
-    public static JArray Parse(string json)
-    {
-      JsonReader jsonReader = new JsonTextReader(new StringReader(json));
-
-      return Load(jsonReader);
-    }
-
-    /// <summary>
-    /// Creates a <see cref="JArray"/> from an object.
-    /// </summary>
-    /// <param name="o">The object that will be used to create <see cref="JArray"/>.</param>
-    /// <returns>A <see cref="JArray"/> with the values of the specified object</returns>
-    public static new JArray FromObject(object o)
-    {
-      return FromObject(o, new JsonSerializer());
-    }
-
-    /// <summary>
-    /// Creates a <see cref="JArray"/> from an object.
-    /// </summary>
-    /// <param name="o">The object that will be used to create <see cref="JArray"/>.</param>
-    /// <param name="jsonSerializer">The <see cref="JsonSerializer"/> that will be used to read the object.</param>
-    /// <returns>A <see cref="JArray"/> with the values of the specified object</returns>
-    public static new JArray FromObject(object o, JsonSerializer jsonSerializer)
-    {
-      JToken token = FromObjectInternal(o, jsonSerializer);
-
-      if (token.Type != JTokenType.Array)
-        throw new ArgumentException("Object serialized to {0}. JArray instance expected.".FormatWith(CultureInfo.InvariantCulture, token.Type));
-
-      return (JArray)token;
-    }
-
-    /// <summary>
-    /// Writes this token to a <see cref="JsonWriter"/>.
-    /// </summary>
-    /// <param name="writer">A <see cref="JsonWriter"/> into which this method will write.</param>
-    /// <param name="converters">A collection of <see cref="JsonConverter"/> which will be used when writing the token.</param>
-    public override void WriteTo(JsonWriter writer, params JsonConverter[] converters)
-    {
-      writer.WriteStartArray();
-
-      foreach (JToken token in Children())
-      {
-        token.WriteTo(writer, converters);
-      }
-
-      writer.WriteEndArray();
-    }
-
-    /// <summary>
-    /// Gets the <see cref="JToken"/> with the specified key.
-    /// </summary>
-    /// <value>The <see cref="JToken"/> with the specified key.</value>
-    public override JToken this[object key]
-    {
-      get
-      {
-        ValidationUtils.ArgumentNotNull(key, "o");
-
-        if (!(key is int))
-          throw new ArgumentException("Accessed JArray values with invalid key value: {0}. Array position index expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key)));
-
-        return GetItem((int)key);
-      }
-      set
-      {
-        ValidationUtils.ArgumentNotNull(key, "o");
-
-        if (!(key is int))
-          throw new ArgumentException("Set JArray values with invalid key value: {0}. Array position index expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key)));
-
-        SetItem((int)key, value);
-      }
-    }
-
-    /// <summary>
-    /// Gets or sets the <see cref="Newtonsoft.Json.Linq.JToken"/> at the specified index.
-    /// </summary>
-    /// <value></value>
-    public JToken this[int index]
-    {
-      get { return GetItem(index); }
-      set { SetItem(index, value); }
-    }
-
-    #region IList<JToken> Members
-
-    /// <summary>
-    /// Determines the index of a specific item in the <see cref="T:System.Collections.Generic.IList`1"/>.
-    /// </summary>
-    /// <param name="item">The object to locate in the <see cref="T:System.Collections.Generic.IList`1"/>.</param>
-    /// <returns>
-    /// The index of <paramref name="item"/> if found in the list; otherwise, -1.
-    /// </returns>
-    public int IndexOf(JToken item)
-    {
-      return IndexOfItem(item);
-    }
-
-    /// <summary>
-    /// Inserts an item to the <see cref="T:System.Collections.Generic.IList`1"/> at the specified index.
-    /// </summary>
-    /// <param name="index">The zero-based index at which <paramref name="item"/> should be inserted.</param>
-    /// <param name="item">The object to insert into the <see cref="T:System.Collections.Generic.IList`1"/>.</param>
-    /// <exception cref="T:System.ArgumentOutOfRangeException">
-    /// 	<paramref name="index"/> is not a valid index in the <see cref="T:System.Collections.Generic.IList`1"/>.</exception>
-    /// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.IList`1"/> is read-only.</exception>
-    public void Insert(int index, JToken item)
-    {
-      InsertItem(index, item);
-    }
-
-    /// <summary>
-    /// Removes the <see cref="T:System.Collections.Generic.IList`1"/> item at the specified index.
-    /// </summary>
-    /// <param name="index">The zero-based index of the item to remove.</param>
-    /// <exception cref="T:System.ArgumentOutOfRangeException">
-    /// 	<paramref name="index"/> is not a valid index in the <see cref="T:System.Collections.Generic.IList`1"/>.</exception>
-    /// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.IList`1"/> is read-only.</exception>
-    public void RemoveAt(int index)
-    {
-      RemoveItemAt(index);
-    }
-
-    #endregion
-
-    #region ICollection<JToken> Members
-
-    /// <summary>
-    /// Adds an item to the <see cref="T:System.Collections.Generic.ICollection`1"/>.
-    /// </summary>
-    /// <param name="item">The object to add to the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param>
-    /// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only.</exception>
-    public void Add(JToken item)
-    {
-      Add((object)item);
-    }
-
-    /// <summary>
-    /// Removes all items from the <see cref="T:System.Collections.Generic.ICollection`1"/>.
-    /// </summary>
-    /// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only. </exception>
-    public void Clear()
-    {
-      ClearItems();
-    }
-
-    /// <summary>
-    /// Determines whether the <see cref="T:System.Collections.Generic.ICollection`1"/> contains a specific value.
-    /// </summary>
-    /// <param name="item">The object to locate in the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param>
-    /// <returns>
-    /// true if <paramref name="item"/> is found in the <see cref="T:System.Collections.Generic.ICollection`1"/>; otherwise, false.
-    /// </returns>
-    public bool Contains(JToken item)
-    {
-      return ContainsItem(item);
-    }
-
-    void ICollection<JToken>.CopyTo(JToken[] array, int arrayIndex)
-    {
-      CopyItemsTo(array, arrayIndex);
-    }
-
-    /// <summary>
-    /// Gets the number of elements contained in the <see cref="T:System.Collections.Generic.ICollection`1"/>.
-    /// </summary>
-    /// <value></value>
-    /// <returns>The number of elements contained in the <see cref="T:System.Collections.Generic.ICollection`1"/>.</returns>
-    public int Count
-    {
-      get { return CountItems(); }
-    }
-
-    bool ICollection<JToken>.IsReadOnly
-    {
-      get { return false; }
-    }
-
-    /// <summary>
-    /// Removes the first occurrence of a specific object from the <see cref="T:System.Collections.Generic.ICollection`1"/>.
-    /// </summary>
-    /// <param name="item">The object to remove from the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param>
-    /// <returns>
-    /// true if <paramref name="item"/> was successfully removed from the <see cref="T:System.Collections.Generic.ICollection`1"/>; otherwise, false. This method also returns false if <paramref name="item"/> is not found in the original <see cref="T:System.Collections.Generic.ICollection`1"/>.
-    /// </returns>
-    /// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only.</exception>
-    public bool Remove(JToken item)
-    {
-      return RemoveItem(item);
-    }
-
-    #endregion
-
-    internal override int GetDeepHashCode()
-    {
-      return ContentsHashCode();
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using Newtonsoft.Json.Utilities;
+using System.IO;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Linq
+{
+  /// <summary>
+  /// Represents a JSON array.
+  /// </summary>
+  /// <example>
+  ///   <code lang="cs" source="..\Src\Newtonsoft.Json.Tests\Documentation\LinqToJsonTests.cs" region="LinqToJsonCreateParseArray" title="Parsing a JSON Array from Text" />
+  /// </example>
+  public class JArray : JContainer, IList<JToken>
+  {
+    private readonly IList<JToken> _values = new List<JToken>();
+
+    /// <summary>
+    /// Gets the container's children tokens.
+    /// </summary>
+    /// <value>The container's children tokens.</value>
+    protected override IList<JToken> ChildrenTokens
+    {
+      get { return _values; }
+    }
+
+    /// <summary>
+    /// Gets the node type for this <see cref="JToken"/>.
+    /// </summary>
+    /// <value>The type.</value>
+    public override JTokenType Type
+    {
+      get { return JTokenType.Array; }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JArray"/> class.
+    /// </summary>
+    public JArray()
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JArray"/> class from another <see cref="JArray"/> object.
+    /// </summary>
+    /// <param name="other">A <see cref="JArray"/> object to copy from.</param>
+    public JArray(JArray other)
+      : base(other)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JArray"/> class with the specified content.
+    /// </summary>
+    /// <param name="content">The contents of the array.</param>
+    public JArray(params object[] content)
+      : this((object)content)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JArray"/> class with the specified content.
+    /// </summary>
+    /// <param name="content">The contents of the array.</param>
+    public JArray(object content)
+    {
+      Add(content);
+    }
+
+    internal override bool DeepEquals(JToken node)
+    {
+      JArray t = node as JArray;
+      return (t != null && ContentsEqual(t));
+    }
+
+    internal override JToken CloneToken()
+    {
+      return new JArray(this);
+    }
+
+    /// <summary>
+    /// Loads an <see cref="JArray"/> from a <see cref="JsonReader"/>. 
+    /// </summary>
+    /// <param name="reader">A <see cref="JsonReader"/> that will be read for the content of the <see cref="JArray"/>.</param>
+    /// <returns>A <see cref="JArray"/> that contains the JSON that was read from the specified <see cref="JsonReader"/>.</returns>
+    public static new JArray Load(JsonReader reader)
+    {
+      if (reader.TokenType == JsonToken.None)
+      {
+        if (!reader.Read())
+          throw JsonReaderException.Create(reader, "Error reading JArray from JsonReader.");
+      }
+
+      while (reader.TokenType == JsonToken.Comment)
+      {
+        reader.Read();
+      }
+
+      if (reader.TokenType != JsonToken.StartArray)
+        throw JsonReaderException.Create(reader, "Error reading JArray from JsonReader. Current JsonReader item is not an array: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
+
+      JArray a = new JArray();
+      a.SetLineInfo(reader as IJsonLineInfo);
+
+      a.ReadTokenFrom(reader);
+
+      return a;
+    }
+
+    /// <summary>
+    /// Load a <see cref="JArray"/> from a string that contains JSON.
+    /// </summary>
+    /// <param name="json">A <see cref="String"/> that contains JSON.</param>
+    /// <returns>A <see cref="JArray"/> populated from the string that contains JSON.</returns>
+    /// <example>
+    ///   <code lang="cs" source="..\Src\Newtonsoft.Json.Tests\Documentation\LinqToJsonTests.cs" region="LinqToJsonCreateParseArray" title="Parsing a JSON Array from Text" />
+    /// </example>
+    public static new JArray Parse(string json)
+    {
+      JsonReader reader = new JsonTextReader(new StringReader(json));
+
+      JArray a = Load(reader);
+
+      if (reader.Read() && reader.TokenType != JsonToken.Comment)
+        throw JsonReaderException.Create(reader, "Additional text found in JSON string after parsing content.");
+
+      return a;
+    }
+
+    /// <summary>
+    /// Creates a <see cref="JArray"/> from an object.
+    /// </summary>
+    /// <param name="o">The object that will be used to create <see cref="JArray"/>.</param>
+    /// <returns>A <see cref="JArray"/> with the values of the specified object</returns>
+    public static new JArray FromObject(object o)
+    {
+      return FromObject(o, new JsonSerializer());
+    }
+
+    /// <summary>
+    /// Creates a <see cref="JArray"/> from an object.
+    /// </summary>
+    /// <param name="o">The object that will be used to create <see cref="JArray"/>.</param>
+    /// <param name="jsonSerializer">The <see cref="JsonSerializer"/> that will be used to read the object.</param>
+    /// <returns>A <see cref="JArray"/> with the values of the specified object</returns>
+    public static new JArray FromObject(object o, JsonSerializer jsonSerializer)
+    {
+      JToken token = FromObjectInternal(o, jsonSerializer);
+
+      if (token.Type != JTokenType.Array)
+        throw new ArgumentException("Object serialized to {0}. JArray instance expected.".FormatWith(CultureInfo.InvariantCulture, token.Type));
+
+      return (JArray)token;
+    }
+
+    /// <summary>
+    /// Writes this token to a <see cref="JsonWriter"/>.
+    /// </summary>
+    /// <param name="writer">A <see cref="JsonWriter"/> into which this method will write.</param>
+    /// <param name="converters">A collection of <see cref="JsonConverter"/> which will be used when writing the token.</param>
+    public override void WriteTo(JsonWriter writer, params JsonConverter[] converters)
+    {
+      writer.WriteStartArray();
+
+      foreach (JToken token in ChildrenTokens)
+      {
+        token.WriteTo(writer, converters);
+      }
+
+      writer.WriteEndArray();
+    }
+
+    /// <summary>
+    /// Gets the <see cref="JToken"/> with the specified key.
+    /// </summary>
+    /// <value>The <see cref="JToken"/> with the specified key.</value>
+    public override JToken this[object key]
+    {
+      get
+      {
+        ValidationUtils.ArgumentNotNull(key, "o");
+
+        if (!(key is int))
+          throw new ArgumentException("Accessed JArray values with invalid key value: {0}. Array position index expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key)));
+
+        return GetItem((int)key);
+      }
+      set
+      {
+        ValidationUtils.ArgumentNotNull(key, "o");
+
+        if (!(key is int))
+          throw new ArgumentException("Set JArray values with invalid key value: {0}. Array position index expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key)));
+
+        SetItem((int)key, value);
+      }
+    }
+
+    /// <summary>
+    /// Gets or sets the <see cref="Newtonsoft.Json.Linq.JToken"/> at the specified index.
+    /// </summary>
+    /// <value></value>
+    public JToken this[int index]
+    {
+      get { return GetItem(index); }
+      set { SetItem(index, value); }
+    }
+
+    #region IList<JToken> Members
+
+    /// <summary>
+    /// Determines the index of a specific item in the <see cref="T:System.Collections.Generic.IList`1"/>.
+    /// </summary>
+    /// <param name="item">The object to locate in the <see cref="T:System.Collections.Generic.IList`1"/>.</param>
+    /// <returns>
+    /// The index of <paramref name="item"/> if found in the list; otherwise, -1.
+    /// </returns>
+    public int IndexOf(JToken item)
+    {
+      return IndexOfItem(item);
+    }
+
+    /// <summary>
+    /// Inserts an item to the <see cref="T:System.Collections.Generic.IList`1"/> at the specified index.
+    /// </summary>
+    /// <param name="index">The zero-based index at which <paramref name="item"/> should be inserted.</param>
+    /// <param name="item">The object to insert into the <see cref="T:System.Collections.Generic.IList`1"/>.</param>
+    /// <exception cref="T:System.ArgumentOutOfRangeException">
+    /// 	<paramref name="index"/> is not a valid index in the <see cref="T:System.Collections.Generic.IList`1"/>.</exception>
+    /// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.IList`1"/> is read-only.</exception>
+    public void Insert(int index, JToken item)
+    {
+      InsertItem(index, item, false);
+    }
+
+    /// <summary>
+    /// Removes the <see cref="T:System.Collections.Generic.IList`1"/> item at the specified index.
+    /// </summary>
+    /// <param name="index">The zero-based index of the item to remove.</param>
+    /// <exception cref="T:System.ArgumentOutOfRangeException">
+    /// 	<paramref name="index"/> is not a valid index in the <see cref="T:System.Collections.Generic.IList`1"/>.</exception>
+    /// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.IList`1"/> is read-only.</exception>
+    public void RemoveAt(int index)
+    {
+      RemoveItemAt(index);
+    }
+
+    #endregion
+
+    #region ICollection<JToken> Members
+
+    /// <summary>
+    /// Adds an item to the <see cref="T:System.Collections.Generic.ICollection`1"/>.
+    /// </summary>
+    /// <param name="item">The object to add to the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param>
+    /// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only.</exception>
+    public void Add(JToken item)
+    {
+      Add((object)item);
+    }
+
+    /// <summary>
+    /// Removes all items from the <see cref="T:System.Collections.Generic.ICollection`1"/>.
+    /// </summary>
+    /// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only. </exception>
+    public void Clear()
+    {
+      ClearItems();
+    }
+
+    /// <summary>
+    /// Determines whether the <see cref="T:System.Collections.Generic.ICollection`1"/> contains a specific value.
+    /// </summary>
+    /// <param name="item">The object to locate in the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param>
+    /// <returns>
+    /// true if <paramref name="item"/> is found in the <see cref="T:System.Collections.Generic.ICollection`1"/>; otherwise, false.
+    /// </returns>
+    public bool Contains(JToken item)
+    {
+      return ContainsItem(item);
+    }
+
+    void ICollection<JToken>.CopyTo(JToken[] array, int arrayIndex)
+    {
+      CopyItemsTo(array, arrayIndex);
+    }
+
+    bool ICollection<JToken>.IsReadOnly
+    {
+      get { return false; }
+    }
+
+    /// <summary>
+    /// Removes the first occurrence of a specific object from the <see cref="T:System.Collections.Generic.ICollection`1"/>.
+    /// </summary>
+    /// <param name="item">The object to remove from the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param>
+    /// <returns>
+    /// true if <paramref name="item"/> was successfully removed from the <see cref="T:System.Collections.Generic.ICollection`1"/>; otherwise, false. This method also returns false if <paramref name="item"/> is not found in the original <see cref="T:System.Collections.Generic.ICollection`1"/>.
+    /// </returns>
+    /// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only.</exception>
+    public bool Remove(JToken item)
+    {
+      return RemoveItem(item);
+    }
+
+    #endregion
+
+    internal override int GetDeepHashCode()
+    {
+      return ContentsHashCode();
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JConstructor.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JConstructor.cs
index 296d1ae..bb37617 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JConstructor.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JConstructor.cs
@@ -1,196 +1,206 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Newtonsoft.Json.Utilities;
-using System.Globalization;
-
-namespace Newtonsoft.Json.Linq
-{
-  /// <summary>
-  /// Represents a JSON constructor.
-  /// </summary>
-  public class JConstructor : JContainer
-  {
-    private string _name;
-
-    /// <summary>
-    /// Gets or sets the name of this constructor.
-    /// </summary>
-    /// <value>The constructor name.</value>
-    public string Name
-    {
-      get { return _name; }
-      set { _name = value; }
-    }
-
-    /// <summary>
-    /// Gets the node type for this <see cref="JToken"/>.
-    /// </summary>
-    /// <value>The type.</value>
-    public override JTokenType Type
-    {
-      get { return JTokenType.Constructor; }
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JConstructor"/> class.
-    /// </summary>
-    public JConstructor()
-    {
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JConstructor"/> class from another <see cref="JConstructor"/> object.
-    /// </summary>
-    /// <param name="other">A <see cref="JConstructor"/> object to copy from.</param>
-    public JConstructor(JConstructor other)
-      : base(other)
-    {
-      _name = other.Name;
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JConstructor"/> class with the specified name and content.
-    /// </summary>
-    /// <param name="name">The constructor name.</param>
-    /// <param name="content">The contents of the constructor.</param>
-    public JConstructor(string name, params object[] content)
-      : this(name, (object)content)
-    {
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JConstructor"/> class with the specified name and content.
-    /// </summary>
-    /// <param name="name">The constructor name.</param>
-    /// <param name="content">The contents of the constructor.</param>
-    public JConstructor(string name, object content)
-      : this(name)
-    {
-      Add(content);
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JConstructor"/> class with the specified name.
-    /// </summary>
-    /// <param name="name">The constructor name.</param>
-    public JConstructor(string name)
-    {
-      ValidationUtils.ArgumentNotNullOrEmpty(name, "name");
-
-      _name = name;
-    }
-
-    internal override bool DeepEquals(JToken node)
-    {
-      JConstructor c = node as JConstructor;
-      return (c != null && _name == c.Name && ContentsEqual(c));
-    }
-
-    internal override JToken CloneToken()
-    {
-      return new JConstructor(this);
-    }
-
-    /// <summary>
-    /// Writes this token to a <see cref="JsonWriter"/>.
-    /// </summary>
-    /// <param name="writer">A <see cref="JsonWriter"/> into which this method will write.</param>
-    /// <param name="converters">A collection of <see cref="JsonConverter"/> which will be used when writing the token.</param>
-    public override void WriteTo(JsonWriter writer, params JsonConverter[] converters)
-    {
-      writer.WriteStartConstructor(_name);
-
-      foreach (JToken token in Children())
-      {
-        token.WriteTo(writer, converters);
-      }
-
-      writer.WriteEndConstructor();
-    }
-
-    /// <summary>
-    /// Gets the <see cref="JToken"/> with the specified key.
-    /// </summary>
-    /// <value>The <see cref="JToken"/> with the specified key.</value>
-    public override JToken this[object key]
-    {
-      get
-      {
-        ValidationUtils.ArgumentNotNull(key, "o");
-
-        if (!(key is int))
-          throw new ArgumentException("Accessed JConstructor values with invalid key value: {0}. Argument position index expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key)));
-
-        return GetItem((int)key);
-      }
-      set
-      {
-        ValidationUtils.ArgumentNotNull(key, "o");
-
-        if (!(key is int))
-          throw new ArgumentException("Set JConstructor values with invalid key value: {0}. Argument position index expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key)));
-
-        SetItem((int)key, value);
-      }
-    }
-
-    internal override int GetDeepHashCode()
-    {
-      return _name.GetHashCode() ^ ContentsHashCode();
-    }
-
-    /// <summary>
-    /// Loads an <see cref="JConstructor"/> from a <see cref="JsonReader"/>. 
-    /// </summary>
-    /// <param name="reader">A <see cref="JsonReader"/> that will be read for the content of the <see cref="JConstructor"/>.</param>
-    /// <returns>A <see cref="JConstructor"/> that contains the JSON that was read from the specified <see cref="JsonReader"/>.</returns>
-    public static JConstructor Load(JsonReader reader)
-    {
-      if (reader.TokenType == JsonToken.None)
-      {
-        if (!reader.Read())
-          throw new Exception("Error reading JConstructor from JsonReader.");
-      }
-
-      if (reader.TokenType != JsonToken.StartConstructor)
-        throw new Exception("Error reading JConstructor from JsonReader. Current JsonReader item is not a constructor: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
-
-      JConstructor c = new JConstructor((string)reader.Value);
-      c.SetLineInfo(reader as IJsonLineInfo);
-
-      if (!reader.Read())
-        throw new Exception("Error reading JConstructor from JsonReader.");
-
-      c.ReadContentFrom(reader);
-
-      return c;
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using Newtonsoft.Json.Utilities;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Linq
+{
+  /// <summary>
+  /// Represents a JSON constructor.
+  /// </summary>
+  public class JConstructor : JContainer
+  {
+    private string _name;
+    private readonly IList<JToken> _values = new List<JToken>();
+
+    /// <summary>
+    /// Gets the container's children tokens.
+    /// </summary>
+    /// <value>The container's children tokens.</value>
+    protected override IList<JToken> ChildrenTokens
+    {
+      get { return _values; }
+    }
+
+    /// <summary>
+    /// Gets or sets the name of this constructor.
+    /// </summary>
+    /// <value>The constructor name.</value>
+    public string Name
+    {
+      get { return _name; }
+      set { _name = value; }
+    }
+
+    /// <summary>
+    /// Gets the node type for this <see cref="JToken"/>.
+    /// </summary>
+    /// <value>The type.</value>
+    public override JTokenType Type
+    {
+      get { return JTokenType.Constructor; }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JConstructor"/> class.
+    /// </summary>
+    public JConstructor()
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JConstructor"/> class from another <see cref="JConstructor"/> object.
+    /// </summary>
+    /// <param name="other">A <see cref="JConstructor"/> object to copy from.</param>
+    public JConstructor(JConstructor other)
+      : base(other)
+    {
+      _name = other.Name;
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JConstructor"/> class with the specified name and content.
+    /// </summary>
+    /// <param name="name">The constructor name.</param>
+    /// <param name="content">The contents of the constructor.</param>
+    public JConstructor(string name, params object[] content)
+      : this(name, (object)content)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JConstructor"/> class with the specified name and content.
+    /// </summary>
+    /// <param name="name">The constructor name.</param>
+    /// <param name="content">The contents of the constructor.</param>
+    public JConstructor(string name, object content)
+      : this(name)
+    {
+      Add(content);
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JConstructor"/> class with the specified name.
+    /// </summary>
+    /// <param name="name">The constructor name.</param>
+    public JConstructor(string name)
+    {
+      ValidationUtils.ArgumentNotNullOrEmpty(name, "name");
+
+      _name = name;
+    }
+
+    internal override bool DeepEquals(JToken node)
+    {
+      JConstructor c = node as JConstructor;
+      return (c != null && _name == c.Name && ContentsEqual(c));
+    }
+
+    internal override JToken CloneToken()
+    {
+      return new JConstructor(this);
+    }
+
+    /// <summary>
+    /// Writes this token to a <see cref="JsonWriter"/>.
+    /// </summary>
+    /// <param name="writer">A <see cref="JsonWriter"/> into which this method will write.</param>
+    /// <param name="converters">A collection of <see cref="JsonConverter"/> which will be used when writing the token.</param>
+    public override void WriteTo(JsonWriter writer, params JsonConverter[] converters)
+    {
+      writer.WriteStartConstructor(_name);
+
+      foreach (JToken token in Children())
+      {
+        token.WriteTo(writer, converters);
+      }
+
+      writer.WriteEndConstructor();
+    }
+
+    /// <summary>
+    /// Gets the <see cref="JToken"/> with the specified key.
+    /// </summary>
+    /// <value>The <see cref="JToken"/> with the specified key.</value>
+    public override JToken this[object key]
+    {
+      get
+      {
+        ValidationUtils.ArgumentNotNull(key, "o");
+
+        if (!(key is int))
+          throw new ArgumentException("Accessed JConstructor values with invalid key value: {0}. Argument position index expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key)));
+
+        return GetItem((int)key);
+      }
+      set
+      {
+        ValidationUtils.ArgumentNotNull(key, "o");
+
+        if (!(key is int))
+          throw new ArgumentException("Set JConstructor values with invalid key value: {0}. Argument position index expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key)));
+
+        SetItem((int)key, value);
+      }
+    }
+
+    internal override int GetDeepHashCode()
+    {
+      return _name.GetHashCode() ^ ContentsHashCode();
+    }
+
+    /// <summary>
+    /// Loads an <see cref="JConstructor"/> from a <see cref="JsonReader"/>. 
+    /// </summary>
+    /// <param name="reader">A <see cref="JsonReader"/> that will be read for the content of the <see cref="JConstructor"/>.</param>
+    /// <returns>A <see cref="JConstructor"/> that contains the JSON that was read from the specified <see cref="JsonReader"/>.</returns>
+    public static new JConstructor Load(JsonReader reader)
+    {
+      if (reader.TokenType == JsonToken.None)
+      {
+        if (!reader.Read())
+          throw JsonReaderException.Create(reader, "Error reading JConstructor from JsonReader.");
+      }
+
+      while (reader.TokenType == JsonToken.Comment)
+      {
+        reader.Read();
+      }
+
+      if (reader.TokenType != JsonToken.StartConstructor)
+        throw JsonReaderException.Create(reader, "Error reading JConstructor from JsonReader. Current JsonReader item is not a constructor: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
+
+      JConstructor c = new JConstructor((string)reader.Value);
+      c.SetLineInfo(reader as IJsonLineInfo);
+
+      c.ReadTokenFrom(reader);
+
+      return c;
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JContainer.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JContainer.cs
index b5e995d..f106e85 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JContainer.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JContainer.cs
@@ -1,1047 +1,989 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
-using Newtonsoft.Json.Utilities;
-using System.Collections;
-using System.Diagnostics;
-using System.Globalization;
-using System.ComponentModel;
-using System.Collections.Specialized;
-#if !SILVERLIGHT
-using Newtonsoft.Json.Linq.ComponentModel;
-#endif
-
-namespace Newtonsoft.Json.Linq
-{
-  /// <summary>
-  /// Represents a token that can contain other tokens.
-  /// </summary>
-  public abstract class JContainer : JToken, IList<JToken>
-#if !SILVERLIGHT
-    , ITypedList, IBindingList
-#else
-    , IList, INotifyCollectionChanged
-#endif
-  {
-#if !SILVERLIGHT
-    /// <summary>
-    /// Occurs when the list changes or an item in the list changes.
-    /// </summary>
-    public event ListChangedEventHandler ListChanged;
-
-    /// <summary>
-    /// Occurs before an item is added to the collection.
-    /// </summary>
-    public event AddingNewEventHandler AddingNew;
-#else
-    /// <summary>
-    /// Occurs when the items list of the collection has changed, or the collection is reset.
-    /// </summary>
-    public event NotifyCollectionChangedEventHandler CollectionChanged;
-#endif
-
-    private JToken _content;
-    private object _syncRoot;
-    private bool _busy;
-
-    internal JToken Content
-    {
-      get { return _content; }
-      set { _content = value; }
-    }
-
-    internal JContainer()
-    {
-    }
-
-    internal JContainer(JContainer other)
-    {
-      ValidationUtils.ArgumentNotNull(other, "c");
-
-      JToken content = other.Last;
-      if (content != null)
-      {
-        do
-        {
-          content = content._next;
-          Add(content.CloneToken());
-        }
-        while (content != other.Last);
-      }
-    }
-
-    internal void CheckReentrancy()
-    {
-      if (_busy)
-        throw new InvalidOperationException("Cannot change {0} during a collection change event.".FormatWith(CultureInfo.InvariantCulture, GetType()));
-    }
-
- #if !SILVERLIGHT
-    /// <summary>
-    /// Raises the <see cref="AddingNew"/> event.
-    /// </summary>
-    /// <param name="e">The <see cref="AddingNewEventArgs"/> instance containing the event data.</param>
-    protected virtual void OnAddingNew(AddingNewEventArgs e)
-    {
-      AddingNewEventHandler handler = AddingNew;
-      if (handler != null)
-        handler(this, e);
-    }
-
-    /// <summary>
-    /// Raises the <see cref="ListChanged"/> event.
-    /// </summary>
-    /// <param name="e">The <see cref="ListChangedEventArgs"/> instance containing the event data.</param>
-    protected virtual void OnListChanged(ListChangedEventArgs e)
-    {
-      ListChangedEventHandler handler = ListChanged;
-
-      if (handler != null)
-      {
-        _busy = true;
-        try
-        {
-          handler(this, e);
-        }
-        finally
-        {
-          _busy = false;
-        }
-      }
-    }
-#else
-    /// <summary>
-    /// Raises the <see cref="CollectionChanged"/> event.
-    /// </summary>
-    /// <param name="e">The <see cref="NotifyCollectionChangedEventArgs"/> instance containing the event data.</param>
-    protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
-    {
-      NotifyCollectionChangedEventHandler handler = CollectionChanged;
-
-      if (handler != null)
-      {
-        _busy = true;
-        try
-        {
-          handler(this, e);
-        }
-        finally
-        {
-          _busy = false;
-        }
-      }
-    }
-#endif
-
-    /// <summary>
-    /// Gets a value indicating whether this token has childen tokens.
-    /// </summary>
-    /// <value>
-    /// 	<c>true</c> if this token has child values; otherwise, <c>false</c>.
-    /// </value>
-    public override bool HasValues
-    {
-      get { return (_content != null); }
-    }
-
-    internal bool ContentsEqual(JContainer container)
-    {
-      JToken t1 = First;
-      JToken t2 = container.First;
-
-      if (t1 == t2)
-        return true;
-
-      do
-      {
-        if (t1 == null && t2 == null)
-          return true;
-
-        if (t1 != null && t2 != null && t1.DeepEquals(t2))
-        {
-          t1 = (t1 != Last) ? t1.Next : null;
-          t2 = (t2 != container.Last) ? t2.Next : null;
-        }
-        else
-        {
-          return false;
-        }
-      }
-      while (true);
-    }
-
-    /// <summary>
-    /// Get the first child token of this token.
-    /// </summary>
-    /// <value>
-    /// A <see cref="JToken"/> containing the first child token of the <see cref="JToken"/>.
-    /// </value>
-    public override JToken First
-    {
-      get
-      {
-        if (Last == null)
-          return null;
-
-        return Last._next;
-      }
-    }
-
-    /// <summary>
-    /// Get the last child token of this token.
-    /// </summary>
-    /// <value>
-    /// A <see cref="JToken"/> containing the last child token of the <see cref="JToken"/>.
-    /// </value>
-    public override JToken Last
-    {
-      [DebuggerStepThrough]
-      get { return _content; }
-    }
-
-    /// <summary>
-    /// Returns a collection of the child tokens of this token, in document order.
-    /// </summary>
-    /// <returns>
-    /// An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> containing the child tokens of this <see cref="JToken"/>, in document order.
-    /// </returns>
-    public override JEnumerable<JToken> Children()
-    {
-      return new JEnumerable<JToken>(ChildrenInternal());
-    }
-
-    internal IEnumerable<JToken> ChildrenInternal()
-    {
-      JToken first = First;
-      JToken current = first;
-      if (current == null)
-        yield break;
-
-      do
-      {
-        yield return current;
-      }
-      while ((current = current.Next) != null);
-    }
-
-    /// <summary>
-    /// Returns a collection of the child values of this token, in document order.
-    /// </summary>
-    /// <typeparam name="T">The type to convert the values to.</typeparam>
-    /// <returns>
-    /// A <see cref="IEnumerable{T}"/> containing the child values of this <see cref="JToken"/>, in document order.
-    /// </returns>
-    public override IEnumerable<T> Values<T>()
-    {
-      return Children().Convert<JToken, T>();
-    }
-
-    /// <summary>
-    /// Returns a collection of the descendant tokens for this token in document order.
-    /// </summary>
-    /// <returns>An <see cref="IEnumerable{JToken}"/> containing the descendant tokens of the <see cref="JToken"/>.</returns>
-    public IEnumerable<JToken> Descendants()
-    {
-      foreach (JToken o in Children())
-      {
-        yield return o;
-        JContainer c = o as JContainer;
-        if (c != null)
-        {
-          foreach (JToken d in c.Descendants())
-          {
-            yield return d;
-          }
-        }
-      }
-    }
-
-    internal bool IsMultiContent(object content)
-    {
-      return (content is IEnumerable && !(content is string) && !(content is JToken) && !(content is byte[]));
-    }
-
-    internal virtual void AddItem(bool isLast, JToken previous, JToken item)
-    {
-      CheckReentrancy();
-
-      ValidateToken(item, null);
-
-      item = EnsureParentToken(item);
-
-      JToken next = (previous != null) ? previous._next : item;
-
-      item.Parent = this;
-      item.Next = next;
-
-      if (previous != null)
-        previous.Next = item;
-
-      if (isLast || previous == null)
-        _content = item;
-
-#if !SILVERLIGHT
-      if (ListChanged != null)
-        OnListChanged(new ListChangedEventArgs(ListChangedType.ItemAdded, IndexOfItem(item)));
-#else
-      if (CollectionChanged != null)
-        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, IndexOfItem(item)));
-#endif
-    }
-
-    internal JToken EnsureParentToken(JToken item)
-    {
-      if (item.Parent != null)
-      {
-        item = item.CloneToken();
-      }
-      else
-      {
-        // check whether attempting to add a token to itself
-        JContainer parent = this;
-        while (parent.Parent != null)
-        {
-          parent = parent.Parent;
-        }
-        if (item == parent)
-        {
-          item = item.CloneToken();
-        }
-      }
-      return item;
-    }
-
-    internal void AddInternal(bool isLast, JToken previous, object content)
-    {
-      if (IsMultiContent(content))
-      {
-        IEnumerable enumerable = (IEnumerable) content;
-
-        JToken multiPrevious = previous;
-        foreach (object c in enumerable)
-        {
-          AddInternal(isLast, multiPrevious, c);
-          multiPrevious = (multiPrevious != null) ? multiPrevious._next : Last;
-        }
-      }
-      else
-      {
-        JToken item = CreateFromContent(content);
-
-        AddItem(isLast, previous, item);
-      }
-    }
-
-    internal int IndexOfItem(JToken item)
-    {
-      int index = 0;
-      foreach (JToken token in Children())
-      {
-        if (token == item)
-          return index;
-
-        index++;
-      }
-
-      return -1;
-    }
-
-    internal virtual void InsertItem(int index, JToken item)
-    {
-      if (index == 0)
-      {
-        AddFirst(item);
-      }
-      else
-      {
-        JToken token = GetItem(index);
-        AddInternal(false, token.Previous, item);
-      }
-    }
-
-    internal virtual void RemoveItemAt(int index)
-    {
-      if (index < 0)
-        throw new ArgumentOutOfRangeException("index", "index is less than 0.");
-
-      CheckReentrancy();
-
-      int currentIndex = 0;
-      foreach (JToken token in Children())
-      {
-        if (index == currentIndex)
-        {
-          token.Remove();
-
-#if !SILVERLIGHT
-          OnListChanged(new ListChangedEventArgs(ListChangedType.ItemDeleted, index));
-#else
-          OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, token, index));
-#endif
-
-          return;
-        }
-
-        currentIndex++;
-      }
-
-      throw new ArgumentOutOfRangeException("index", "index is equal to or greater than Count.");
-    }
-
-    internal virtual bool RemoveItem(JToken item)
-    {
-      if (item == null || item.Parent != this)
-        return false;
-
-      CheckReentrancy();
-
-      JToken content = _content;
-
-      int itemIndex = 0;
-      while (content._next != item)
-      {
-        itemIndex++;
-        content = content._next;
-      }
-      if (content == item)
-      {
-        // token is containers last child
-        _content = null;
-      }
-      else
-      {
-        if (_content == item)
-        {
-          _content = content;
-        }
-        content._next = item._next;
-      }
-      item.Parent = null;
-      item.Next = null;
-
-#if !SILVERLIGHT
-      OnListChanged(new ListChangedEventArgs(ListChangedType.ItemDeleted, itemIndex));
-#else
-      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, itemIndex));
-#endif
-
-      return true;
-    }
-
-    internal virtual JToken GetItem(int index)
-    {
-      return Children().ElementAt(index);
-    }
-
-    internal virtual void SetItem(int index, JToken item)
-    {
-      CheckReentrancy();
-
-      JToken token = GetItem(index);
-      token.Replace(item);
-
-#if !SILVERLIGHT
-      OnListChanged(new ListChangedEventArgs(ListChangedType.ItemChanged, index));
-#else
-      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, item, token, index));
-#endif
-    }
-
-    internal virtual void ClearItems()
-    {
-      CheckReentrancy();
-
-      while (_content != null)
-      {
-        JToken o = _content;
-
-        JToken next = o._next;
-        if (o != _content || next != o._next)
-          throw new InvalidOperationException("This operation was corrupted by external code.");
-
-        if (next != o)
-          o._next = next._next;
-        else
-          _content = null;
-
-        next.Parent = null;
-        next._next = null;
-      }
-
-#if !SILVERLIGHT
-      OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
-#else
-      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
-#endif
-    }
-
-    internal virtual void ReplaceItem(JToken existing, JToken replacement)
-    {
-      if (existing == null || existing.Parent != this)
-        return;
-
-      if (IsTokenUnchanged(existing, replacement))
-        return;
-
-      CheckReentrancy();
-
-      replacement = EnsureParentToken(replacement);
-
-      ValidateToken(replacement, existing);
-
-      JToken content = _content;
-
-      int itemIndex = 0;
-      while (content._next != existing)
-      {
-        itemIndex++;
-        content = content._next;
-      }
-
-      if (content == existing)
-      {
-        // token is containers last child
-        _content = replacement;
-        replacement._next = replacement;
-      }
-      else
-      {
-        if (_content == existing)
-        {
-          _content = replacement;
-        }
-        content._next = replacement;
-        replacement._next = existing._next;
-      }
-
-      replacement.Parent = this;
-
-      existing.Parent = null;
-      existing.Next = null;
-
-#if !SILVERLIGHT
-      OnListChanged(new ListChangedEventArgs(ListChangedType.ItemChanged, itemIndex));
-#else
-      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, replacement, existing, itemIndex));
-#endif
-    }
-
-    internal virtual bool ContainsItem(JToken item)
-    {
-      return (IndexOfItem(item) != -1);
-    }
-
-    internal virtual void CopyItemsTo(Array array, int arrayIndex)
-    {
-      if (array == null)
-        throw new ArgumentNullException("array");
-      if (arrayIndex < 0)
-        throw new ArgumentOutOfRangeException("arrayIndex", "arrayIndex is less than 0.");
-      if (arrayIndex >= array.Length)
-        throw new ArgumentException("arrayIndex is equal to or greater than the length of array.");
-      if (CountItems() > array.Length - arrayIndex)
-        throw new ArgumentException("The number of elements in the source JObject is greater than the available space from arrayIndex to the end of the destination array.");
-
-      int index = 0;
-      foreach (JToken token in Children())
-      {
-        array.SetValue(token, arrayIndex + index);
-        index++;
-      }
-    }
-
-    internal virtual int CountItems()
-    {
-      return Children().Count();
-    }
-
-    internal static bool IsTokenUnchanged(JToken currentValue, JToken newValue)
-    {
-      JValue v1 = currentValue as JValue;
-      if (v1 != null)
-      {
-        // null will get turned into a JValue of type null
-        if (v1.Type == JTokenType.Null && newValue == null)
-          return true;
-
-        return v1.Equals(newValue);
-      }
-
-      return false;
-    }
-
-    internal virtual void ValidateToken(JToken o, JToken existing)
-    {
-      ValidationUtils.ArgumentNotNull(o, "o");
-
-      if (o.Type == JTokenType.Property)
-        throw new ArgumentException("Can not add {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, o.GetType(), GetType()));
-    }
-
-    /// <summary>
-    /// Adds the specified content as children of this <see cref="JToken"/>.
-    /// </summary>
-    /// <param name="content">The content to be added.</param>
-    public void Add(object content)
-    {
-      AddInternal(true, Last, content);
-    }
-
-    /// <summary>
-    /// Adds the specified content as the first children of this <see cref="JToken"/>.
-    /// </summary>
-    /// <param name="content">The content to be added.</param>
-    public void AddFirst(object content)
-    {
-      AddInternal(false, Last, content);
-    }
-
-    internal JToken CreateFromContent(object content)
-    {
-      if (content is JToken)
-        return (JToken)content;
-      
-      return new JValue(content);
-    }
-
-    /// <summary>
-    /// Creates an <see cref="JsonWriter"/> that can be used to add tokens to the <see cref="JToken"/>.
-    /// </summary>
-    /// <returns>An <see cref="JsonWriter"/> that is ready to have content written to it.</returns>
-    public JsonWriter CreateWriter()
-    {
-      return new JTokenWriter(this);
-    }
-
-    /// <summary>
-    /// Replaces the children nodes of this token with the specified content.
-    /// </summary>
-    /// <param name="content">The content.</param>
-    public void ReplaceAll(object content)
-    {
-      ClearItems();
-      Add(content);
-    }
-
-    /// <summary>
-    /// Removes the child nodes from this token.
-    /// </summary>
-    public void RemoveAll()
-    {
-      ClearItems();
-    }
-
-    internal void ReadContentFrom(JsonReader r)
-    {
-      ValidationUtils.ArgumentNotNull(r, "r");
-      IJsonLineInfo lineInfo = r as IJsonLineInfo;
-
-      JContainer parent = this;
-
-      do
-      {
-        if (parent is JProperty && ((JProperty)parent).Value != null)
-        {
-          if (parent == this)
-            return;
-
-          parent = parent.Parent;
-        }
-
-        switch (r.TokenType)
-        {
-          case JsonToken.None:
-            // new reader. move to actual content
-            break;
-          case JsonToken.StartArray:
-            JArray a = new JArray();
-            a.SetLineInfo(lineInfo);
-            parent.Add(a);
-            parent = a;
-            break;
-
-          case JsonToken.EndArray:
-            if (parent == this)
-              return;
-
-            parent = parent.Parent;
-            break;
-          case JsonToken.StartObject:
-            JObject o = new JObject();
-            o.SetLineInfo(lineInfo);
-            parent.Add(o);
-            parent = o;
-            break;
-          case JsonToken.EndObject:
-            if (parent == this)
-              return;
-
-            parent = parent.Parent;
-            break;
-          case JsonToken.StartConstructor:
-            JConstructor constructor = new JConstructor(r.Value.ToString());
-            constructor.SetLineInfo(constructor);
-            parent.Add(constructor);
-            parent = constructor;
-            break;
-          case JsonToken.EndConstructor:
-            if (parent == this)
-              return;
-
-            parent = parent.Parent;
-            break;
-          case JsonToken.String:
-          case JsonToken.Integer:
-          case JsonToken.Float:
-          case JsonToken.Date:
-          case JsonToken.Boolean:
-          case JsonToken.Bytes:
-            JValue v = new JValue(r.Value);
-            v.SetLineInfo(lineInfo);
-            parent.Add(v);
-            break;
-          case JsonToken.Comment:
-            v = JValue.CreateComment(r.Value.ToString());
-            v.SetLineInfo(lineInfo);
-            parent.Add(v);
-            break;
-          case JsonToken.Null:
-            v = new JValue(null, JTokenType.Null);
-            v.SetLineInfo(lineInfo);
-            parent.Add(v);
-            break;
-          case JsonToken.Undefined:
-            v = new JValue(null, JTokenType.Undefined);
-            v.SetLineInfo(lineInfo);
-            parent.Add(v);
-            break;
-          case JsonToken.PropertyName:
-            string propertyName = r.Value.ToString();
-            JProperty property = new JProperty(propertyName);
-            property.SetLineInfo(lineInfo);
-            JObject parentObject = (JObject) parent;
-            // handle multiple properties with the same name in JSON
-            JProperty existingPropertyWithName = parentObject.Property(propertyName);
-            if (existingPropertyWithName == null)
-              parent.Add(property);
-            else
-              existingPropertyWithName.Replace(property);
-            parent = property;
-            break;
-          default:
-            throw new InvalidOperationException("The JsonReader should not be on a token of type {0}.".FormatWith(CultureInfo.InvariantCulture, r.TokenType));
-        }
-      }
-      while (r.Read());
-    }
-
-    internal int ContentsHashCode()
-    {
-      int hashCode = 0;
-      foreach (JToken item in Children())
-      {
-        hashCode ^= item.GetDeepHashCode();
-      }
-      return hashCode;
-    }
-
-#if !SILVERLIGHT
-    string ITypedList.GetListName(PropertyDescriptor[] listAccessors)
-    {
-      return string.Empty;
-    }
-
-    PropertyDescriptorCollection ITypedList.GetItemProperties(PropertyDescriptor[] listAccessors)
-    {
-      JObject o = First as JObject;
-      if (o != null)
-      {
-        // explicitly use constructor because compact framework has no provider
-        JTypeDescriptor descriptor = new JTypeDescriptor(o);
-        return descriptor.GetProperties();
-      }
-
-      return null;
-    }
-#endif
-
-    #region IList<JToken> Members
-
-    int IList<JToken>.IndexOf(JToken item)
-    {
-      return IndexOfItem(item);
-    }
-
-    void IList<JToken>.Insert(int index, JToken item)
-    {
-      InsertItem(index, item);
-    }
-
-    void IList<JToken>.RemoveAt(int index)
-    {
-      RemoveItemAt(index);
-    }
-
-    JToken IList<JToken>.this[int index]
-    {
-      get { return GetItem(index); }
-      set { SetItem(index, value); }
-    }
-
-    #endregion
-
-    #region ICollection<JToken> Members
-
-    void ICollection<JToken>.Add(JToken item)
-    {
-      Add(item);
-    }
-
-    void ICollection<JToken>.Clear()
-    {
-      ClearItems();
-    }
-
-    bool ICollection<JToken>.Contains(JToken item)
-    {
-      return ContainsItem(item);
-    }
-
-    void ICollection<JToken>.CopyTo(JToken[] array, int arrayIndex)
-    {
-      CopyItemsTo(array, arrayIndex);
-    }
-
-    int ICollection<JToken>.Count
-    {
-      get { return CountItems(); }
-    }
-
-    bool ICollection<JToken>.IsReadOnly
-    {
-      get { return false; }
-    }
-
-    bool ICollection<JToken>.Remove(JToken item)
-    {
-      return RemoveItem(item);
-    }
-
-    #endregion
-
-    private JToken EnsureValue(object value)
-    {
-      if (value == null)
-        return null;
-
-      if (value is JToken)
-        return (JToken) value;
-
-      throw new ArgumentException("Argument is not a JToken.");
-    }
-
-    #region IList Members
-
-    int IList.Add(object value)
-    {
-      Add(EnsureValue(value));
-      return CountItems() - 1;
-    }
-
-    void IList.Clear()
-    {
-      ClearItems();
-    }
-
-    bool IList.Contains(object value)
-    {
-      return ContainsItem(EnsureValue(value));
-    }
-
-    int IList.IndexOf(object value)
-    {
-      return IndexOfItem(EnsureValue(value));
-    }
-
-    void IList.Insert(int index, object value)
-    {
-      InsertItem(index, EnsureValue(value));
-    }
-
-    bool IList.IsFixedSize
-    {
-      get { return false; }
-    }
-
-    bool IList.IsReadOnly
-    {
-      get { return false; }
-    }
-
-    void IList.Remove(object value)
-    {
-      RemoveItem(EnsureValue(value));
-    }
-
-    void IList.RemoveAt(int index)
-    {
-      RemoveItemAt(index);
-    }
-
-    object IList.this[int index]
-    {
-      get { return GetItem(index); }
-      set { SetItem(index, EnsureValue(value)); }
-    }
-
-    #endregion
-
-    #region ICollection Members
-
-    void ICollection.CopyTo(Array array, int index)
-    {
-      CopyItemsTo(array, index);
-    }
-
-    int ICollection.Count
-    {
-      get { return CountItems(); }
-    }
-
-    bool ICollection.IsSynchronized
-    {
-      get { return false; }
-    }
-
-    object ICollection.SyncRoot
-    {
-      get
-      {
-        if (_syncRoot == null)
-          Interlocked.CompareExchange(ref _syncRoot, new object(), null);
-
-        return _syncRoot;
-      }
-
-    }
-
-    #endregion
-
-    #region IBindingList Members
-
-#if !SILVERLIGHT
-    void IBindingList.AddIndex(PropertyDescriptor property)
-    {
-    }
-
-    object IBindingList.AddNew()
-    {
-      AddingNewEventArgs args = new AddingNewEventArgs();
-      OnAddingNew(args);
-
-      if (args.NewObject == null)
-        throw new Exception("Could not determine new value to add to '{0}'.".FormatWith(CultureInfo.InvariantCulture, GetType()));
-
-      if (!(args.NewObject is JToken))
-        throw new Exception("New item to be added to collection must be compatible with {0}.".FormatWith(CultureInfo.InvariantCulture, typeof (JToken)));
-
-      JToken newItem = (JToken)args.NewObject;
-      Add(newItem);
-
-      return newItem;
-    }
-
-    bool IBindingList.AllowEdit
-    {
-      get { return true; }
-    }
-
-    bool IBindingList.AllowNew
-    {
-      get { return true; }
-    }
-
-    bool IBindingList.AllowRemove
-    {
-      get { return true; }
-    }
-
-    void IBindingList.ApplySort(PropertyDescriptor property, ListSortDirection direction)
-    {
-      throw new NotSupportedException();
-    }
-
-    int IBindingList.Find(PropertyDescriptor property, object key)
-    {
-      throw new NotSupportedException();
-    }
-
-    bool IBindingList.IsSorted
-    {
-      get { return false; }
-    }
-
-    void IBindingList.RemoveIndex(PropertyDescriptor property)
-    {
-    }
-
-    void IBindingList.RemoveSort()
-    {
-      throw new NotSupportedException();
-    }
-
-    ListSortDirection IBindingList.SortDirection
-    {
-      get { return ListSortDirection.Ascending; }
-    }
-
-    PropertyDescriptor IBindingList.SortProperty
-    {
-      get { return null; }
-    }
-
-    bool IBindingList.SupportsChangeNotification
-    {
-      get { return true; }
-    }
-
-    bool IBindingList.SupportsSearching
-    {
-      get { return false; }
-    }
-
-    bool IBindingList.SupportsSorting
-    {
-      get { return false; }
-    }
-#endif
-
-    #endregion
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+#if !PORTABLE
+using System.Collections.Specialized;
+#endif
+using System.Threading;
+using Newtonsoft.Json.Utilities;
+using System.Collections;
+using System.Globalization;
+using System.ComponentModel;
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#else
+using System.Linq;
+#endif
+
+namespace Newtonsoft.Json.Linq
+{
+  /// <summary>
+  /// Represents a token that can contain other tokens.
+  /// </summary>
+  public abstract class JContainer : JToken, IList<JToken>
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+    , ITypedList, IBindingList
+#elif !PORTABLE
+    , INotifyCollectionChanged
+#endif
+    , IList
+#if !(SILVERLIGHT || NET20 || NET35 || NETFX_CORE || PORTABLE)
+    , INotifyCollectionChanged
+#endif
+  {
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+    /// <summary>
+    /// Occurs when the list changes or an item in the list changes.
+    /// </summary>
+    public event ListChangedEventHandler ListChanged;
+
+    /// <summary>
+    /// Occurs before an item is added to the collection.
+    /// </summary>
+    public event AddingNewEventHandler AddingNew;
+#endif
+#if SILVERLIGHT || !(NET20 || NET35 || PORTABLE)
+    /// <summary>
+    /// Occurs when the items list of the collection has changed, or the collection is reset.
+    /// </summary>
+    public event NotifyCollectionChangedEventHandler CollectionChanged;
+#endif
+
+    /// <summary>
+    /// Gets the container's children tokens.
+    /// </summary>
+    /// <value>The container's children tokens.</value>
+    protected abstract IList<JToken> ChildrenTokens { get; }
+
+    private object _syncRoot;
+    private bool _busy;
+
+    internal JContainer()
+    {
+    }
+
+    internal JContainer(JContainer other)
+    {
+      ValidationUtils.ArgumentNotNull(other, "c");
+
+      foreach (JToken child in other)
+      {
+        Add(child);
+      }
+    }
+
+    internal void CheckReentrancy()
+    {
+      if (_busy)
+        throw new InvalidOperationException("Cannot change {0} during a collection change event.".FormatWith(CultureInfo.InvariantCulture, GetType()));
+    }
+
+ #if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+    /// <summary>
+    /// Raises the <see cref="AddingNew"/> event.
+    /// </summary>
+    /// <param name="e">The <see cref="AddingNewEventArgs"/> instance containing the event data.</param>
+    protected virtual void OnAddingNew(AddingNewEventArgs e)
+    {
+      AddingNewEventHandler handler = AddingNew;
+      if (handler != null)
+        handler(this, e);
+    }
+
+    /// <summary>
+    /// Raises the <see cref="ListChanged"/> event.
+    /// </summary>
+    /// <param name="e">The <see cref="ListChangedEventArgs"/> instance containing the event data.</param>
+    protected virtual void OnListChanged(ListChangedEventArgs e)
+    {
+      ListChangedEventHandler handler = ListChanged;
+
+      if (handler != null)
+      {
+        _busy = true;
+        try
+        {
+          handler(this, e);
+        }
+        finally
+        {
+          _busy = false;
+        }
+      }
+    }
+#endif
+#if SILVERLIGHT || !(NET20 || NET35 || PORTABLE)
+    /// <summary>
+    /// Raises the <see cref="CollectionChanged"/> event.
+    /// </summary>
+    /// <param name="e">The <see cref="NotifyCollectionChangedEventArgs"/> instance containing the event data.</param>
+    protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
+    {
+      NotifyCollectionChangedEventHandler handler = CollectionChanged;
+
+      if (handler != null)
+      {
+        _busy = true;
+        try
+        {
+          handler(this, e);
+        }
+        finally
+        {
+          _busy = false;
+        }
+      }
+    }
+#endif
+
+    /// <summary>
+    /// Gets a value indicating whether this token has childen tokens.
+    /// </summary>
+    /// <value>
+    /// 	<c>true</c> if this token has child values; otherwise, <c>false</c>.
+    /// </value>
+    public override bool HasValues
+    {
+      get { return ChildrenTokens.Count > 0; }
+    }
+
+    internal bool ContentsEqual(JContainer container)
+    {
+      if (container == this)
+        return true;
+
+      IList<JToken> t1 = ChildrenTokens;
+      IList<JToken> t2 = container.ChildrenTokens;
+
+      if (t1.Count != t2.Count)
+        return false;
+
+      for (int i = 0; i < t1.Count; i++)
+      {
+        if (!t1[i].DeepEquals(t2[i]))
+          return false;
+      }
+
+      return true;
+    }
+
+    /// <summary>
+    /// Get the first child token of this token.
+    /// </summary>
+    /// <value>
+    /// A <see cref="JToken"/> containing the first child token of the <see cref="JToken"/>.
+    /// </value>
+    public override JToken First
+    {
+      get { return ChildrenTokens.FirstOrDefault(); }
+    }
+
+    /// <summary>
+    /// Get the last child token of this token.
+    /// </summary>
+    /// <value>
+    /// A <see cref="JToken"/> containing the last child token of the <see cref="JToken"/>.
+    /// </value>
+    public override JToken Last
+    {
+      get { return ChildrenTokens.LastOrDefault(); }
+    }
+
+    /// <summary>
+    /// Returns a collection of the child tokens of this token, in document order.
+    /// </summary>
+    /// <returns>
+    /// An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> containing the child tokens of this <see cref="JToken"/>, in document order.
+    /// </returns>
+    public override JEnumerable<JToken> Children()
+    {
+      return new JEnumerable<JToken>(ChildrenTokens);
+    }
+
+    /// <summary>
+    /// Returns a collection of the child values of this token, in document order.
+    /// </summary>
+    /// <typeparam name="T">The type to convert the values to.</typeparam>
+    /// <returns>
+    /// A <see cref="IEnumerable{T}"/> containing the child values of this <see cref="JToken"/>, in document order.
+    /// </returns>
+    public override IEnumerable<T> Values<T>()
+    {
+      return ChildrenTokens.Convert<JToken, T>();
+    }
+
+    /// <summary>
+    /// Returns a collection of the descendant tokens for this token in document order.
+    /// </summary>
+    /// <returns>An <see cref="IEnumerable{JToken}"/> containing the descendant tokens of the <see cref="JToken"/>.</returns>
+    public IEnumerable<JToken> Descendants()
+    {
+      foreach (JToken o in ChildrenTokens)
+      {
+        yield return o;
+        JContainer c = o as JContainer;
+        if (c != null)
+        {
+          foreach (JToken d in c.Descendants())
+          {
+            yield return d;
+          }
+        }
+      }
+    }
+
+    internal bool IsMultiContent(object content)
+    {
+      return (content is IEnumerable && !(content is string) && !(content is JToken) && !(content is byte[]));
+    }
+
+    internal JToken EnsureParentToken(JToken item, bool skipParentCheck)
+    {
+      if (item == null)
+        return new JValue((object) null);
+
+      if (skipParentCheck)
+        return item;
+
+      // to avoid a token having multiple parents or creating a recursive loop, create a copy if...
+      // the item already has a parent
+      // the item is being added to itself
+      // the item is being added to the root parent of itself
+      if (item.Parent != null || item == this || (item.HasValues && Root == item))
+        item = item.CloneToken();
+
+      return item;
+    }
+
+    private class JTokenReferenceEqualityComparer : IEqualityComparer<JToken>
+    {
+      public static readonly JTokenReferenceEqualityComparer Instance = new JTokenReferenceEqualityComparer();
+
+      public bool Equals(JToken x, JToken y)
+      {
+        return ReferenceEquals(x, y);
+      }
+
+      public int GetHashCode(JToken obj)
+      {
+        if (obj == null)
+          return 0;
+
+        return obj.GetHashCode();
+      }
+    }
+
+    internal int IndexOfItem(JToken item)
+    {
+      return ChildrenTokens.IndexOf(item, JTokenReferenceEqualityComparer.Instance);
+    }
+
+    internal virtual void InsertItem(int index, JToken item, bool skipParentCheck)
+    {
+      if (index > ChildrenTokens.Count)
+        throw new ArgumentOutOfRangeException("index", "Index must be within the bounds of the List.");
+
+      CheckReentrancy();
+
+      item = EnsureParentToken(item, skipParentCheck);
+
+      JToken previous = (index == 0) ? null : ChildrenTokens[index - 1];
+      // haven't inserted new token yet so next token is still at the inserting index
+      JToken next = (index == ChildrenTokens.Count) ? null : ChildrenTokens[index];
+
+      ValidateToken(item, null);
+
+      item.Parent = this;
+
+      item.Previous = previous;
+      if (previous != null)
+        previous.Next = item;
+
+      item.Next = next;
+      if (next != null)
+        next.Previous = item;
+      
+      ChildrenTokens.Insert(index, item);
+
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+      if (ListChanged != null)
+        OnListChanged(new ListChangedEventArgs(ListChangedType.ItemAdded, index));
+#endif
+#if SILVERLIGHT || !(NET20 || NET35 || PORTABLE)
+      if (CollectionChanged != null)
+        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, index));
+#endif
+    }
+
+    internal virtual void RemoveItemAt(int index)
+    {
+      if (index < 0)
+        throw new ArgumentOutOfRangeException("index", "Index is less than 0.");
+      if (index >= ChildrenTokens.Count)
+        throw new ArgumentOutOfRangeException("index", "Index is equal to or greater than Count.");
+
+      CheckReentrancy();
+
+      JToken item = ChildrenTokens[index];
+      JToken previous = (index == 0) ? null : ChildrenTokens[index - 1];
+      JToken next = (index == ChildrenTokens.Count - 1) ? null : ChildrenTokens[index + 1];
+
+      if (previous != null)
+        previous.Next = next;
+      if (next != null)
+        next.Previous = previous;
+
+      item.Parent = null;
+      item.Previous = null;
+      item.Next = null;
+
+      ChildrenTokens.RemoveAt(index);
+
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+      OnListChanged(new ListChangedEventArgs(ListChangedType.ItemDeleted, index));
+#endif
+#if SILVERLIGHT || !(NET20 || NET35 || PORTABLE)
+      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, index));
+#endif
+    }
+
+    internal virtual bool RemoveItem(JToken item)
+    {
+      int index = IndexOfItem(item);
+      if (index >= 0)
+      {
+        RemoveItemAt(index);
+        return true;
+      }
+
+      return false;
+    }
+
+    internal virtual JToken GetItem(int index)
+    {
+      return ChildrenTokens[index];
+    }
+
+    internal virtual void SetItem(int index, JToken item)
+    {
+      if (index < 0)
+        throw new ArgumentOutOfRangeException("index", "Index is less than 0.");
+      if (index >= ChildrenTokens.Count)
+        throw new ArgumentOutOfRangeException("index", "Index is equal to or greater than Count.");
+
+      JToken existing = ChildrenTokens[index];
+
+      if (IsTokenUnchanged(existing, item))
+        return;
+
+      CheckReentrancy();
+
+      item = EnsureParentToken(item, false);
+
+      ValidateToken(item, existing);
+
+      JToken previous = (index == 0) ? null : ChildrenTokens[index - 1];
+      JToken next = (index == ChildrenTokens.Count - 1) ? null : ChildrenTokens[index + 1];
+
+      item.Parent = this;
+
+      item.Previous = previous;
+      if (previous != null)
+        previous.Next = item;
+
+      item.Next = next;
+      if (next != null)
+        next.Previous = item;
+
+      ChildrenTokens[index] = item;
+
+      existing.Parent = null;
+      existing.Previous = null;
+      existing.Next = null;
+
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+      OnListChanged(new ListChangedEventArgs(ListChangedType.ItemChanged, index));
+#endif
+#if SILVERLIGHT || !(NET20 || NET35 || PORTABLE)
+      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, item, existing, index));
+#endif
+    }
+
+    internal virtual void ClearItems()
+    {
+      CheckReentrancy();
+
+      foreach (JToken item in ChildrenTokens)
+      {
+        item.Parent = null;
+        item.Previous = null;
+        item.Next = null;
+      }
+
+      ChildrenTokens.Clear();
+
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+      OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
+#endif
+#if SILVERLIGHT || !(NET20 || NET35 || PORTABLE)
+      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
+#endif
+    }
+
+    internal virtual void ReplaceItem(JToken existing, JToken replacement)
+    {
+      if (existing == null || existing.Parent != this)
+        return;
+
+      int index = IndexOfItem(existing);
+      SetItem(index, replacement);
+    }
+
+    internal virtual bool ContainsItem(JToken item)
+    {
+      return (IndexOfItem(item) != -1);
+    }
+
+    internal virtual void CopyItemsTo(Array array, int arrayIndex)
+    {
+      if (array == null)
+        throw new ArgumentNullException("array");
+      if (arrayIndex < 0)
+        throw new ArgumentOutOfRangeException("arrayIndex", "arrayIndex is less than 0.");
+      if (arrayIndex >= array.Length)
+        throw new ArgumentException("arrayIndex is equal to or greater than the length of array.");
+      if (Count > array.Length - arrayIndex)
+        throw new ArgumentException("The number of elements in the source JObject is greater than the available space from arrayIndex to the end of the destination array.");
+
+      int index = 0;
+      foreach (JToken token in ChildrenTokens)
+      {
+        array.SetValue(token, arrayIndex + index);
+        index++;
+      }
+    }
+
+    internal static bool IsTokenUnchanged(JToken currentValue, JToken newValue)
+    {
+      JValue v1 = currentValue as JValue;
+      if (v1 != null)
+      {
+        // null will get turned into a JValue of type null
+        if (v1.Type == JTokenType.Null && newValue == null)
+          return true;
+
+        return v1.Equals(newValue);
+      }
+
+      return false;
+    }
+
+    internal virtual void ValidateToken(JToken o, JToken existing)
+    {
+      ValidationUtils.ArgumentNotNull(o, "o");
+
+      if (o.Type == JTokenType.Property)
+        throw new ArgumentException("Can not add {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, o.GetType(), GetType()));
+    }
+
+    /// <summary>
+    /// Adds the specified content as children of this <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="content">The content to be added.</param>
+    public virtual void Add(object content)
+    {
+      AddInternal(ChildrenTokens.Count, content, false);
+    }
+
+    internal void AddAndSkipParentCheck(JToken token)
+    {
+      AddInternal(ChildrenTokens.Count, token, true);
+    }
+
+    /// <summary>
+    /// Adds the specified content as the first children of this <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="content">The content to be added.</param>
+    public void AddFirst(object content)
+    {
+      AddInternal(0, content, false);
+    }
+
+    internal void AddInternal(int index, object content, bool skipParentCheck)
+    {
+      if (IsMultiContent(content))
+      {
+        IEnumerable enumerable = (IEnumerable)content;
+
+        int multiIndex = index;
+        foreach (object c in enumerable)
+        {
+          AddInternal(multiIndex, c, skipParentCheck);
+          multiIndex++;
+        }
+      }
+      else
+      {
+        JToken item = CreateFromContent(content);
+
+        InsertItem(index, item, skipParentCheck);
+      }
+    }
+
+    internal JToken CreateFromContent(object content)
+    {
+      if (content is JToken)
+        return (JToken)content;
+      
+      return new JValue(content);
+    }
+
+    /// <summary>
+    /// Creates an <see cref="JsonWriter"/> that can be used to add tokens to the <see cref="JToken"/>.
+    /// </summary>
+    /// <returns>An <see cref="JsonWriter"/> that is ready to have content written to it.</returns>
+    public JsonWriter CreateWriter()
+    {
+      return new JTokenWriter(this);
+    }
+
+    /// <summary>
+    /// Replaces the children nodes of this token with the specified content.
+    /// </summary>
+    /// <param name="content">The content.</param>
+    public void ReplaceAll(object content)
+    {
+      ClearItems();
+      Add(content);
+    }
+
+    /// <summary>
+    /// Removes the child nodes from this token.
+    /// </summary>
+    public void RemoveAll()
+    {
+      ClearItems();
+    }
+
+    internal void ReadTokenFrom(JsonReader reader)
+    {
+      int startDepth = reader.Depth;
+
+      if (!reader.Read())
+        throw JsonReaderException.Create(reader, "Error reading {0} from JsonReader.".FormatWith(CultureInfo.InvariantCulture, GetType().Name));
+
+      ReadContentFrom(reader);
+
+      int endDepth = reader.Depth;
+
+      if (endDepth > startDepth)
+        throw JsonReaderException.Create(reader, "Unexpected end of content while loading {0}.".FormatWith(CultureInfo.InvariantCulture, GetType().Name));
+    }
+
+    internal void ReadContentFrom(JsonReader r)
+    {
+      ValidationUtils.ArgumentNotNull(r, "r");
+      IJsonLineInfo lineInfo = r as IJsonLineInfo;
+
+      JContainer parent = this;
+
+      do
+      {
+        if (parent is JProperty && ((JProperty)parent).Value != null)
+        {
+          if (parent == this)
+            return;
+
+          parent = parent.Parent;
+        }
+
+        switch (r.TokenType)
+        {
+          case JsonToken.None:
+            // new reader. move to actual content
+            break;
+          case JsonToken.StartArray:
+            JArray a = new JArray();
+            a.SetLineInfo(lineInfo);
+            parent.Add(a);
+            parent = a;
+            break;
+
+          case JsonToken.EndArray:
+            if (parent == this)
+              return;
+
+            parent = parent.Parent;
+            break;
+          case JsonToken.StartObject:
+            JObject o = new JObject();
+            o.SetLineInfo(lineInfo);
+            parent.Add(o);
+            parent = o;
+            break;
+          case JsonToken.EndObject:
+            if (parent == this)
+              return;
+
+            parent = parent.Parent;
+            break;
+          case JsonToken.StartConstructor:
+            JConstructor constructor = new JConstructor(r.Value.ToString());
+            constructor.SetLineInfo(constructor);
+            parent.Add(constructor);
+            parent = constructor;
+            break;
+          case JsonToken.EndConstructor:
+            if (parent == this)
+              return;
+
+            parent = parent.Parent;
+            break;
+          case JsonToken.String:
+          case JsonToken.Integer:
+          case JsonToken.Float:
+          case JsonToken.Date:
+          case JsonToken.Boolean:
+          case JsonToken.Bytes:
+            JValue v = new JValue(r.Value);
+            v.SetLineInfo(lineInfo);
+            parent.Add(v);
+            break;
+          case JsonToken.Comment:
+            v = JValue.CreateComment(r.Value.ToString());
+            v.SetLineInfo(lineInfo);
+            parent.Add(v);
+            break;
+          case JsonToken.Null:
+            v = new JValue(null, JTokenType.Null);
+            v.SetLineInfo(lineInfo);
+            parent.Add(v);
+            break;
+          case JsonToken.Undefined:
+            v = new JValue(null, JTokenType.Undefined);
+            v.SetLineInfo(lineInfo);
+            parent.Add(v);
+            break;
+          case JsonToken.PropertyName:
+            string propertyName = r.Value.ToString();
+            JProperty property = new JProperty(propertyName);
+            property.SetLineInfo(lineInfo);
+            JObject parentObject = (JObject) parent;
+            // handle multiple properties with the same name in JSON
+            JProperty existingPropertyWithName = parentObject.Property(propertyName);
+            if (existingPropertyWithName == null)
+              parent.Add(property);
+            else
+              existingPropertyWithName.Replace(property);
+            parent = property;
+            break;
+          default:
+            throw new InvalidOperationException("The JsonReader should not be on a token of type {0}.".FormatWith(CultureInfo.InvariantCulture, r.TokenType));
+        }
+      }
+      while (r.Read());
+    }
+
+    internal int ContentsHashCode()
+    {
+      int hashCode = 0;
+      foreach (JToken item in ChildrenTokens)
+      {
+        hashCode ^= item.GetDeepHashCode();
+      }
+      return hashCode;
+    }
+
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+    string ITypedList.GetListName(PropertyDescriptor[] listAccessors)
+    {
+      return string.Empty;
+    }
+
+    PropertyDescriptorCollection ITypedList.GetItemProperties(PropertyDescriptor[] listAccessors)
+    {
+      ICustomTypeDescriptor d = First as ICustomTypeDescriptor;
+      if (d != null)
+        return d.GetProperties();
+
+      return null;
+    }
+#endif
+
+    #region IList<JToken> Members
+
+    int IList<JToken>.IndexOf(JToken item)
+    {
+      return IndexOfItem(item);
+    }
+
+    void IList<JToken>.Insert(int index, JToken item)
+    {
+      InsertItem(index, item, false);
+    }
+
+    void IList<JToken>.RemoveAt(int index)
+    {
+      RemoveItemAt(index);
+    }
+
+    JToken IList<JToken>.this[int index]
+    {
+      get { return GetItem(index); }
+      set { SetItem(index, value); }
+    }
+
+    #endregion
+
+    #region ICollection<JToken> Members
+
+    void ICollection<JToken>.Add(JToken item)
+    {
+      Add(item);
+    }
+
+    void ICollection<JToken>.Clear()
+    {
+      ClearItems();
+    }
+
+    bool ICollection<JToken>.Contains(JToken item)
+    {
+      return ContainsItem(item);
+    }
+
+    void ICollection<JToken>.CopyTo(JToken[] array, int arrayIndex)
+    {
+      CopyItemsTo(array, arrayIndex);
+    }
+
+    bool ICollection<JToken>.IsReadOnly
+    {
+      get { return false; }
+    }
+
+    bool ICollection<JToken>.Remove(JToken item)
+    {
+      return RemoveItem(item);
+    }
+
+    #endregion
+
+    private JToken EnsureValue(object value)
+    {
+      if (value == null)
+        return null;
+
+      if (value is JToken)
+        return (JToken) value;
+
+      throw new ArgumentException("Argument is not a JToken.");
+    }
+
+    #region IList Members
+
+    int IList.Add(object value)
+    {
+      Add(EnsureValue(value));
+      return Count - 1;
+    }
+
+    void IList.Clear()
+    {
+      ClearItems();
+    }
+
+    bool IList.Contains(object value)
+    {
+      return ContainsItem(EnsureValue(value));
+    }
+
+    int IList.IndexOf(object value)
+    {
+      return IndexOfItem(EnsureValue(value));
+    }
+
+    void IList.Insert(int index, object value)
+    {
+      InsertItem(index, EnsureValue(value), false);
+    }
+
+    bool IList.IsFixedSize
+    {
+      get { return false; }
+    }
+
+    bool IList.IsReadOnly
+    {
+      get { return false; }
+    }
+
+    void IList.Remove(object value)
+    {
+      RemoveItem(EnsureValue(value));
+    }
+
+    void IList.RemoveAt(int index)
+    {
+      RemoveItemAt(index);
+    }
+
+    object IList.this[int index]
+    {
+      get { return GetItem(index); }
+      set { SetItem(index, EnsureValue(value)); }
+    }
+
+    #endregion
+
+    #region ICollection Members
+
+    void ICollection.CopyTo(Array array, int index)
+    {
+      CopyItemsTo(array, index);
+    }
+
+    /// <summary>
+    /// Gets the count of child JSON tokens.
+    /// </summary>
+    /// <value>The count of child JSON tokens</value>
+    public int Count
+    {
+      get { return ChildrenTokens.Count; }
+    }
+
+    bool ICollection.IsSynchronized
+    {
+      get { return false; }
+    }
+
+    object ICollection.SyncRoot
+    {
+      get
+      {
+        if (_syncRoot == null)
+          Interlocked.CompareExchange(ref _syncRoot, new object(), null);
+
+        return _syncRoot;
+      }
+
+    }
+
+    #endregion
+
+    #region IBindingList Members
+
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+    void IBindingList.AddIndex(PropertyDescriptor property)
+    {
+    }
+
+    object IBindingList.AddNew()
+    {
+      AddingNewEventArgs args = new AddingNewEventArgs();
+      OnAddingNew(args);
+
+      if (args.NewObject == null)
+        throw new JsonException("Could not determine new value to add to '{0}'.".FormatWith(CultureInfo.InvariantCulture, GetType()));
+
+      if (!(args.NewObject is JToken))
+        throw new JsonException("New item to be added to collection must be compatible with {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JToken)));
+
+      JToken newItem = (JToken)args.NewObject;
+      Add(newItem);
+
+      return newItem;
+    }
+
+    bool IBindingList.AllowEdit
+    {
+      get { return true; }
+    }
+
+    bool IBindingList.AllowNew
+    {
+      get { return true; }
+    }
+
+    bool IBindingList.AllowRemove
+    {
+      get { return true; }
+    }
+
+    void IBindingList.ApplySort(PropertyDescriptor property, ListSortDirection direction)
+    {
+      throw new NotSupportedException();
+    }
+
+    int IBindingList.Find(PropertyDescriptor property, object key)
+    {
+      throw new NotSupportedException();
+    }
+
+    bool IBindingList.IsSorted
+    {
+      get { return false; }
+    }
+
+    void IBindingList.RemoveIndex(PropertyDescriptor property)
+    {
+    }
+
+    void IBindingList.RemoveSort()
+    {
+      throw new NotSupportedException();
+    }
+
+    ListSortDirection IBindingList.SortDirection
+    {
+      get { return ListSortDirection.Ascending; }
+    }
+
+    PropertyDescriptor IBindingList.SortProperty
+    {
+      get { return null; }
+    }
+
+    bool IBindingList.SupportsChangeNotification
+    {
+      get { return true; }
+    }
+
+    bool IBindingList.SupportsSearching
+    {
+      get { return false; }
+    }
+
+    bool IBindingList.SupportsSorting
+    {
+      get { return false; }
+    }
+#endif
+
+    #endregion
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JEnumerable.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JEnumerable.cs
index 71c5fbb..d29b5ea 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JEnumerable.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JEnumerable.cs
@@ -1,91 +1,118 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Newtonsoft.Json.Utilities;
-using System.Collections;
-
-namespace Newtonsoft.Json.Linq
-{
-  /// <summary>
-  /// Represents a collection of <see cref="JToken"/> objects.
-  /// </summary>
-  /// <typeparam name="T">The type of token</typeparam>
-  public struct JEnumerable<T> : IJEnumerable<T> where T : JToken
-  {
-    /// <summary>
-    /// An empty collection of <see cref="JToken"/> objects.
-    /// </summary>
-    public static readonly JEnumerable<T> Empty = new JEnumerable<T>(Enumerable.Empty<T>());
-
-    private IEnumerable<T> _enumerable;
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JEnumerable{T}"/> struct.
-    /// </summary>
-    /// <param name="enumerable">The enumerable.</param>
-    public JEnumerable(IEnumerable<T> enumerable)
-    {
-      ValidationUtils.ArgumentNotNull(enumerable, "enumerable");
-
-      _enumerable = enumerable;
-    }
-
-    /// <summary>
-    /// Returns an enumerator that iterates through the collection.
-    /// </summary>
-    /// <returns>
-    /// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
-    /// </returns>
-    public IEnumerator<T> GetEnumerator()
-    {
-      return _enumerable.GetEnumerator();
-    }
-
-    /// <summary>
-    /// Returns an enumerator that iterates through a collection.
-    /// </summary>
-    /// <returns>
-    /// An <see cref="T:System.Collections.IEnumerator"/> object that can be used to iterate through the collection.
-    /// </returns>
-    IEnumerator IEnumerable.GetEnumerator()
-    {
-      return GetEnumerator();
-    }
-
-    /// <summary>
-    /// Gets the <see cref="IJEnumerable{JToken}"/> with the specified key.
-    /// </summary>
-    /// <value></value>
-    public IJEnumerable<JToken> this[object key]
-    {
-      get { return new JEnumerable<JToken>(Extensions.Values<T, JToken>(_enumerable, key)); }
-    }
-
-    /// <summary>
-    /// Determines whether the specified <see cref="System.Object"/> is equal to this instance.
-    /// </summary>
-    /// <param name="obj">The <see cref="System.Object"/> to compare with this instance.</param>
-    /// <returns>
-    /// 	<c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>.
-    /// </returns>
-    public override bool Equals(object obj)
-    {
-      if (obj is JEnumerable<T>)
-        return _enumerable.Equals(((JEnumerable<T>)obj)._enumerable);
-
-      return false;
-    }
-
-    /// <summary>
-    /// Returns a hash code for this instance.
-    /// </summary>
-    /// <returns>
-    /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. 
-    /// </returns>
-    public override int GetHashCode()
-    {
-      return _enumerable.GetHashCode();
-    }
-  }
-}
+#region License
+// 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.
+#endregion
+
+using System.Collections.Generic;
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#else
+using System.Linq;
+#endif
+using Newtonsoft.Json.Utilities;
+using System.Collections;
+
+namespace Newtonsoft.Json.Linq
+{
+  /// <summary>
+  /// Represents a collection of <see cref="JToken"/> objects.
+  /// </summary>
+  /// <typeparam name="T">The type of token</typeparam>
+  public struct JEnumerable<T> : IJEnumerable<T> where T : JToken
+  {
+    /// <summary>
+    /// An empty collection of <see cref="JToken"/> objects.
+    /// </summary>
+    public static readonly JEnumerable<T> Empty = new JEnumerable<T>(Enumerable.Empty<T>());
+
+    private readonly IEnumerable<T> _enumerable;
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JEnumerable{T}"/> struct.
+    /// </summary>
+    /// <param name="enumerable">The enumerable.</param>
+    public JEnumerable(IEnumerable<T> enumerable)
+    {
+      ValidationUtils.ArgumentNotNull(enumerable, "enumerable");
+
+      _enumerable = enumerable;
+    }
+
+    /// <summary>
+    /// Returns an enumerator that iterates through the collection.
+    /// </summary>
+    /// <returns>
+    /// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
+    /// </returns>
+    public IEnumerator<T> GetEnumerator()
+    {
+      return _enumerable.GetEnumerator();
+    }
+
+    /// <summary>
+    /// Returns an enumerator that iterates through a collection.
+    /// </summary>
+    /// <returns>
+    /// An <see cref="T:System.Collections.IEnumerator"/> object that can be used to iterate through the collection.
+    /// </returns>
+    IEnumerator IEnumerable.GetEnumerator()
+    {
+      return GetEnumerator();
+    }
+
+    /// <summary>
+    /// Gets the <see cref="IJEnumerable{JToken}"/> with the specified key.
+    /// </summary>
+    /// <value></value>
+    public IJEnumerable<JToken> this[object key]
+    {
+      get { return new JEnumerable<JToken>(Extensions.Values<T, JToken>(_enumerable, key)); }
+    }
+
+    /// <summary>
+    /// Determines whether the specified <see cref="System.Object"/> is equal to this instance.
+    /// </summary>
+    /// <param name="obj">The <see cref="System.Object"/> to compare with this instance.</param>
+    /// <returns>
+    /// 	<c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>.
+    /// </returns>
+    public override bool Equals(object obj)
+    {
+      if (obj is JEnumerable<T>)
+        return _enumerable.Equals(((JEnumerable<T>)obj)._enumerable);
+
+      return false;
+    }
+
+    /// <summary>
+    /// Returns a hash code for this instance.
+    /// </summary>
+    /// <returns>
+    /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. 
+    /// </returns>
+    public override int GetHashCode()
+    {
+      return _enumerable.GetHashCode();
+    }
+  }
+}
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JObject.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JObject.cs
index b591ade..9c42707 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JObject.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JObject.cs
@@ -1,495 +1,743 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.ComponentModel;
-using System.Linq;
-using System.IO;
-using Newtonsoft.Json.Utilities;
-using System.Globalization;
-#if !PocketPC && !SILVERLIGHT
-using Newtonsoft.Json.Linq.ComponentModel;
-#endif
-
-namespace Newtonsoft.Json.Linq
-{
-  /// <summary>
-  /// Represents a JSON object.
-  /// </summary>
-#if !PocketPC && !SILVERLIGHT
-  [TypeDescriptionProvider(typeof(JTypeDescriptionProvider))]
-#endif
-  public class JObject : JContainer, IDictionary<string, JToken>, INotifyPropertyChanged
-#if !PocketPC && !SILVERLIGHT && !NET20
-    , INotifyPropertyChanging
-#endif
-  {
-    /// <summary>
-    /// Occurs when a property value changes.
-    /// </summary>
-    public event PropertyChangedEventHandler PropertyChanged;
-
-#if !PocketPC && !SILVERLIGHT && !NET20
-    /// <summary>
-    /// Occurs when a property value is changing.
-    /// </summary>
-    public event PropertyChangingEventHandler PropertyChanging;
-#endif
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JObject"/> class.
-    /// </summary>
-    public JObject()
-    {
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JObject"/> class from another <see cref="JObject"/> object.
-    /// </summary>
-    /// <param name="other">A <see cref="JObject"/> object to copy from.</param>
-    public JObject(JObject other)
-      : base(other)
-    {
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JObject"/> class with the specified content.
-    /// </summary>
-    /// <param name="content">The contents of the object.</param>
-    public JObject(params object[] content)
-      : this((object)content)
-    {
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JObject"/> class with the specified content.
-    /// </summary>
-    /// <param name="content">The contents of the object.</param>
-    public JObject(object content)
-    {
-      Add(content);
-    }
-
-    internal override bool DeepEquals(JToken node)
-    {
-      JObject t = node as JObject;
-      return (t != null && ContentsEqual(t));
-    }
-
-    internal override void ValidateToken(JToken o, JToken existing)
-    {
-      ValidationUtils.ArgumentNotNull(o, "o");
-
-      if (o.Type != JTokenType.Property)
-        throw new ArgumentException("Can not add {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, o.GetType(), GetType()));
-
-      // looping over all properties every time isn't good
-      // need to think about performance here
-      JProperty property = (JProperty)o;
-      foreach (JProperty childProperty in Children())
-      {
-        if (childProperty != existing && string.Equals(childProperty.Name, property.Name, StringComparison.Ordinal))
-          throw new ArgumentException("Can not add property {0} to {1}. Property with the same name already exists on object.".FormatWith(CultureInfo.InvariantCulture, property.Name, GetType()));
-      }
-    }
-
-    internal void InternalPropertyChanged(JProperty childProperty)
-    {
-      OnPropertyChanged(childProperty.Name);
-#if !SILVERLIGHT
-      OnListChanged(new ListChangedEventArgs(ListChangedType.ItemChanged, IndexOfItem(childProperty)));
-#else
-      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, childProperty, childProperty, IndexOfItem(childProperty)));
-#endif
-    }
-
-    internal void InternalPropertyChanging(JProperty childProperty)
-    {
-#if !PocketPC && !SILVERLIGHT && !NET20
-      OnPropertyChanging(childProperty.Name);
-#endif
-    }
-
-    internal override JToken CloneToken()
-    {
-      return new JObject(this);
-    }
-
-    /// <summary>
-    /// Gets the node type for this <see cref="JToken"/>.
-    /// </summary>
-    /// <value>The type.</value>
-    public override JTokenType Type
-    {
-      get { return JTokenType.Object; }
-    }
-
-    /// <summary>
-    /// Gets an <see cref="IEnumerable{JProperty}"/> of this object's properties.
-    /// </summary>
-    /// <returns>An <see cref="IEnumerable{JProperty}"/> of this object's properties.</returns>
-    public IEnumerable<JProperty> Properties()
-    {
-      return Children().Cast<JProperty>();
-    }
-
-    /// <summary>
-    /// Gets a <see cref="JProperty"/> the specified name.
-    /// </summary>
-    /// <param name="name">The property name.</param>
-    /// <returns>A <see cref="JProperty"/> with the specified name or null.</returns>
-    public JProperty Property(string name)
-    {
-      return Properties()
-        .Where(p => string.Equals(p.Name, name, StringComparison.Ordinal))
-        .SingleOrDefault();
-    }
-
-    /// <summary>
-    /// Gets an <see cref="JEnumerable{JToken}"/> of this object's property values.
-    /// </summary>
-    /// <returns>An <see cref="JEnumerable{JToken}"/> of this object's property values.</returns>
-    public JEnumerable<JToken> PropertyValues()
-    {
-      return new JEnumerable<JToken>(Properties().Select(p => p.Value));
-    }
-
-    /// <summary>
-    /// Gets the <see cref="JToken"/> with the specified key.
-    /// </summary>
-    /// <value>The <see cref="JToken"/> with the specified key.</value>
-    public override JToken this[object key]
-    {
-      get
-      {
-        ValidationUtils.ArgumentNotNull(key, "o");
-
-        string propertyName = key as string;
-        if (propertyName == null)
-          throw new ArgumentException("Accessed JObject values with invalid key value: {0}. Object property name expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key)));
-
-        return this[propertyName];
-      }
-      set
-      {
-        ValidationUtils.ArgumentNotNull(key, "o");
-
-        string propertyName = key as string;
-        if (propertyName == null)
-          throw new ArgumentException("Set JObject values with invalid key value: {0}. Object property name expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key)));
-
-        this[propertyName] = value;
-      }
-    }
-
-    /// <summary>
-    /// Gets or sets the <see cref="Newtonsoft.Json.Linq.JToken"/> with the specified property name.
-    /// </summary>
-    /// <value></value>
-    public JToken this[string propertyName]
-    {
-      get
-      {
-        ValidationUtils.ArgumentNotNull(propertyName, "propertyName");
-
-        JProperty property = Property(propertyName);
-
-        return (property != null) ? property.Value : null;
-      }
-      set
-      {
-        JProperty property = Property(propertyName);
-        if (property != null)
-        {
-          property.Value = value;
-        }
-        else
-        {
-#if !PocketPC && !SILVERLIGHT && !NET20
-          OnPropertyChanging(propertyName);
-#endif
-          Add(new JProperty(propertyName, value));
-          OnPropertyChanged(propertyName);
-        }
-      }
-    }
-
-    /// <summary>
-    /// Loads an <see cref="JObject"/> from a <see cref="JsonReader"/>. 
-    /// </summary>
-    /// <param name="reader">A <see cref="JsonReader"/> that will be read for the content of the <see cref="JObject"/>.</param>
-    /// <returns>A <see cref="JObject"/> that contains the JSON that was read from the specified <see cref="JsonReader"/>.</returns>
-    public static JObject Load(JsonReader reader)
-    {
-      ValidationUtils.ArgumentNotNull(reader, "reader");
-
-      if (reader.TokenType == JsonToken.None)
-      {
-        if (!reader.Read())
-          throw new Exception("Error reading JObject from JsonReader.");
-      }
-      if (reader.TokenType != JsonToken.StartObject)
-        throw new Exception(
-          "Error reading JObject from JsonReader. Current JsonReader item is not an object: {0}".FormatWith(
-            CultureInfo.InvariantCulture, reader.TokenType));
-
-      JObject o = new JObject();
-      o.SetLineInfo(reader as IJsonLineInfo);
-      
-      if (!reader.Read())
-        throw new Exception("Error reading JObject from JsonReader.");
-
-      o.ReadContentFrom(reader);
-
-      return o;
-    }
-
-    /// <summary>
-    /// Load a <see cref="JObject"/> from a string that contains JSON.
-    /// </summary>
-    /// <param name="json">A <see cref="String"/> that contains JSON.</param>
-    /// <returns>A <see cref="JObject"/> populated from the string that contains JSON.</returns>
-    public static JObject Parse(string json)
-    {
-      JsonReader jsonReader = new JsonTextReader(new StringReader(json));
-
-      return Load(jsonReader);
-    }
-
-    /// <summary>
-    /// Creates a <see cref="JObject"/> from an object.
-    /// </summary>
-    /// <param name="o">The object that will be used to create <see cref="JObject"/>.</param>
-    /// <returns>A <see cref="JObject"/> with the values of the specified object</returns>
-    public static new JObject FromObject(object o)
-    {
-      return FromObject(o, new JsonSerializer());
-    }
-
-    /// <summary>
-    /// Creates a <see cref="JArray"/> from an object.
-    /// </summary>
-    /// <param name="o">The object that will be used to create <see cref="JArray"/>.</param>
-    /// <param name="jsonSerializer">The <see cref="JsonSerializer"/> that will be used to read the object.</param>
-    /// <returns>A <see cref="JArray"/> with the values of the specified object</returns>
-    public static new JObject FromObject(object o, JsonSerializer jsonSerializer)
-    {
-      JToken token = FromObjectInternal(o, jsonSerializer);
-
-      if (token != null && token.Type != JTokenType.Object)
-        throw new ArgumentException("Object serialized to {0}. JObject instance expected.".FormatWith(CultureInfo.InvariantCulture, token.Type));
-
-      return (JObject)token;
-    }
-
-    /// <summary>
-    /// Writes this token to a <see cref="JsonWriter"/>.
-    /// </summary>
-    /// <param name="writer">A <see cref="JsonWriter"/> into which this method will write.</param>
-    /// <param name="converters">A collection of <see cref="JsonConverter"/> which will be used when writing the token.</param>
-    public override void WriteTo(JsonWriter writer, params JsonConverter[] converters)
-    {
-      writer.WriteStartObject();
-
-      foreach (JProperty property in ChildrenInternal())
-      {
-        property.WriteTo(writer, converters);
-      }
-
-      writer.WriteEndObject();
-    }
-
-    #region IDictionary<string,JToken> Members
-    /// <summary>
-    /// Adds the specified property name.
-    /// </summary>
-    /// <param name="propertyName">Name of the property.</param>
-    /// <param name="value">The value.</param>
-    public void Add(string propertyName, JToken value)
-    {
-      Add(new JProperty(propertyName, value));
-    }
-
-    bool IDictionary<string, JToken>.ContainsKey(string key)
-    {
-      return (Property(key) != null);
-    }
-
-    ICollection<string> IDictionary<string, JToken>.Keys
-    {
-      get { throw new NotImplementedException(); }
-    }
-
-    /// <summary>
-    /// Removes the property with the specified name.
-    /// </summary>
-    /// <param name="propertyName">Name of the property.</param>
-    /// <returns>true if item was successfully removed; otherwise, false.</returns>
-    public bool Remove(string propertyName)
-    {
-      JProperty property = Property(propertyName);
-      if (property == null)
-        return false;
-
-      property.Remove();
-      return true;
-    }
-
-    /// <summary>
-    /// Tries the get value.
-    /// </summary>
-    /// <param name="propertyName">Name of the property.</param>
-    /// <param name="value">The value.</param>
-    /// <returns>true if a value was successfully retrieved; otherwise, false.</returns>
-    public bool TryGetValue(string propertyName, out JToken value)
-    {
-      JProperty property = Property(propertyName);
-      if (property == null)
-      {
-        value = null;
-        return false;
-      }
-
-      value = property.Value;
-      return true;
-    }
-
-    ICollection<JToken> IDictionary<string, JToken>.Values
-    {
-      get { throw new NotImplementedException(); }
-    }
-
-    #endregion
-
-    #region ICollection<KeyValuePair<string,JToken>> Members
-
-    void ICollection<KeyValuePair<string,JToken>>.Add(KeyValuePair<string, JToken> item)
-    {
-      Add(new JProperty(item.Key, item.Value));
-    }
-
-    void ICollection<KeyValuePair<string, JToken>>.Clear()
-    {
-      RemoveAll();
-    }
-
-    bool ICollection<KeyValuePair<string,JToken>>.Contains(KeyValuePair<string, JToken> item)
-    {
-      JProperty property = Property(item.Key);
-      if (property == null)
-        return false;
-
-      return (property.Value == item.Value);
-    }
-
-    void ICollection<KeyValuePair<string,JToken>>.CopyTo(KeyValuePair<string, JToken>[] array, int arrayIndex)
-    {
-      if (array == null)
-        throw new ArgumentNullException("array");
-      if (arrayIndex < 0)
-        throw new ArgumentOutOfRangeException("arrayIndex", "arrayIndex is less than 0.");
-      if (arrayIndex >= array.Length)
-        throw new ArgumentException("arrayIndex is equal to or greater than the length of array.");
-      if (Count > array.Length - arrayIndex)
-        throw new ArgumentException("The number of elements in the source JObject is greater than the available space from arrayIndex to the end of the destination array.");
-
-      int index = 0;
-      foreach (JProperty property in Properties())
-      {
-        array[arrayIndex + index] = new KeyValuePair<string, JToken>(property.Name, property.Value);
-        index++;
-      }
-    }
-
-    /// <summary>
-    /// Gets the number of elements contained in the <see cref="T:System.Collections.Generic.ICollection`1"/>.
-    /// </summary>
-    /// <value></value>
-    /// <returns>The number of elements contained in the <see cref="T:System.Collections.Generic.ICollection`1"/>.</returns>
-    public int Count
-    {
-      get { return Children().Count(); }
-    }
-
-    bool ICollection<KeyValuePair<string,JToken>>.IsReadOnly
-    {
-      get { return false; }
-    }
-
-    bool ICollection<KeyValuePair<string,JToken>>.Remove(KeyValuePair<string, JToken> item)
-    {
-      if (!((ICollection<KeyValuePair<string,JToken>>)this).Contains(item))
-        return false;
-
-      ((IDictionary<string, JToken>)this).Remove(item.Key);
-      return true;
-    }
-
-    #endregion
-
-    internal override int GetDeepHashCode()
-    {
-      return ContentsHashCode();
-    }
-
-    /// <summary>
-    /// Returns an enumerator that iterates through the collection.
-    /// </summary>
-    /// <returns>
-    /// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
-    /// </returns>
-    public IEnumerator<KeyValuePair<string, JToken>> GetEnumerator()
-    {
-      foreach (JProperty property in Properties())
-      {
-        yield return new KeyValuePair<string, JToken>(property.Name, property.Value);
-      }
-    }
-
-    /// <summary>
-    /// Raises the <see cref="PropertyChanged"/> event with the provided arguments.
-    /// </summary>
-    /// <param name="propertyName">Name of the property.</param>
-    protected virtual void OnPropertyChanged(string propertyName)
-    {
-      if (PropertyChanged != null)
-        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
-    }
-
-#if !PocketPC && !SILVERLIGHT && !NET20
-    /// <summary>
-    /// Raises the <see cref="PropertyChanging"/> event with the provided arguments.
-    /// </summary>
-    /// <param name="propertyName">Name of the property.</param>
-    protected virtual void OnPropertyChanging(string propertyName)
-    {
-      if (PropertyChanging != null)
-        PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
-    }
-#endif
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+#if !PORTABLE
+using System.Collections.Specialized;
+#endif
+using System.ComponentModel;
+#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
+using System.Dynamic;
+using System.Linq.Expressions;
+#endif
+using System.IO;
+using Newtonsoft.Json.Utilities;
+using System.Globalization;
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#else
+using System.Linq;
+#endif
+
+namespace Newtonsoft.Json.Linq
+{
+  /// <summary>
+  /// Represents a JSON object.
+  /// </summary>
+  /// <example>
+  ///   <code lang="cs" source="..\Src\Newtonsoft.Json.Tests\Documentation\LinqToJsonTests.cs" region="LinqToJsonCreateParse" title="Parsing a JSON Object from Text" />
+  /// </example>
+  public class JObject : JContainer, IDictionary<string, JToken>, INotifyPropertyChanged
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+    , ICustomTypeDescriptor
+#endif
+#if !(SILVERLIGHT || NET20 || NETFX_CORE || PORTABLE)
+    , INotifyPropertyChanging
+#endif
+  {
+    private readonly JPropertyKeyedCollection _properties = new JPropertyKeyedCollection();
+
+    /// <summary>
+    /// Gets the container's children tokens.
+    /// </summary>
+    /// <value>The container's children tokens.</value>
+    protected override IList<JToken> ChildrenTokens
+    {
+      get { return _properties; }
+    }
+
+    /// <summary>
+    /// Occurs when a property value changes.
+    /// </summary>
+    public event PropertyChangedEventHandler PropertyChanged;
+
+#if !(SILVERLIGHT || NET20 || NETFX_CORE || PORTABLE)
+    /// <summary>
+    /// Occurs when a property value is changing.
+    /// </summary>
+    public event PropertyChangingEventHandler PropertyChanging;
+#endif
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JObject"/> class.
+    /// </summary>
+    public JObject()
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JObject"/> class from another <see cref="JObject"/> object.
+    /// </summary>
+    /// <param name="other">A <see cref="JObject"/> object to copy from.</param>
+    public JObject(JObject other)
+      : base(other)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JObject"/> class with the specified content.
+    /// </summary>
+    /// <param name="content">The contents of the object.</param>
+    public JObject(params object[] content)
+      : this((object)content)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JObject"/> class with the specified content.
+    /// </summary>
+    /// <param name="content">The contents of the object.</param>
+    public JObject(object content)
+    {
+      Add(content);
+    }
+
+    internal override bool DeepEquals(JToken node)
+    {
+      JObject t = node as JObject;
+      if (t == null)
+        return false;
+
+      return _properties.Compare(t._properties);
+    }
+
+    internal override void InsertItem(int index, JToken item, bool skipParentCheck)
+    {
+      // don't add comments to JObject, no name to reference comment by
+      if (item != null && item.Type == JTokenType.Comment)
+        return;
+
+      base.InsertItem(index, item, skipParentCheck);
+    }
+
+    internal override void ValidateToken(JToken o, JToken existing)
+    {
+      ValidationUtils.ArgumentNotNull(o, "o");
+
+      if (o.Type != JTokenType.Property)
+        throw new ArgumentException("Can not add {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, o.GetType(), GetType()));
+
+      JProperty newProperty = (JProperty) o;
+
+      if (existing != null)
+      {
+        JProperty existingProperty = (JProperty) existing;
+
+        if (newProperty.Name == existingProperty.Name)
+          return;
+      }
+
+      if (_properties.TryGetValue(newProperty.Name, out existing))
+        throw new ArgumentException("Can not add property {0} to {1}. Property with the same name already exists on object.".FormatWith(CultureInfo.InvariantCulture, newProperty.Name, GetType()));
+    }
+
+    internal void InternalPropertyChanged(JProperty childProperty)
+    {
+      OnPropertyChanged(childProperty.Name);
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+      OnListChanged(new ListChangedEventArgs(ListChangedType.ItemChanged, IndexOfItem(childProperty)));
+#endif
+#if SILVERLIGHT || !(NET20 || NET35 || PORTABLE)
+      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, childProperty, childProperty, IndexOfItem(childProperty)));
+#endif
+    }
+
+    internal void InternalPropertyChanging(JProperty childProperty)
+    {
+#if !(SILVERLIGHT || NET20 || NETFX_CORE || PORTABLE)
+      OnPropertyChanging(childProperty.Name);
+#endif
+    }
+
+    internal override JToken CloneToken()
+    {
+      return new JObject(this);
+    }
+
+    /// <summary>
+    /// Gets the node type for this <see cref="JToken"/>.
+    /// </summary>
+    /// <value>The type.</value>
+    public override JTokenType Type
+    {
+      get { return JTokenType.Object; }
+    }
+
+    /// <summary>
+    /// Gets an <see cref="IEnumerable{JProperty}"/> of this object's properties.
+    /// </summary>
+    /// <returns>An <see cref="IEnumerable{JProperty}"/> of this object's properties.</returns>
+    public IEnumerable<JProperty> Properties()
+    {
+      return ChildrenTokens.Cast<JProperty>();
+    }
+
+    /// <summary>
+    /// Gets a <see cref="JProperty"/> the specified name.
+    /// </summary>
+    /// <param name="name">The property name.</param>
+    /// <returns>A <see cref="JProperty"/> with the specified name or null.</returns>
+    public JProperty Property(string name)
+    {
+      if (name == null)
+        return null;
+
+      JToken property;
+      _properties.TryGetValue(name, out property);
+      return (JProperty)property;
+    }
+
+    /// <summary>
+    /// Gets an <see cref="JEnumerable{JToken}"/> of this object's property values.
+    /// </summary>
+    /// <returns>An <see cref="JEnumerable{JToken}"/> of this object's property values.</returns>
+    public JEnumerable<JToken> PropertyValues()
+    {
+      return new JEnumerable<JToken>(Properties().Select(p => p.Value));
+    }
+
+    /// <summary>
+    /// Gets the <see cref="JToken"/> with the specified key.
+    /// </summary>
+    /// <value>The <see cref="JToken"/> with the specified key.</value>
+    public override JToken this[object key]
+    {
+      get
+      {
+        ValidationUtils.ArgumentNotNull(key, "o");
+
+        string propertyName = key as string;
+        if (propertyName == null)
+          throw new ArgumentException("Accessed JObject values with invalid key value: {0}. Object property name expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key)));
+
+        return this[propertyName];
+      }
+      set
+      {
+        ValidationUtils.ArgumentNotNull(key, "o");
+
+        string propertyName = key as string;
+        if (propertyName == null)
+          throw new ArgumentException("Set JObject values with invalid key value: {0}. Object property name expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key)));
+
+        this[propertyName] = value;
+      }
+    }
+
+    /// <summary>
+    /// Gets or sets the <see cref="Newtonsoft.Json.Linq.JToken"/> with the specified property name.
+    /// </summary>
+    /// <value></value>
+    public JToken this[string propertyName]
+    {
+      get
+      {
+        ValidationUtils.ArgumentNotNull(propertyName, "propertyName");
+
+        JProperty property = Property(propertyName);
+
+        return (property != null) ? property.Value : null;
+      }
+      set
+      {
+        JProperty property = Property(propertyName);
+        if (property != null)
+        {
+          property.Value = value;
+        }
+        else
+        {
+#if !(SILVERLIGHT || NET20 || NETFX_CORE || PORTABLE)
+          OnPropertyChanging(propertyName);
+#endif
+          Add(new JProperty(propertyName, value));
+          OnPropertyChanged(propertyName);
+        }
+      }
+    }
+
+    /// <summary>
+    /// Loads an <see cref="JObject"/> from a <see cref="JsonReader"/>. 
+    /// </summary>
+    /// <param name="reader">A <see cref="JsonReader"/> that will be read for the content of the <see cref="JObject"/>.</param>
+    /// <returns>A <see cref="JObject"/> that contains the JSON that was read from the specified <see cref="JsonReader"/>.</returns>
+    public static new JObject Load(JsonReader reader)
+    {
+      ValidationUtils.ArgumentNotNull(reader, "reader");
+
+      if (reader.TokenType == JsonToken.None)
+      {
+        if (!reader.Read())
+          throw JsonReaderException.Create(reader, "Error reading JObject from JsonReader.");
+      }
+
+      while (reader.TokenType == JsonToken.Comment)
+      {
+        reader.Read();
+      }
+
+      if (reader.TokenType != JsonToken.StartObject)
+      {
+        throw JsonReaderException.Create(reader, "Error reading JObject from JsonReader. Current JsonReader item is not an object: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
+      }
+
+      JObject o = new JObject();
+      o.SetLineInfo(reader as IJsonLineInfo);
+      
+      o.ReadTokenFrom(reader);
+
+      return o;
+    }
+
+    /// <summary>
+    /// Load a <see cref="JObject"/> from a string that contains JSON.
+    /// </summary>
+    /// <param name="json">A <see cref="String"/> that contains JSON.</param>
+    /// <returns>A <see cref="JObject"/> populated from the string that contains JSON.</returns>
+    /// <example>
+    ///   <code lang="cs" source="..\Src\Newtonsoft.Json.Tests\Documentation\LinqToJsonTests.cs" region="LinqToJsonCreateParse" title="Parsing a JSON Object from Text" />
+    /// </example>
+    public static new JObject Parse(string json)
+    {
+      JsonReader reader = new JsonTextReader(new StringReader(json));
+
+      JObject o = Load(reader);
+
+      if (reader.Read() && reader.TokenType != JsonToken.Comment)
+        throw JsonReaderException.Create(reader, "Additional text found in JSON string after parsing content.");
+
+      return o;
+    }
+
+    /// <summary>
+    /// Creates a <see cref="JObject"/> from an object.
+    /// </summary>
+    /// <param name="o">The object that will be used to create <see cref="JObject"/>.</param>
+    /// <returns>A <see cref="JObject"/> with the values of the specified object</returns>
+    public static new JObject FromObject(object o)
+    {
+      return FromObject(o, new JsonSerializer());
+    }
+
+    /// <summary>
+    /// Creates a <see cref="JArray"/> from an object.
+    /// </summary>
+    /// <param name="o">The object that will be used to create <see cref="JArray"/>.</param>
+    /// <param name="jsonSerializer">The <see cref="JsonSerializer"/> that will be used to read the object.</param>
+    /// <returns>A <see cref="JArray"/> with the values of the specified object</returns>
+    public static new JObject FromObject(object o, JsonSerializer jsonSerializer)
+    {
+      JToken token = FromObjectInternal(o, jsonSerializer);
+
+      if (token != null && token.Type != JTokenType.Object)
+        throw new ArgumentException("Object serialized to {0}. JObject instance expected.".FormatWith(CultureInfo.InvariantCulture, token.Type));
+
+      return (JObject)token;
+    }
+
+    /// <summary>
+    /// Writes this token to a <see cref="JsonWriter"/>.
+    /// </summary>
+    /// <param name="writer">A <see cref="JsonWriter"/> into which this method will write.</param>
+    /// <param name="converters">A collection of <see cref="JsonConverter"/> which will be used when writing the token.</param>
+    public override void WriteTo(JsonWriter writer, params JsonConverter[] converters)
+    {
+      writer.WriteStartObject();
+
+      foreach (JProperty property in ChildrenTokens)
+      {
+        property.WriteTo(writer, converters);
+      }
+
+      writer.WriteEndObject();
+    }
+
+    #region IDictionary<string,JToken> Members
+    /// <summary>
+    /// Adds the specified property name.
+    /// </summary>
+    /// <param name="propertyName">Name of the property.</param>
+    /// <param name="value">The value.</param>
+    public void Add(string propertyName, JToken value)
+    {
+      Add(new JProperty(propertyName, value));
+    }
+
+    bool IDictionary<string, JToken>.ContainsKey(string key)
+    {
+      return _properties.Contains(key);
+    }
+
+    ICollection<string> IDictionary<string, JToken>.Keys
+    {
+      // todo: make order the collection returned match JObject order
+      get { return _properties.Keys; }
+    }
+
+    /// <summary>
+    /// Removes the property with the specified name.
+    /// </summary>
+    /// <param name="propertyName">Name of the property.</param>
+    /// <returns>true if item was successfully removed; otherwise, false.</returns>
+    public bool Remove(string propertyName)
+    {
+      JProperty property = Property(propertyName);
+      if (property == null)
+        return false;
+
+      property.Remove();
+      return true;
+    }
+
+    /// <summary>
+    /// Tries the get value.
+    /// </summary>
+    /// <param name="propertyName">Name of the property.</param>
+    /// <param name="value">The value.</param>
+    /// <returns>true if a value was successfully retrieved; otherwise, false.</returns>
+    public bool TryGetValue(string propertyName, out JToken value)
+    {
+      JProperty property = Property(propertyName);
+      if (property == null)
+      {
+        value = null;
+        return false;
+      }
+
+      value = property.Value;
+      return true;
+    }
+
+    ICollection<JToken> IDictionary<string, JToken>.Values
+    {
+      get
+      {
+        // todo: need to wrap _properties.Values with a collection to get the JProperty value
+        throw new NotImplementedException();
+      }
+    }
+
+    #endregion
+
+    #region ICollection<KeyValuePair<string,JToken>> Members
+
+    void ICollection<KeyValuePair<string,JToken>>.Add(KeyValuePair<string, JToken> item)
+    {
+      Add(new JProperty(item.Key, item.Value));
+    }
+
+    void ICollection<KeyValuePair<string, JToken>>.Clear()
+    {
+      RemoveAll();
+    }
+
+    bool ICollection<KeyValuePair<string,JToken>>.Contains(KeyValuePair<string, JToken> item)
+    {
+      JProperty property = Property(item.Key);
+      if (property == null)
+        return false;
+
+      return (property.Value == item.Value);
+    }
+
+    void ICollection<KeyValuePair<string,JToken>>.CopyTo(KeyValuePair<string, JToken>[] array, int arrayIndex)
+    {
+      if (array == null)
+        throw new ArgumentNullException("array");
+      if (arrayIndex < 0)
+        throw new ArgumentOutOfRangeException("arrayIndex", "arrayIndex is less than 0.");
+      if (arrayIndex >= array.Length)
+        throw new ArgumentException("arrayIndex is equal to or greater than the length of array.");
+      if (Count > array.Length - arrayIndex)
+        throw new ArgumentException("The number of elements in the source JObject is greater than the available space from arrayIndex to the end of the destination array.");
+
+      int index = 0;
+      foreach (JProperty property in ChildrenTokens)
+      {
+        array[arrayIndex + index] = new KeyValuePair<string, JToken>(property.Name, property.Value);
+        index++;
+      }
+    }
+
+    bool ICollection<KeyValuePair<string,JToken>>.IsReadOnly
+    {
+      get { return false; }
+    }
+
+    bool ICollection<KeyValuePair<string,JToken>>.Remove(KeyValuePair<string, JToken> item)
+    {
+      if (!((ICollection<KeyValuePair<string,JToken>>)this).Contains(item))
+        return false;
+
+      ((IDictionary<string, JToken>)this).Remove(item.Key);
+      return true;
+    }
+
+    #endregion
+
+    internal override int GetDeepHashCode()
+    {
+      return ContentsHashCode();
+    }
+
+    /// <summary>
+    /// Returns an enumerator that iterates through the collection.
+    /// </summary>
+    /// <returns>
+    /// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
+    /// </returns>
+    public IEnumerator<KeyValuePair<string, JToken>> GetEnumerator()
+    {
+      foreach (JProperty property in ChildrenTokens)
+      {
+        yield return new KeyValuePair<string, JToken>(property.Name, property.Value);
+      }
+    }
+
+    /// <summary>
+    /// Raises the <see cref="PropertyChanged"/> event with the provided arguments.
+    /// </summary>
+    /// <param name="propertyName">Name of the property.</param>
+    protected virtual void OnPropertyChanged(string propertyName)
+    {
+      if (PropertyChanged != null)
+        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+    }
+
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE || NET20)
+    /// <summary>
+    /// Raises the <see cref="PropertyChanging"/> event with the provided arguments.
+    /// </summary>
+    /// <param name="propertyName">Name of the property.</param>
+    protected virtual void OnPropertyChanging(string propertyName)
+    {
+      if (PropertyChanging != null)
+        PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
+    }
+#endif
+
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+    // include custom type descriptor on JObject rather than use a provider because the properties are specific to a type
+    #region ICustomTypeDescriptor
+    /// <summary>
+    /// Returns the properties for this instance of a component.
+    /// </summary>
+    /// <returns>
+    /// A <see cref="T:System.ComponentModel.PropertyDescriptorCollection"/> that represents the properties for this component instance.
+    /// </returns>
+    PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties()
+    {
+      return ((ICustomTypeDescriptor) this).GetProperties(null);
+    }
+
+    private static Type GetTokenPropertyType(JToken token)
+    {
+      if (token is JValue)
+      {
+        JValue v = (JValue)token;
+        return (v.Value != null) ? v.Value.GetType() : typeof(object);
+      }
+
+      return token.GetType();
+    }
+
+    /// <summary>
+    /// Returns the properties for this instance of a component using the attribute array as a filter.
+    /// </summary>
+    /// <param name="attributes">An array of type <see cref="T:System.Attribute"/> that is used as a filter.</param>
+    /// <returns>
+    /// A <see cref="T:System.ComponentModel.PropertyDescriptorCollection"/> that represents the filtered properties for this component instance.
+    /// </returns>
+    PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes)
+    {
+      PropertyDescriptorCollection descriptors = new PropertyDescriptorCollection(null);
+
+      foreach (KeyValuePair<string, JToken> propertyValue in this)
+      {
+        descriptors.Add(new JPropertyDescriptor(propertyValue.Key, GetTokenPropertyType(propertyValue.Value)));
+      }
+
+      return descriptors;
+    }
+
+    /// <summary>
+    /// Returns a collection of custom attributes for this instance of a component.
+    /// </summary>
+    /// <returns>
+    /// An <see cref="T:System.ComponentModel.AttributeCollection"/> containing the attributes for this object.
+    /// </returns>
+    AttributeCollection ICustomTypeDescriptor.GetAttributes()
+    {
+      return AttributeCollection.Empty;
+    }
+
+    /// <summary>
+    /// Returns the class name of this instance of a component.
+    /// </summary>
+    /// <returns>
+    /// The class name of the object, or null if the class does not have a name.
+    /// </returns>
+    string ICustomTypeDescriptor.GetClassName()
+    {
+      return null;
+    }
+
+    /// <summary>
+    /// Returns the name of this instance of a component.
+    /// </summary>
+    /// <returns>
+    /// The name of the object, or null if the object does not have a name.
+    /// </returns>
+    string ICustomTypeDescriptor.GetComponentName()
+    {
+      return null;
+    }
+
+    /// <summary>
+    /// Returns a type converter for this instance of a component.
+    /// </summary>
+    /// <returns>
+    /// A <see cref="T:System.ComponentModel.TypeConverter"/> that is the converter for this object, or null if there is no <see cref="T:System.ComponentModel.TypeConverter"/> for this object.
+    /// </returns>
+    TypeConverter ICustomTypeDescriptor.GetConverter()
+    {
+      return new TypeConverter();
+    }
+
+    /// <summary>
+    /// Returns the default event for this instance of a component.
+    /// </summary>
+    /// <returns>
+    /// An <see cref="T:System.ComponentModel.EventDescriptor"/> that represents the default event for this object, or null if this object does not have events.
+    /// </returns>
+    EventDescriptor ICustomTypeDescriptor.GetDefaultEvent()
+    {
+      return null;
+    }
+
+    /// <summary>
+    /// Returns the default property for this instance of a component.
+    /// </summary>
+    /// <returns>
+    /// A <see cref="T:System.ComponentModel.PropertyDescriptor"/> that represents the default property for this object, or null if this object does not have properties.
+    /// </returns>
+    PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty()
+    {
+      return null;
+    }
+
+    /// <summary>
+    /// Returns an editor of the specified type for this instance of a component.
+    /// </summary>
+    /// <param name="editorBaseType">A <see cref="T:System.Type"/> that represents the editor for this object.</param>
+    /// <returns>
+    /// An <see cref="T:System.Object"/> of the specified type that is the editor for this object, or null if the editor cannot be found.
+    /// </returns>
+    object ICustomTypeDescriptor.GetEditor(Type editorBaseType)
+    {
+      return null;
+    }
+
+    /// <summary>
+    /// Returns the events for this instance of a component using the specified attribute array as a filter.
+    /// </summary>
+    /// <param name="attributes">An array of type <see cref="T:System.Attribute"/> that is used as a filter.</param>
+    /// <returns>
+    /// An <see cref="T:System.ComponentModel.EventDescriptorCollection"/> that represents the filtered events for this component instance.
+    /// </returns>
+    EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes)
+    {
+      return EventDescriptorCollection.Empty;
+    }
+
+    /// <summary>
+    /// Returns the events for this instance of a component.
+    /// </summary>
+    /// <returns>
+    /// An <see cref="T:System.ComponentModel.EventDescriptorCollection"/> that represents the events for this component instance.
+    /// </returns>
+    EventDescriptorCollection ICustomTypeDescriptor.GetEvents()
+    {
+      return EventDescriptorCollection.Empty;
+    }
+
+    /// <summary>
+    /// Returns an object that contains the property described by the specified property descriptor.
+    /// </summary>
+    /// <param name="pd">A <see cref="T:System.ComponentModel.PropertyDescriptor"/> that represents the property whose owner is to be found.</param>
+    /// <returns>
+    /// An <see cref="T:System.Object"/> that represents the owner of the specified property.
+    /// </returns>
+    object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd)
+    {
+      return null;
+    }
+    #endregion
+#endif
+
+#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
+    /// <summary>
+    /// Returns the <see cref="T:System.Dynamic.DynamicMetaObject"/> responsible for binding operations performed on this object.
+    /// </summary>
+    /// <param name="parameter">The expression tree representation of the runtime value.</param>
+    /// <returns>
+    /// The <see cref="T:System.Dynamic.DynamicMetaObject"/> to bind this object.
+    /// </returns>
+    protected override DynamicMetaObject GetMetaObject(Expression parameter)
+    {
+      return new DynamicProxyMetaObject<JObject>(parameter, this, new JObjectDynamicProxy(), true);
+    }
+
+    private class JObjectDynamicProxy : DynamicProxy<JObject>
+    {
+      public override bool TryGetMember(JObject instance, GetMemberBinder binder, out object result)
+      {
+        // result can be null
+        result = instance[binder.Name];
+        return true;
+      }
+
+      public override bool TrySetMember(JObject instance, SetMemberBinder binder, object value)
+      {
+        JToken v = value as JToken;
+
+        // this can throw an error if value isn't a valid for a JValue
+        if (v == null)
+          v = new JValue(value);
+
+        instance[binder.Name] = v;
+        return true;
+      }
+
+      public override IEnumerable<string> GetDynamicMemberNames(JObject instance)
+      {
+        return instance.Properties().Select(p => p.Name);
+      }
+    }
+#endif
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JPath.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JPath.cs
index 0b1b3e3..572144f 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JPath.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JPath.cs
@@ -1,170 +1,208 @@
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using Newtonsoft.Json.Utilities;
-
-namespace Newtonsoft.Json.Linq
-{
-  internal class JPath
-  {
-    private readonly string _expression;
-    public List<object> Parts { get; private set; }
-
-    private int _currentIndex;
-
-    public JPath(string expression)
-    {
-      ValidationUtils.ArgumentNotNull(expression, "expression");
-      _expression = expression;
-      Parts = new List<object>();
-
-      ParseMain();
-    }
-
-    private void ParseMain()
-    {
-      int currentPartStartIndex = _currentIndex;
-      bool followingIndexer = false;
-
-      while (_currentIndex < _expression.Length)
-      {
-        char currentChar = _expression[_currentIndex];
-
-        switch (currentChar)
-        {
-          case '[':
-          case '(':
-            if (_currentIndex > currentPartStartIndex)
-            {
-              string member = _expression.Substring(currentPartStartIndex, _currentIndex - currentPartStartIndex);
-              Parts.Add(member);
-            }
-
-            ParseIndexer(currentChar);
-            currentPartStartIndex = _currentIndex + 1;
-            followingIndexer = true;
-            break;
-          case ']':
-          case ')':
-            throw new Exception("Unexpected character while parsing path: " + currentChar);
-          case '.':
-            if (_currentIndex > currentPartStartIndex)
-            {
-              string member = _expression.Substring(currentPartStartIndex, _currentIndex - currentPartStartIndex);
-              Parts.Add(member);
-            }
-            currentPartStartIndex = _currentIndex + 1;
-            followingIndexer = false;
-            break;
-          default:
-            if (followingIndexer)
-              throw new Exception("Unexpected character following indexer: " + currentChar);
-            break;
-        }
-
-        _currentIndex++;
-      }
-
-      if (_currentIndex - 1 > currentPartStartIndex)
-      {
-        string member = _expression.Substring(currentPartStartIndex, _currentIndex - currentPartStartIndex);
-        Parts.Add(member);
-      }
-    }
-
-    private void ParseIndexer(char indexerOpenChar)
-    {
-      _currentIndex++;
-
-      char indexerCloseChar = (indexerOpenChar == '[') ? ']' : ')';
-      int indexerStart = _currentIndex;
-      int indexerLength = 0;
-      bool indexerClosed = false;
-
-      while (_currentIndex < _expression.Length)
-      {
-        char currentCharacter = _expression[_currentIndex];
-        if (char.IsDigit(currentCharacter))
-        {
-          indexerLength++;
-        }
-        else if (currentCharacter == indexerCloseChar)
-        {
-          indexerClosed = true;
-          break;
-        }
-        else
-        {
-          throw new Exception("Unexpected character while parsing path indexer: " + currentCharacter);
-        }
-
-        _currentIndex++;
-      }
-
-      if (!indexerClosed)
-        throw new Exception("Path ended with open indexer. Expected " + indexerCloseChar);
-
-      if (indexerLength == 0)
-        throw new Exception("Empty path indexer.");
-
-      string indexer = _expression.Substring(indexerStart, indexerLength);
-      Parts.Add(Convert.ToInt32(indexer, CultureInfo.InvariantCulture));
-    }
-
-    internal JToken Evaluate(JToken root, bool errorWhenNoMatch)
-    {
-      JToken current = root;
-
-      foreach (object part in Parts)
-      {
-        string propertyName = part as string;
-        if (propertyName != null)
-        {
-          JObject o = current as JObject;
-          if (o != null)
-          {
-            current = o[propertyName];
-
-            if (current == null && errorWhenNoMatch)
-              throw new Exception("Property '{0}' does not exist on JObject.".FormatWith(CultureInfo.InvariantCulture, propertyName));
-          }
-          else
-          {
-            if (errorWhenNoMatch)
-              throw new Exception("Property '{0}' not valid on {1}.".FormatWith(CultureInfo.InvariantCulture, propertyName, current.GetType().Name));
-
-            return null;
-          }
-        }
-        else
-        {
-          int index = (int) part;
-
-          JArray a = current as JArray;
-
-          if (a != null)
-          {
-            if (a.Count <= index)
-            {
-              if (errorWhenNoMatch)
-                throw new IndexOutOfRangeException("Index {0} outside the bounds of JArray.".FormatWith(CultureInfo.InvariantCulture, index));
-              
-              return null;
-            }
-
-            current = a[index];
-          }
-          else
-          {
-            if (errorWhenNoMatch)
-              throw new Exception("Index {0} not valid on {1}.".FormatWith(CultureInfo.InvariantCulture, index, current.GetType().Name));
-
-            return null;
-          }
-        }
-      }
-
-      return current;
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Linq
+{
+  internal class JPath
+  {
+    private readonly string _expression;
+    public List<object> Parts { get; private set; }
+
+    private int _currentIndex;
+
+    public JPath(string expression)
+    {
+      ValidationUtils.ArgumentNotNull(expression, "expression");
+      _expression = expression;
+      Parts = new List<object>();
+
+      ParseMain();
+    }
+
+    private void ParseMain()
+    {
+      int currentPartStartIndex = _currentIndex;
+      bool followingIndexer = false;
+
+      while (_currentIndex < _expression.Length)
+      {
+        char currentChar = _expression[_currentIndex];
+
+        switch (currentChar)
+        {
+          case '[':
+          case '(':
+            if (_currentIndex > currentPartStartIndex)
+            {
+              string member = _expression.Substring(currentPartStartIndex, _currentIndex - currentPartStartIndex);
+              Parts.Add(member);
+            }
+
+            ParseIndexer(currentChar);
+            currentPartStartIndex = _currentIndex + 1;
+            followingIndexer = true;
+            break;
+          case ']':
+          case ')':
+            throw new JsonException("Unexpected character while parsing path: " + currentChar);
+          case '.':
+            if (_currentIndex > currentPartStartIndex)
+            {
+              string member = _expression.Substring(currentPartStartIndex, _currentIndex - currentPartStartIndex);
+              Parts.Add(member);
+            }
+            currentPartStartIndex = _currentIndex + 1;
+            followingIndexer = false;
+            break;
+          default:
+            if (followingIndexer)
+              throw new JsonException("Unexpected character following indexer: " + currentChar);
+            break;
+        }
+
+        _currentIndex++;
+      }
+
+      if (_currentIndex > currentPartStartIndex)
+      {
+        string member = _expression.Substring(currentPartStartIndex, _currentIndex - currentPartStartIndex);
+        Parts.Add(member);
+      }
+    }
+
+    private void ParseIndexer(char indexerOpenChar)
+    {
+      _currentIndex++;
+
+      char indexerCloseChar = (indexerOpenChar == '[') ? ']' : ')';
+      int indexerStart = _currentIndex;
+      int indexerLength = 0;
+      bool indexerClosed = false;
+
+      while (_currentIndex < _expression.Length)
+      {
+        char currentCharacter = _expression[_currentIndex];
+        if (char.IsDigit(currentCharacter))
+        {
+          indexerLength++;
+        }
+        else if (currentCharacter == indexerCloseChar)
+        {
+          indexerClosed = true;
+          break;
+        }
+        else
+        {
+          throw new JsonException("Unexpected character while parsing path indexer: " + currentCharacter);
+        }
+
+        _currentIndex++;
+      }
+
+      if (!indexerClosed)
+        throw new JsonException("Path ended with open indexer. Expected " + indexerCloseChar);
+
+      if (indexerLength == 0)
+        throw new JsonException("Empty path indexer.");
+
+      string indexer = _expression.Substring(indexerStart, indexerLength);
+      Parts.Add(Convert.ToInt32(indexer, CultureInfo.InvariantCulture));
+    }
+
+    internal JToken Evaluate(JToken root, bool errorWhenNoMatch)
+    {
+      JToken current = root;
+
+      foreach (object part in Parts)
+      {
+        string propertyName = part as string;
+        if (propertyName != null)
+        {
+          JObject o = current as JObject;
+          if (o != null)
+          {
+            current = o[propertyName];
+
+            if (current == null && errorWhenNoMatch)
+              throw new JsonException("Property '{0}' does not exist on JObject.".FormatWith(CultureInfo.InvariantCulture, propertyName));
+          }
+          else
+          {
+            if (errorWhenNoMatch)
+              throw new JsonException("Property '{0}' not valid on {1}.".FormatWith(CultureInfo.InvariantCulture, propertyName, current.GetType().Name));
+
+            return null;
+          }
+        }
+        else
+        {
+          int index = (int) part;
+
+          JArray a = current as JArray;
+          JConstructor c = current as JConstructor;
+
+          if (a != null)
+          {
+            if (a.Count <= index)
+            {
+              if (errorWhenNoMatch)
+                throw new IndexOutOfRangeException("Index {0} outside the bounds of JArray.".FormatWith(CultureInfo.InvariantCulture, index));
+              
+              return null;
+            }
+
+            current = a[index];
+          }
+          else if (c != null)
+          {
+            if (c.Count <= index)
+            {
+              if (errorWhenNoMatch)
+                throw new IndexOutOfRangeException("Index {0} outside the bounds of JConstructor.".FormatWith(CultureInfo.InvariantCulture, index));
+
+              return null;
+            }
+
+            current = c[index];
+          }
+          else
+          {
+            if (errorWhenNoMatch)
+              throw new JsonException("Index {0} not valid on {1}.".FormatWith(CultureInfo.InvariantCulture, index, current.GetType().Name));
+
+            return null;
+          }
+        }
+      }
+
+      return current;
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JProperty.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JProperty.cs
index d100388..ccfba60 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JProperty.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JProperty.cs
@@ -1,271 +1,249 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Linq;
-using System.Text;
-using Newtonsoft.Json.Utilities;
-using System.Diagnostics;
-using System.Globalization;
-
-namespace Newtonsoft.Json.Linq
-{
-  /// <summary>
-  /// Represents a JSON property.
-  /// </summary>
-  public class JProperty : JContainer
-  {
-    private readonly string _name;
-
-    /// <summary>
-    /// Gets the property name.
-    /// </summary>
-    /// <value>The property name.</value>
-    public string Name
-    {
-      [DebuggerStepThrough]
-      get { return _name; }
-    }
-
-    /// <summary>
-    /// Gets or sets the property value.
-    /// </summary>
-    /// <value>The property value.</value>
-    public JToken Value
-    {
-      [DebuggerStepThrough]
-      get { return Content; }
-      set
-      {
-        CheckReentrancy();
-
-        JToken newValue = value ?? new JValue((object) null);
-
-        if (Content == null)
-        {
-          newValue = EnsureParentToken(newValue);
-
-          Content = newValue;
-          Content.Parent = this;
-          Content.Next = Content;
-        }
-        else
-        {
-          Content.Replace(newValue);
-        }
-      }
-    }
-
-    internal override void ReplaceItem(JToken existing, JToken replacement)
-    {
-      if (IsTokenUnchanged(existing, replacement))
-        return;
-
-      if (Parent != null)
-        ((JObject)Parent).InternalPropertyChanging(this);
-
-      base.ReplaceItem(existing, replacement);
-
-      if (Parent != null)
-        ((JObject)Parent).InternalPropertyChanged(this);
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JProperty"/> class from another <see cref="JProperty"/> object.
-    /// </summary>
-    /// <param name="other">A <see cref="JProperty"/> object to copy from.</param>
-    public JProperty(JProperty other)
-      : base(other)
-    {
-      _name = other.Name;
-    }
-
-    internal override void AddItem(bool isLast, JToken previous, JToken item)
-    {
-      if (Value != null)
-        throw new Exception("{0} cannot have multiple values.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty)));
-
-      Value = item;
-    }
-
-    internal override JToken GetItem(int index)
-    {
-      if (index != 0)
-        throw new ArgumentOutOfRangeException();
-
-      return Value;
-    }
-
-    internal override void SetItem(int index, JToken item)
-    {
-      if (index != 0)
-        throw new ArgumentOutOfRangeException();
-      
-      Value = item;
-    }
-
-    internal override bool RemoveItem(JToken item)
-    {
-      throw new Exception("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty)));
-    }
-
-    internal override void RemoveItemAt(int index)
-    {
-      throw new Exception("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty)));
-    }
-
-    internal override void InsertItem(int index, JToken item)
-    {
-      throw new Exception("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty)));
-    }
-
-    internal override bool ContainsItem(JToken item)
-    {
-      return (Value == item);
-    }
-
-    internal override void ClearItems()
-    {
-      throw new Exception("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty)));
-    }
-
-    /// <summary>
-    /// Returns a collection of the child tokens of this token, in document order.
-    /// </summary>
-    /// <returns>
-    /// An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> containing the child tokens of this <see cref="JToken"/>, in document order.
-    /// </returns>
-    public override JEnumerable<JToken> Children()
-    {
-      return new JEnumerable<JToken>(GetValueEnumerable());
-    }
-
-    private IEnumerable<JToken> GetValueEnumerable()
-    {
-      yield return Value;
-    }
-
-    internal override bool DeepEquals(JToken node)
-    {
-      JProperty t = node as JProperty;
-      return (t != null && _name == t.Name && ContentsEqual(t));
-    }
-
-    internal override JToken CloneToken()
-    {
-      return new JProperty(this);
-    }
-
-    /// <summary>
-    /// Gets the node type for this <see cref="JToken"/>.
-    /// </summary>
-    /// <value>The type.</value>
-    public override JTokenType Type
-    {
-      [DebuggerStepThrough]
-      get { return JTokenType.Property; }
-    }
-
-    internal JProperty(string name)
-    {
-      // called from JTokenWriter
-      ValidationUtils.ArgumentNotNull(name, "name");
-
-      _name = name;
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JProperty"/> class.
-    /// </summary>
-    /// <param name="name">The property name.</param>
-    /// <param name="content">The property content.</param>
-    public JProperty(string name, params object[] content)
-      : this(name, (object)content)
-    {
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JProperty"/> class.
-    /// </summary>
-    /// <param name="name">The property name.</param>
-    /// <param name="content">The property content.</param>
-    public JProperty(string name, object content)
-    {
-      ValidationUtils.ArgumentNotNull(name, "name");
-
-      _name = name;
-
-      Value = IsMultiContent(content)
-        ? new JArray(content)
-        : CreateFromContent(content);
-    }
-
-    /// <summary>
-    /// Writes this token to a <see cref="JsonWriter"/>.
-    /// </summary>
-    /// <param name="writer">A <see cref="JsonWriter"/> into which this method will write.</param>
-    /// <param name="converters">A collection of <see cref="JsonConverter"/> which will be used when writing the token.</param>
-    public override void WriteTo(JsonWriter writer, params JsonConverter[] converters)
-    {
-      writer.WritePropertyName(_name);
-      Value.WriteTo(writer, converters);
-    }
-
-    internal override int GetDeepHashCode()
-    {
-      return _name.GetHashCode() ^ ((Value != null) ? Value.GetDeepHashCode() : 0);
-    }
-
-    /// <summary>
-    /// Loads an <see cref="JProperty"/> from a <see cref="JsonReader"/>. 
-    /// </summary>
-    /// <param name="reader">A <see cref="JsonReader"/> that will be read for the content of the <see cref="JProperty"/>.</param>
-    /// <returns>A <see cref="JProperty"/> that contains the JSON that was read from the specified <see cref="JsonReader"/>.</returns>
-    public static JProperty Load(JsonReader reader)
-    {
-      if (reader.TokenType == JsonToken.None)
-      {
-        if (!reader.Read())
-          throw new Exception("Error reading JProperty from JsonReader.");
-      }
-      if (reader.TokenType != JsonToken.PropertyName)
-        throw new Exception(
-          "Error reading JProperty from JsonReader. Current JsonReader item is not a property: {0}".FormatWith(
-            CultureInfo.InvariantCulture, reader.TokenType));
-
-      JProperty p = new JProperty((string)reader.Value);
-      p.SetLineInfo(reader as IJsonLineInfo);
-
-      if (!reader.Read())
-        throw new Exception("Error reading JProperty from JsonReader.");
-
-      p.ReadContentFrom(reader);
-
-      return p;
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using Newtonsoft.Json.Utilities;
+using System.Diagnostics;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Linq
+{
+  /// <summary>
+  /// Represents a JSON property.
+  /// </summary>
+  public class JProperty : JContainer
+  {
+    private readonly List<JToken> _content = new List<JToken>();
+    private readonly string _name;
+
+    /// <summary>
+    /// Gets the container's children tokens.
+    /// </summary>
+    /// <value>The container's children tokens.</value>
+    protected override IList<JToken> ChildrenTokens
+    {
+      get { return _content; }
+    }
+
+    /// <summary>
+    /// Gets the property name.
+    /// </summary>
+    /// <value>The property name.</value>
+    public string Name
+    {
+      [DebuggerStepThrough]
+      get { return _name; }
+    }
+
+    /// <summary>
+    /// Gets or sets the property value.
+    /// </summary>
+    /// <value>The property value.</value>
+    public JToken Value
+    {
+      [DebuggerStepThrough]
+      get { return (ChildrenTokens.Count > 0) ? ChildrenTokens[0] : null; }
+      set
+      {
+        CheckReentrancy();
+
+        JToken newValue = value ?? new JValue((object) null);
+
+        if (ChildrenTokens.Count == 0)
+        {
+          InsertItem(0, newValue, false);
+        }
+        else
+        {
+          SetItem(0, newValue);
+        }
+      }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JProperty"/> class from another <see cref="JProperty"/> object.
+    /// </summary>
+    /// <param name="other">A <see cref="JProperty"/> object to copy from.</param>
+    public JProperty(JProperty other)
+      : base(other)
+    {
+      _name = other.Name;
+    }
+
+    internal override JToken GetItem(int index)
+    {
+      if (index != 0)
+        throw new ArgumentOutOfRangeException();
+
+      return Value;
+    }
+
+    internal override void SetItem(int index, JToken item)
+    {
+      if (index != 0)
+        throw new ArgumentOutOfRangeException();
+
+      if (IsTokenUnchanged(Value, item))
+        return;
+
+      if (Parent != null)
+        ((JObject)Parent).InternalPropertyChanging(this);
+
+      base.SetItem(0, item);
+
+      if (Parent != null)
+        ((JObject)Parent).InternalPropertyChanged(this);
+    }
+
+    internal override bool RemoveItem(JToken item)
+    {
+      throw new JsonException("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty)));
+    }
+
+    internal override void RemoveItemAt(int index)
+    {
+      throw new JsonException("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty)));
+    }
+
+    internal override void InsertItem(int index, JToken item, bool skipParentCheck)
+    {
+      if (Value != null)
+        throw new JsonException("{0} cannot have multiple values.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty)));
+
+      base.InsertItem(0, item, false);
+    }
+
+    internal override bool ContainsItem(JToken item)
+    {
+      return (Value == item);
+    }
+
+    internal override void ClearItems()
+    {
+      throw new JsonException("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty)));
+    }
+
+    internal override bool DeepEquals(JToken node)
+    {
+      JProperty t = node as JProperty;
+      return (t != null && _name == t.Name && ContentsEqual(t));
+    }
+
+    internal override JToken CloneToken()
+    {
+      return new JProperty(this);
+    }
+
+    /// <summary>
+    /// Gets the node type for this <see cref="JToken"/>.
+    /// </summary>
+    /// <value>The type.</value>
+    public override JTokenType Type
+    {
+      [DebuggerStepThrough]
+      get { return JTokenType.Property; }
+    }
+
+    internal JProperty(string name)
+    {
+      // called from JTokenWriter
+      ValidationUtils.ArgumentNotNull(name, "name");
+
+      _name = name;
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JProperty"/> class.
+    /// </summary>
+    /// <param name="name">The property name.</param>
+    /// <param name="content">The property content.</param>
+    public JProperty(string name, params object[] content)
+      : this(name, (object)content)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JProperty"/> class.
+    /// </summary>
+    /// <param name="name">The property name.</param>
+    /// <param name="content">The property content.</param>
+    public JProperty(string name, object content)
+    {
+      ValidationUtils.ArgumentNotNull(name, "name");
+
+      _name = name;
+
+      Value = IsMultiContent(content)
+        ? new JArray(content)
+        : CreateFromContent(content);
+    }
+
+    /// <summary>
+    /// Writes this token to a <see cref="JsonWriter"/>.
+    /// </summary>
+    /// <param name="writer">A <see cref="JsonWriter"/> into which this method will write.</param>
+    /// <param name="converters">A collection of <see cref="JsonConverter"/> which will be used when writing the token.</param>
+    public override void WriteTo(JsonWriter writer, params JsonConverter[] converters)
+    {
+      writer.WritePropertyName(_name);
+      Value.WriteTo(writer, converters);
+    }
+
+    internal override int GetDeepHashCode()
+    {
+      return _name.GetHashCode() ^ ((Value != null) ? Value.GetDeepHashCode() : 0);
+    }
+
+    /// <summary>
+    /// Loads an <see cref="JProperty"/> from a <see cref="JsonReader"/>. 
+    /// </summary>
+    /// <param name="reader">A <see cref="JsonReader"/> that will be read for the content of the <see cref="JProperty"/>.</param>
+    /// <returns>A <see cref="JProperty"/> that contains the JSON that was read from the specified <see cref="JsonReader"/>.</returns>
+    public static new JProperty Load(JsonReader reader)
+    {
+      if (reader.TokenType == JsonToken.None)
+      {
+        if (!reader.Read())
+          throw JsonReaderException.Create(reader, "Error reading JProperty from JsonReader.");
+      }
+
+      while (reader.TokenType == JsonToken.Comment)
+      {
+        reader.Read();
+      }
+
+      if (reader.TokenType != JsonToken.PropertyName)
+        throw JsonReaderException.Create(reader, "Error reading JProperty from JsonReader. Current JsonReader item is not a property: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
+
+      JProperty p = new JProperty((string)reader.Value);
+      p.SetLineInfo(reader as IJsonLineInfo);
+
+      p.ReadTokenFrom(reader);
+
+      return p;
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JPropertyDescriptor.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JPropertyDescriptor.cs
new file mode 100644
index 0000000..6f2282b
--- /dev/null
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JPropertyDescriptor.cs
@@ -0,0 +1,173 @@
+#region License
+// 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.
+#endregion
+
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+using System;
+using System.ComponentModel;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Linq
+{
+  /// <summary>
+  /// Represents a view of a <see cref="JProperty"/>.
+  /// </summary>
+  public class JPropertyDescriptor : PropertyDescriptor
+  {
+    private readonly Type _propertyType;
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JPropertyDescriptor"/> class.
+    /// </summary>
+    /// <param name="name">The name.</param>
+    /// <param name="propertyType">Type of the property.</param>
+    public JPropertyDescriptor(string name, Type propertyType)
+      : base(name, null)
+    {
+      ValidationUtils.ArgumentNotNull(name, "name");
+      ValidationUtils.ArgumentNotNull(propertyType, "propertyType");
+
+      _propertyType = propertyType;
+    }
+
+    private static JObject CastInstance(object instance)
+    {
+      return (JObject)instance;
+    }
+
+    /// <summary>
+    /// When overridden in a derived class, returns whether resetting an object changes its value.
+    /// </summary>
+    /// <returns>
+    /// true if resetting the component changes its value; otherwise, false.
+    /// </returns>
+    /// <param name="component">The component to test for reset capability. 
+    ///                 </param>
+    public override bool CanResetValue(object component)
+    {
+      return false;
+    }
+
+    /// <summary>
+    /// When overridden in a derived class, gets the current value of the property on a component.
+    /// </summary>
+    /// <returns>
+    /// The value of a property for a given component.
+    /// </returns>
+    /// <param name="component">The component with the property for which to retrieve the value. 
+    ///                 </param>
+    public override object GetValue(object component)
+    {
+      JToken token = CastInstance(component)[Name];
+
+      return token;
+    }
+
+    /// <summary>
+    /// When overridden in a derived class, resets the value for this property of the component to the default value.
+    /// </summary>
+    /// <param name="component">The component with the property value that is to be reset to the default value. 
+    ///                 </param>
+    public override void ResetValue(object component)
+    {
+    }
+
+    /// <summary>
+    /// When overridden in a derived class, sets the value of the component to a different value.
+    /// </summary>
+    /// <param name="component">The component with the property value that is to be set. 
+    ///                 </param><param name="value">The new value. 
+    ///                 </param>
+    public override void SetValue(object component, object value)
+    {
+      JToken token = (value is JToken) ? (JToken) value : new JValue(value);
+
+      CastInstance(component)[Name] = token;
+    }
+
+    /// <summary>
+    /// When overridden in a derived class, determines a value indicating whether the value of this property needs to be persisted.
+    /// </summary>
+    /// <returns>
+    /// true if the property should be persisted; otherwise, false.
+    /// </returns>
+    /// <param name="component">The component with the property to be examined for persistence. 
+    ///                 </param>
+    public override bool ShouldSerializeValue(object component)
+    {
+      return false;
+    }
+
+    /// <summary>
+    /// When overridden in a derived class, gets the type of the component this property is bound to.
+    /// </summary>
+    /// <returns>
+    /// A <see cref="T:System.Type"/> that represents the type of component this property is bound to. When the <see cref="M:System.ComponentModel.PropertyDescriptor.GetValue(System.Object)"/> or <see cref="M:System.ComponentModel.PropertyDescriptor.SetValue(System.Object,System.Object)"/> methods are invoked, the object specified might be an instance of this type.
+    /// </returns>
+    public override Type ComponentType
+    {
+      get { return typeof(JObject); }
+    }
+
+    /// <summary>
+    /// When overridden in a derived class, gets a value indicating whether this property is read-only.
+    /// </summary>
+    /// <returns>
+    /// true if the property is read-only; otherwise, false.
+    /// </returns>
+    public override bool IsReadOnly
+    {
+      get { return false; }
+    }
+
+    /// <summary>
+    /// When overridden in a derived class, gets the type of the property.
+    /// </summary>
+    /// <returns>
+    /// A <see cref="T:System.Type"/> that represents the type of the property.
+    /// </returns>
+    public override Type PropertyType
+    {
+      get { return _propertyType; }
+    }
+
+    /// <summary>
+    /// Gets the hash code for the name of the member.
+    /// </summary>
+    /// <value></value>
+    /// <returns>
+    /// The hash code for the name of the member.
+    /// </returns>
+    protected override int NameHashCode
+    {
+      get
+      {
+        // override property to fix up an error in its documentation
+        int nameHashCode = base.NameHashCode;
+        return nameHashCode;
+      }
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JPropertyKeyedCollection.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JPropertyKeyedCollection.cs
new file mode 100644
index 0000000..e0c91cb
--- /dev/null
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JPropertyKeyedCollection.cs
@@ -0,0 +1,222 @@
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+
+namespace Newtonsoft.Json.Linq
+{
+  internal class JPropertyKeyedCollection : Collection<JToken>
+  {
+    private static readonly IEqualityComparer<string> Comparer = StringComparer.Ordinal;
+
+    private Dictionary<string, JToken> _dictionary;
+
+    private void AddKey(string key, JToken item)
+    {
+      EnsureDictionary();
+      _dictionary[key] = item;
+    }
+
+    protected void ChangeItemKey(JToken item, string newKey)
+    {
+      if (!ContainsItem(item))
+        throw new ArgumentException("The specified item does not exist in this KeyedCollection.");
+
+      string keyForItem = GetKeyForItem(item);
+      if (!Comparer.Equals(keyForItem, newKey))
+      {
+        if (newKey != null)
+          AddKey(newKey, item);
+
+        if (keyForItem != null)
+          RemoveKey(keyForItem);
+      }
+    }
+
+    protected override void ClearItems()
+    {
+      base.ClearItems();
+
+      if (_dictionary != null)
+        _dictionary.Clear();
+    }
+
+    public bool Contains(string key)
+    {
+      if (key == null)
+        throw new ArgumentNullException("key");
+
+      if (_dictionary != null)
+        return _dictionary.ContainsKey(key);
+
+      return false;
+    }
+
+    private bool ContainsItem(JToken item)
+    {
+      if (_dictionary == null)
+        return false;
+
+      string key = GetKeyForItem(item);
+      JToken value;
+      return _dictionary.TryGetValue(key, out value);
+    }
+
+    private void EnsureDictionary()
+    {
+      if (_dictionary == null)
+        _dictionary = new Dictionary<string, JToken>(Comparer);
+    }
+
+    private string GetKeyForItem(JToken item)
+    {
+      return ((JProperty)item).Name;
+    }
+
+    protected override void InsertItem(int index, JToken item)
+    {
+      AddKey(GetKeyForItem(item), item);
+      base.InsertItem(index, item);
+    }
+
+    public bool Remove(string key)
+    {
+      if (key == null)
+        throw new ArgumentNullException("key");
+
+      if (_dictionary != null)
+        return _dictionary.ContainsKey(key) && Remove(_dictionary[key]);
+
+      return false;
+    }
+
+    protected override void RemoveItem(int index)
+    {
+      string keyForItem = GetKeyForItem(Items[index]);
+      RemoveKey(keyForItem);
+      base.RemoveItem(index);
+    }
+
+    private void RemoveKey(string key)
+    {
+      if (_dictionary != null)
+        _dictionary.Remove(key);
+    }
+
+    protected override void SetItem(int index, JToken item)
+    {
+      string keyForItem = GetKeyForItem(item);
+      string keyAtIndex = GetKeyForItem(Items[index]);
+
+      if (Comparer.Equals(keyAtIndex, keyForItem))
+      {
+        if (_dictionary != null)
+          _dictionary[keyForItem] = item;
+      }
+      else
+      {
+        AddKey(keyForItem, item);
+
+        if (keyAtIndex != null)
+          RemoveKey(keyAtIndex);
+      }
+      base.SetItem(index, item);
+    }
+
+    public JToken this[string key]
+    {
+      get
+      {
+        if (key == null)
+          throw new ArgumentNullException("key");
+
+        if (_dictionary != null)
+          return _dictionary[key];
+
+        throw new KeyNotFoundException();
+      }
+    }
+
+    public bool TryGetValue(string key, out JToken value)
+    {
+      if (_dictionary == null)
+      {
+        value = null;
+        return false;
+      }
+
+      return _dictionary.TryGetValue(key, out value);
+    }
+
+    public ICollection<string> Keys
+    {
+      get
+      {
+        EnsureDictionary();
+        return _dictionary.Keys;
+      }
+    }
+
+    public ICollection<JToken> Values
+    {
+      get
+      {
+        EnsureDictionary();
+        return _dictionary.Values;
+      }
+    }
+
+    public bool Compare(JPropertyKeyedCollection other)
+    {
+      if (this == other)
+        return true;
+
+      // dictionaries in JavaScript aren't ordered
+      // ignore order when comparing properties
+      Dictionary<string, JToken> d1 = _dictionary;
+      Dictionary<string, JToken> d2 = other._dictionary;
+
+      if (d1.Count != d2.Count)
+        return false;
+
+      foreach (KeyValuePair<string, JToken> keyAndProperty in d1)
+      {
+        JToken secondValue;
+        if (!d2.TryGetValue(keyAndProperty.Key, out secondValue))
+          return false;
+
+        JProperty p1 = (JProperty)keyAndProperty.Value;
+        JProperty p2 = (JProperty)secondValue;
+
+        if (!p1.Value.DeepEquals(p2.Value))
+          return false;
+      }
+
+      return true;
+    }
+  }
+}
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JRaw.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JRaw.cs
index 7e24713..b9c4860 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JRaw.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JRaw.cs
@@ -1,54 +1,75 @@
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Linq;
-using System.Text;
-
-namespace Newtonsoft.Json.Linq
-{
-  /// <summary>
-  /// Represents a raw JSON string.
-  /// </summary>
-  public class JRaw : JValue
-  {
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JRaw"/> class from another <see cref="JRaw"/> object.
-    /// </summary>
-    /// <param name="other">A <see cref="JRaw"/> object to copy from.</param>
-    public JRaw(JRaw other)
-      : base(other)
-    {
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JRaw"/> class.
-    /// </summary>
-    /// <param name="rawJson">The raw json.</param>
-    public JRaw(object rawJson)
-      : base(rawJson, JTokenType.Raw)
-    {
-    }
-
-    /// <summary>
-    /// Creates an instance of <see cref="JRaw"/> with the content of the reader's current token.
-    /// </summary>
-    /// <param name="reader">The reader.</param>
-    /// <returns>An instance of <see cref="JRaw"/> with the content of the reader's current token.</returns>
-    public static JRaw Create(JsonReader reader)
-    {
-      using (StringWriter sw = new StringWriter(CultureInfo.InvariantCulture))
-      using (JsonTextWriter jsonWriter = new JsonTextWriter(sw))
-      {
-        jsonWriter.WriteToken(reader);
-
-        return new JRaw(sw.ToString());
-      }
-    }
-
-    internal override JToken CloneToken()
-    {
-      return new JRaw(this);
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System.Globalization;
+using System.IO;
+
+namespace Newtonsoft.Json.Linq
+{
+  /// <summary>
+  /// Represents a raw JSON string.
+  /// </summary>
+  public class JRaw : JValue
+  {
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JRaw"/> class from another <see cref="JRaw"/> object.
+    /// </summary>
+    /// <param name="other">A <see cref="JRaw"/> object to copy from.</param>
+    public JRaw(JRaw other)
+      : base(other)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JRaw"/> class.
+    /// </summary>
+    /// <param name="rawJson">The raw json.</param>
+    public JRaw(object rawJson)
+      : base(rawJson, JTokenType.Raw)
+    {
+    }
+
+    /// <summary>
+    /// Creates an instance of <see cref="JRaw"/> with the content of the reader's current token.
+    /// </summary>
+    /// <param name="reader">The reader.</param>
+    /// <returns>An instance of <see cref="JRaw"/> with the content of the reader's current token.</returns>
+    public static JRaw Create(JsonReader reader)
+    {
+      using (StringWriter sw = new StringWriter(CultureInfo.InvariantCulture))
+      using (JsonTextWriter jsonWriter = new JsonTextWriter(sw))
+      {
+        jsonWriter.WriteToken(reader);
+
+        return new JRaw(sw.ToString());
+      }
+    }
+
+    internal override JToken CloneToken()
+    {
+      return new JRaw(this);
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JToken.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JToken.cs
index ea88bbc..3ef1554 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JToken.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JToken.cs
@@ -1,1183 +1,1364 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.IO;
-using Newtonsoft.Json.Utilities;
-using System.Diagnostics;
-using System.Globalization;
-using System.Collections;
-using System.ComponentModel;
-
-namespace Newtonsoft.Json.Linq
-{
-  /// <summary>
-  /// Represents an abstract JSON token.
-  /// </summary>
-  public abstract class JToken : IJEnumerable<JToken>, IJsonLineInfo
-  {
-    private JContainer _parent;
-    internal JToken _next;
-    private static JTokenEqualityComparer _equalityComparer;
-
-    private int? _lineNumber;
-    private int? _linePosition;
-
-    /// <summary>
-    /// Gets a comparer that can compare two tokens for value equality.
-    /// </summary>
-    /// <value>A <see cref="JTokenEqualityComparer"/> that can compare two nodes for value equality.</value>
-    public static JTokenEqualityComparer EqualityComparer
-    {
-      get
-      {
-        if (_equalityComparer == null)
-          _equalityComparer = new JTokenEqualityComparer();
-
-        return _equalityComparer;
-      }
-    }
-
-    /// <summary>
-    /// Gets or sets the parent.
-    /// </summary>
-    /// <value>The parent.</value>
-    public JContainer Parent
-    {
-      [DebuggerStepThrough]
-      get { return _parent; }
-      internal set { _parent = value; }
-    }
-
-    /// <summary>
-    /// Gets the root <see cref="JToken"/> of this <see cref="JToken"/>.
-    /// </summary>
-    /// <value>The root <see cref="JToken"/> of this <see cref="JToken"/>.</value>
-    public JToken Root
-    {
-      get
-      {
-        JContainer parent = Parent;
-        if (parent == null)
-          return this;
-
-        while (parent.Parent != null)
-        {
-          parent = parent.Parent;
-        }
-
-        return parent;
-      }
-    }
-
-    internal abstract JToken CloneToken();
-    internal abstract bool DeepEquals(JToken node);
-
-    /// <summary>
-    /// Gets the node type for this <see cref="JToken"/>.
-    /// </summary>
-    /// <value>The type.</value>
-    public abstract JTokenType Type { get; }
-
-    /// <summary>
-    /// Gets a value indicating whether this token has childen tokens.
-    /// </summary>
-    /// <value>
-    /// 	<c>true</c> if this token has child values; otherwise, <c>false</c>.
-    /// </value>
-    public abstract bool HasValues { get; }
-
-    /// <summary>
-    /// Compares the values of two tokens, including the values of all descendant tokens.
-    /// </summary>
-    /// <param name="t1">The first <see cref="JToken"/> to compare.</param>
-    /// <param name="t2">The second <see cref="JToken"/> to compare.</param>
-    /// <returns>true if the tokens are equal; otherwise false.</returns>
-    public static bool DeepEquals(JToken t1, JToken t2)
-    {
-      return (t1 == t2 || (t1 != null && t2 != null && t1.DeepEquals(t2)));
-    }
-
-    /// <summary>
-    /// Gets the next sibling token of this node.
-    /// </summary>
-    /// <value>The <see cref="JToken"/> that contains the next sibling token.</value>
-    public JToken Next
-    {
-      get
-      {
-        if (_parent != null && _next != _parent.First)
-          return _next;
-
-        return null;
-      }
-      internal set { _next = value; }
-    }
-
-    /// <summary>
-    /// Gets the previous sibling token of this node.
-    /// </summary>
-    /// <value>The <see cref="JToken"/> that contains the previous sibling token.</value>
-    public JToken Previous
-    {
-      get
-      {
-        if (_parent == null)
-          return null;
-
-        JToken parentNext = _parent.Content._next;
-        JToken parentNextBefore = null;
-        while (parentNext != this)
-        {
-          parentNextBefore = parentNext;
-          parentNext = parentNext.Next;
-        }
-        return parentNextBefore;
-      }
-    }
-
-    internal JToken()
-    {
-    }
-
-    /// <summary>
-    /// Adds the specified content immediately after this token.
-    /// </summary>
-    /// <param name="content">A content object that contains simple content or a collection of content objects to be added after this token.</param>
-    public void AddAfterSelf(object content)
-    {
-      if (_parent == null)
-        throw new InvalidOperationException("The parent is missing.");
-
-      _parent.AddInternal((Next == null), this, content);
-    }
-
-    /// <summary>
-    /// Adds the specified content immediately before this token.
-    /// </summary>
-    /// <param name="content">A content object that contains simple content or a collection of content objects to be added before this token.</param>
-    public void AddBeforeSelf(object content)
-    {
-      if (_parent == null)
-        throw new InvalidOperationException("The parent is missing.");
-
-      JToken previous = Previous;
-      if (previous == null)
-        previous = _parent.Last;
-
-      _parent.AddInternal(false, previous, content);
-    }
-
-    /// <summary>
-    /// Returns a collection of the ancestor tokens of this token.
-    /// </summary>
-    /// <returns>A collection of the ancestor tokens of this token.</returns>
-    public IEnumerable<JToken> Ancestors()
-    {
-      for (JToken parent = Parent; parent != null; parent = parent.Parent)
-      {
-        yield return parent;
-      }
-    }
-
-    /// <summary>
-    /// Returns a collection of the sibling tokens after this token, in document order.
-    /// </summary>
-    /// <returns>A collection of the sibling tokens after this tokens, in document order.</returns>
-    public IEnumerable<JToken> AfterSelf()
-    {
-      if (Parent == null)
-        yield break;
-
-      for (JToken o = Next; o != null; o = o.Next)
-        yield return o;
-    }
-
-    /// <summary>
-    /// Returns a collection of the sibling tokens before this token, in document order.
-    /// </summary>
-    /// <returns>A collection of the sibling tokens before this token, in document order.</returns>
-    public IEnumerable<JToken> BeforeSelf()
-    {
-      for (JToken o = Parent.First; o != this; o = o.Next)
-        yield return o;
-    }
-
-    /// <summary>
-    /// Gets the <see cref="JToken"/> with the specified key.
-    /// </summary>
-    /// <value>The <see cref="JToken"/> with the specified key.</value>
-    public virtual JToken this[object key]
-    {
-      get { throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); }
-      set { throw new InvalidOperationException("Cannot set child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); }
-    }
-
-    /// <summary>
-    /// Gets the <see cref="JToken"/> with the specified key converted to the specified type.
-    /// </summary>
-    /// <typeparam name="T">The type to convert the token to.</typeparam>
-    /// <param name="key">The token key.</param>
-    /// <returns>The converted token value.</returns>
-    public virtual T Value<T>(object key)
-    {
-      JToken token = this[key];
-
-      return Extensions.Convert<JToken, T>(token);
-    }
-
-    /// <summary>
-    /// Get the first child token of this token.
-    /// </summary>
-    /// <value>A <see cref="JToken"/> containing the first child token of the <see cref="JToken"/>.</value>
-    public virtual JToken First
-    {
-      get { throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); }
-    }
-
-    /// <summary>
-    /// Get the last child token of this token.
-    /// </summary>
-    /// <value>A <see cref="JToken"/> containing the last child token of the <see cref="JToken"/>.</value>
-    public virtual JToken Last
-    {
-      get { throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); }
-    }
-
-    /// <summary>
-    /// Returns a collection of the child tokens of this token, in document order.
-    /// </summary>
-    /// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> containing the child tokens of this <see cref="JToken"/>, in document order.</returns>
-    public virtual JEnumerable<JToken> Children()
-    {
-      throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType()));
-    }
-
-    /// <summary>
-    /// Returns a collection of the child tokens of this token, in document order, filtered by the specified type.
-    /// </summary>
-    /// <typeparam name="T">The type to filter the child tokens on.</typeparam>
-    /// <returns>A <see cref="JEnumerable{T}"/> containing the child tokens of this <see cref="JToken"/>, in document order.</returns>
-    public JEnumerable<T> Children<T>() where T : JToken
-    {
-      return new JEnumerable<T>(Children().OfType<T>());
-    }
-
-    /// <summary>
-    /// Returns a collection of the child values of this token, in document order.
-    /// </summary>
-    /// <typeparam name="T">The type to convert the values to.</typeparam>
-    /// <returns>A <see cref="IEnumerable{T}"/> containing the child values of this <see cref="JToken"/>, in document order.</returns>
-    public virtual IEnumerable<T> Values<T>()
-    {
-      throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType()));
-    }
-
-    /// <summary>
-    /// Removes this token from its parent.
-    /// </summary>
-    public void Remove()
-    {
-      if (_parent == null)
-        throw new InvalidOperationException("The parent is missing.");
-
-      _parent.RemoveItem(this);
-    }
-
-    /// <summary>
-    /// Replaces this token with the specified token.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    public void Replace(JToken value)
-    {
-      if (_parent == null)
-        throw new InvalidOperationException("The parent is missing.");
-
-      _parent.ReplaceItem(this, value);
-    }
-
-    /// <summary>
-    /// Writes this token to a <see cref="JsonWriter"/>.
-    /// </summary>
-    /// <param name="writer">A <see cref="JsonWriter"/> into which this method will write.</param>
-    /// <param name="converters">A collection of <see cref="JsonConverter"/> which will be used when writing the token.</param>
-    public abstract void WriteTo(JsonWriter writer, params JsonConverter[] converters);
-
-    /// <summary>
-    /// Returns the indented JSON for this token.
-    /// </summary>
-    /// <returns>
-    /// The indented JSON for this token.
-    /// </returns>
-    public override string ToString()
-    {
-      return ToString(Formatting.Indented);
-    }
-
-    /// <summary>
-    /// Returns the JSON for this token using the given formatting and converters.
-    /// </summary>
-    /// <param name="formatting">Indicates how the output is formatted.</param>
-    /// <param name="converters">A collection of <see cref="JsonConverter"/> which will be used when writing the token.</param>
-    /// <returns>The JSON for this token using the given formatting and converters.</returns>
-    public string ToString(Formatting formatting, params JsonConverter[] converters)
-    {
-      using (StringWriter sw = new StringWriter(CultureInfo.InvariantCulture))
-      {
-        JsonTextWriter jw = new JsonTextWriter(sw);
-        jw.Formatting = formatting;
-
-        WriteTo(jw, converters);
-
-        return sw.ToString();
-      }
-    }
-
-    private static JValue EnsureValue(JToken value)
-    {
-      if (value == null)
-        throw new ArgumentNullException("value");
-
-      if (value is JProperty)
-        value = ((JProperty)value).Value;
-
-      JValue v = value as JValue;
-
-      return v;
-    }
-
-    private static string GetType(JToken token)
-    {
-      ValidationUtils.ArgumentNotNull(token, "token");
-
-      if (token is JProperty)
-        token = ((JProperty)token).Value;
-
-      return token.Type.ToString();
-    }
-
-    private static bool IsNullable(JToken o)
-    {
-      return (o.Type == JTokenType.Undefined || o.Type == JTokenType.Null);
-    }
-
-    private static bool ValidateFloat(JToken o, bool nullable)
-    {
-      return (o.Type == JTokenType.Float || o.Type == JTokenType.Integer || (nullable && IsNullable(o)));
-    }
-
-    private static bool ValidateInteger(JToken o, bool nullable)
-    {
-      return (o.Type == JTokenType.Integer || (nullable && IsNullable(o)));
-    }
-
-    private static bool ValidateDate(JToken o, bool nullable)
-    {
-      return (o.Type == JTokenType.Date || (nullable && IsNullable(o)));
-    }
-
-    private static bool ValidateBoolean(JToken o, bool nullable)
-    {
-      return (o.Type == JTokenType.Boolean || (nullable && IsNullable(o)));
-    }
-
-    private static bool ValidateString(JToken o)
-    {
-      return (o.Type == JTokenType.String || o.Type == JTokenType.Comment || o.Type == JTokenType.Raw || IsNullable(o));
-    }
-
-    private static bool ValidateBytes(JToken o)
-    {
-      return (o.Type == JTokenType.Bytes || IsNullable(o));
-    }
-
-    #region Cast from operators
-    /// <summary>
-    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Boolean"/>.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    /// <returns>The result of the conversion.</returns>
-    public static explicit operator bool(JToken value)
-    {
-      JValue v = EnsureValue(value);
-      if (v == null || !ValidateBoolean(v, false))
-        throw new ArgumentException("Can not convert {0} to Boolean.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
-
-      return (bool)v.Value;
-    }
-
-#if !PocketPC && !NET20
-    /// <summary>
-    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.DateTimeOffset"/>.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    /// <returns>The result of the conversion.</returns>
-    public static explicit operator DateTimeOffset(JToken value)
-    {
-      JValue v = EnsureValue(value);
-      if (v == null || !ValidateDate(v, false))
-        throw new ArgumentException("Can not convert {0} to DateTimeOffset.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
-
-      return (DateTimeOffset)v.Value;
-    }
-#endif
-
-    /// <summary>
-    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Boolean}"/>.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    /// <returns>The result of the conversion.</returns>
-    public static explicit operator bool?(JToken value)
-    {
-      if (value == null)
-        return null;
-
-      JValue v = EnsureValue(value);
-      if (v == null || !ValidateBoolean(v, true))
-        throw new ArgumentException("Can not convert {0} to Boolean.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
-
-      return (bool?)v.Value;
-    }
-
-    /// <summary>
-    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Int64"/>.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    /// <returns>The result of the conversion.</returns>
-    public static explicit operator long(JToken value)
-    {
-      JValue v = EnsureValue(value);
-      if (v == null || !ValidateInteger(v, false))
-        throw new ArgumentException("Can not convert {0} to Int64.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
-
-      return (long)v.Value;
-    }
-
-    /// <summary>
-    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{DateTime}"/>.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    /// <returns>The result of the conversion.</returns>
-    public static explicit operator DateTime?(JToken value)
-    {
-      if (value == null)
-        return null;
-
-      JValue v = EnsureValue(value);
-      if (v == null || !ValidateDate(v, true))
-        throw new ArgumentException("Can not convert {0} to DateTime.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
-
-      return (DateTime?)v.Value;
-    }
-
-#if !PocketPC && !NET20
-    /// <summary>
-    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{DateTimeOffset}"/>.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    /// <returns>The result of the conversion.</returns>
-    public static explicit operator DateTimeOffset?(JToken value)
-    {
-      if (value == null)
-        return null;
-
-      JValue v = EnsureValue(value);
-      if (v == null || !ValidateDate(v, true))
-        throw new ArgumentException("Can not convert {0} to DateTimeOffset.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
-
-      return (DateTimeOffset?)v.Value;
-    }
-#endif
-
-    /// <summary>
-    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Decimal}"/>.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    /// <returns>The result of the conversion.</returns>
-    public static explicit operator decimal?(JToken value)
-    {
-      if (value == null)
-        return null;
-
-      JValue v = EnsureValue(value);
-      if (v == null || !ValidateFloat(v, true))
-        throw new ArgumentException("Can not convert {0} to Decimal.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
-
-      return (v.Value != null) ? (decimal?)Convert.ToDecimal(v.Value, CultureInfo.InvariantCulture) : null;
-    }
-
-    /// <summary>
-    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Double}"/>.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    /// <returns>The result of the conversion.</returns>
-    public static explicit operator double?(JToken value)
-    {
-      if (value == null)
-        return null;
-
-      JValue v = EnsureValue(value);
-      if (v == null || !ValidateFloat(v, true))
-        throw new ArgumentException("Can not convert {0} to Double.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
-
-      return (double?)v.Value;
-    }
-
-    /// <summary>
-    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Int32"/>.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    /// <returns>The result of the conversion.</returns>
-    public static explicit operator int(JToken value)
-    {
-      JValue v = EnsureValue(value);
-      if (v == null || !ValidateInteger(v, false))
-        throw new ArgumentException("Can not convert {0} to Int32.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
-
-      return Convert.ToInt32(v.Value, CultureInfo.InvariantCulture);
-    }
-
-    /// <summary>
-    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Int32}"/>.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    /// <returns>The result of the conversion.</returns>
-    public static explicit operator int?(JToken value)
-    {
-      if (value == null)
-        return null;
-
-      JValue v = EnsureValue(value);
-      if (v == null || !ValidateInteger(v, true))
-        throw new ArgumentException("Can not convert {0} to Int32.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
-
-      return (v.Value != null) ? (int?)Convert.ToInt32(v.Value, CultureInfo.InvariantCulture) : null;
-    }
-
-    /// <summary>
-    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.DateTime"/>.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    /// <returns>The result of the conversion.</returns>
-    public static explicit operator DateTime(JToken value)
-    {
-      JValue v = EnsureValue(value);
-      if (v == null || !ValidateDate(v, false))
-        throw new ArgumentException("Can not convert {0} to DateTime.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
-
-      return (DateTime)v.Value;
-    }
-
-    /// <summary>
-    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Int64}"/>.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    /// <returns>The result of the conversion.</returns>
-    public static explicit operator long?(JToken value)
-    {
-      if (value == null)
-        return null;
-
-      JValue v = EnsureValue(value);
-      if (v == null || !ValidateInteger(v, true))
-        throw new ArgumentException("Can not convert {0} to Int64.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
-
-      return (long?)v.Value;
-    }
-
-    /// <summary>
-    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Single}"/>.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    /// <returns>The result of the conversion.</returns>
-    public static explicit operator float?(JToken value)
-    {
-      if (value == null)
-        return null;
-
-      JValue v = EnsureValue(value);
-      if (v == null || !ValidateFloat(v, true))
-        throw new ArgumentException("Can not convert {0} to Single.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
-
-      return (v.Value != null) ? (float?)Convert.ToSingle(v.Value, CultureInfo.InvariantCulture) : null;
-    }
-
-    /// <summary>
-    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Decimal"/>.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    /// <returns>The result of the conversion.</returns>
-    public static explicit operator decimal(JToken value)
-    {
-      JValue v = EnsureValue(value);
-      if (v == null || !ValidateFloat(v, false))
-        throw new ArgumentException("Can not convert {0} to Decimal.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
-
-      return Convert.ToDecimal(v.Value, CultureInfo.InvariantCulture);
-    }
-
-    /// <summary>
-    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{UInt32}"/>.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    /// <returns>The result of the conversion.</returns>
-    [CLSCompliant(false)]
-    public static explicit operator uint?(JToken value)
-    {
-      if (value == null)
-        return null;
-
-      JValue v = EnsureValue(value);
-      if (v == null || !ValidateInteger(v, true))
-        throw new ArgumentException("Can not convert {0} to UInt32.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
-
-      return (uint?)v.Value;
-    }
-
-    /// <summary>
-    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{UInt64}"/>.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    /// <returns>The result of the conversion.</returns>
-    [CLSCompliant(false)]
-    public static explicit operator ulong?(JToken value)
-    {
-      if (value == null)
-        return null;
-
-      JValue v = EnsureValue(value);
-      if (v == null || !ValidateInteger(v, true))
-        throw new ArgumentException("Can not convert {0} to UInt64.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
-
-      return (ulong?)v.Value;
-    }
-
-    /// <summary>
-    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Double"/>.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    /// <returns>The result of the conversion.</returns>
-    public static explicit operator double(JToken value)
-    {
-      JValue v = EnsureValue(value);
-      if (v == null || !ValidateFloat(v, false))
-        throw new ArgumentException("Can not convert {0} to Double.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
-
-      return (double)v.Value;
-    }
-
-    /// <summary>
-    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Single"/>.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    /// <returns>The result of the conversion.</returns>
-    public static explicit operator float(JToken value)
-    {
-      JValue v = EnsureValue(value);
-      if (v == null || !ValidateFloat(v, false))
-        throw new ArgumentException("Can not convert {0} to Single.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
-
-      return Convert.ToSingle(v.Value, CultureInfo.InvariantCulture);
-    }
-
-    /// <summary>
-    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.String"/>.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    /// <returns>The result of the conversion.</returns>
-    public static explicit operator string(JToken value)
-    {
-      if (value == null)
-        return null;
-
-      JValue v = EnsureValue(value);
-      if (v == null || !ValidateString(v))
-        throw new ArgumentException("Can not convert {0} to String.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
-
-      return (string)v.Value;
-    }
-
-    /// <summary>
-    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.UInt32"/>.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    /// <returns>The result of the conversion.</returns>
-    [CLSCompliant(false)]
-    public static explicit operator uint(JToken value)
-    {
-      JValue v = EnsureValue(value);
-      if (v == null || !ValidateInteger(v, false))
-        throw new ArgumentException("Can not convert {0} to UInt32.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
-
-      return Convert.ToUInt32(v.Value, CultureInfo.InvariantCulture);
-    }
-
-    /// <summary>
-    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.UInt64"/>.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    /// <returns>The result of the conversion.</returns>
-    [CLSCompliant(false)]
-    public static explicit operator ulong(JToken value)
-    {
-      JValue v = EnsureValue(value);
-      if (v == null || !ValidateInteger(v, false))
-        throw new ArgumentException("Can not convert {0} to UInt64.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
-
-      return Convert.ToUInt64(v.Value, CultureInfo.InvariantCulture);
-    }
-
-    /// <summary>
-    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="T:System.Byte[]"/>.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    /// <returns>The result of the conversion.</returns>
-    public static explicit operator byte[](JToken value)
-    {
-      JValue v = EnsureValue(value);
-      if (v == null || !ValidateBytes(v))
-        throw new ArgumentException("Can not convert {0} to byte array.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
-
-      return (byte[])v.Value;
-    }
-    #endregion
-
-    #region Cast to operators
-    /// <summary>
-    /// Performs an implicit conversion from <see cref="Boolean"/> to <see cref="JToken"/>.
-    /// </summary>
-    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
-    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
-    public static implicit operator JToken(bool value)
-    {
-      return new JValue(value);
-    }
-
-#if !PocketPC && !NET20
-    /// <summary>
-    /// Performs an implicit conversion from <see cref="DateTimeOffset"/> to <see cref="JToken"/>.
-    /// </summary>
-    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
-    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
-    public static implicit operator JToken(DateTimeOffset value)
-    {
-      return new JValue(value);
-    }
-#endif
-
-    /// <summary>
-    /// Performs an implicit conversion from <see cref="Nullable{Boolean}"/> to <see cref="JToken"/>.
-    /// </summary>
-    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
-    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
-    public static implicit operator JToken(bool? value)
-    {
-      return new JValue(value);
-    }
-
-    /// <summary>
-    /// Performs an implicit conversion from <see cref="Nullable{Int64}"/> to <see cref="JToken"/>.
-    /// </summary>
-    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
-    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
-    public static implicit operator JToken(long value)
-    {
-      return new JValue(value);
-    }
-
-    /// <summary>
-    /// Performs an implicit conversion from <see cref="Nullable{DateTime}"/> to <see cref="JToken"/>.
-    /// </summary>
-    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
-    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
-    public static implicit operator JToken(DateTime? value)
-    {
-      return new JValue(value);
-    }
-
-#if !PocketPC && !NET20
-    /// <summary>
-    /// Performs an implicit conversion from <see cref="Nullable{DateTimeOffset}"/> to <see cref="JToken"/>.
-    /// </summary>
-    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
-    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
-    public static implicit operator JToken(DateTimeOffset? value)
-    {
-      return new JValue(value);
-    }
-#endif
-
-    /// <summary>
-    /// Performs an implicit conversion from <see cref="Nullable{Decimal}"/> to <see cref="JToken"/>.
-    /// </summary>
-    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
-    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
-    public static implicit operator JToken(decimal? value)
-    {
-      return new JValue(value);
-    }
-
-    /// <summary>
-    /// Performs an implicit conversion from <see cref="Nullable{Double}"/> to <see cref="JToken"/>.
-    /// </summary>
-    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
-    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
-    public static implicit operator JToken(double? value)
-    {
-      return new JValue(value);
-    }
-
-    /// <summary>
-    /// Performs an implicit conversion from <see cref="UInt16"/> to <see cref="JToken"/>.
-    /// </summary>
-    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
-    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
-    [CLSCompliant(false)]
-    public static implicit operator JToken(ushort value)
-    {
-      return new JValue(value);
-    }
-
-    /// <summary>
-    /// Performs an implicit conversion from <see cref="Int32"/> to <see cref="JToken"/>.
-    /// </summary>
-    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
-    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
-    public static implicit operator JToken(int value)
-    {
-      return new JValue(value);
-    }
-
-    /// <summary>
-    /// Performs an implicit conversion from <see cref="Nullable{Int32}"/> to <see cref="JToken"/>.
-    /// </summary>
-    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
-    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
-    public static implicit operator JToken(int? value)
-    {
-      return new JValue(value);
-    }
-
-    /// <summary>
-    /// Performs an implicit conversion from <see cref="DateTime"/> to <see cref="JToken"/>.
-    /// </summary>
-    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
-    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
-    public static implicit operator JToken(DateTime value)
-    {
-      return new JValue(value);
-    }
-
-    /// <summary>
-    /// Performs an implicit conversion from <see cref="Nullable{Int64}"/> to <see cref="JToken"/>.
-    /// </summary>
-    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
-    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
-    public static implicit operator JToken(long? value)
-    {
-      return new JValue(value);
-    }
-
-    /// <summary>
-    /// Performs an implicit conversion from <see cref="Nullable{Single}"/> to <see cref="JToken"/>.
-    /// </summary>
-    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
-    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
-    public static implicit operator JToken(float? value)
-    {
-      return new JValue(value);
-    }
-
-    /// <summary>
-    /// Performs an implicit conversion from <see cref="Decimal"/> to <see cref="JToken"/>.
-    /// </summary>
-    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
-    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
-    public static implicit operator JToken(decimal value)
-    {
-      return new JValue(value);
-    }
-
-    /// <summary>
-    /// Performs an implicit conversion from <see cref="Nullable{UInt16}"/> to <see cref="JToken"/>.
-    /// </summary>
-    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
-    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
-    [CLSCompliant(false)]
-    public static implicit operator JToken(ushort? value)
-    {
-      return new JValue(value);
-    }
-
-    /// <summary>
-    /// Performs an implicit conversion from <see cref="Nullable{UInt32}"/> to <see cref="JToken"/>.
-    /// </summary>
-    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
-    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
-    [CLSCompliant(false)]
-    public static implicit operator JToken(uint? value)
-    {
-      return new JValue(value);
-    }
-
-    /// <summary>
-    /// Performs an implicit conversion from <see cref="Nullable{UInt64}"/> to <see cref="JToken"/>.
-    /// </summary>
-    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
-    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
-    [CLSCompliant(false)]
-    public static implicit operator JToken(ulong? value)
-    {
-      return new JValue(value);
-    }
-
-    /// <summary>
-    /// Performs an implicit conversion from <see cref="Double"/> to <see cref="JToken"/>.
-    /// </summary>
-    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
-    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
-    public static implicit operator JToken(double value)
-    {
-      return new JValue(value);
-    }
-
-    /// <summary>
-    /// Performs an implicit conversion from <see cref="Single"/> to <see cref="JToken"/>.
-    /// </summary>
-    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
-    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
-    public static implicit operator JToken(float value)
-    {
-      return new JValue(value);
-    }
-
-    /// <summary>
-    /// Performs an implicit conversion from <see cref="String"/> to <see cref="JToken"/>.
-    /// </summary>
-    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
-    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
-    public static implicit operator JToken(string value)
-    {
-      return new JValue(value);
-    }
-
-    /// <summary>
-    /// Performs an implicit conversion from <see cref="UInt32"/> to <see cref="JToken"/>.
-    /// </summary>
-    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
-    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
-    [CLSCompliant(false)]
-    public static implicit operator JToken(uint value)
-    {
-      return new JValue(value);
-    }
-
-    /// <summary>
-    /// Performs an implicit conversion from <see cref="UInt64"/> to <see cref="JToken"/>.
-    /// </summary>
-    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
-    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
-    [CLSCompliant(false)]
-    public static implicit operator JToken(ulong value)
-    {
-      return new JValue(value);
-    }
-
-    /// <summary>
-    /// Performs an implicit conversion from <see cref="T:System.Byte[]"/> to <see cref="Newtonsoft.Json.Linq.JToken"/>.
-    /// </summary>
-    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
-    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
-    public static implicit operator JToken(byte[] value)
-    {
-      return new JValue(value);
-    }
-    #endregion
-
-    IEnumerator IEnumerable.GetEnumerator()
-    {
-      return ((IEnumerable<JToken>)this).GetEnumerator();
-    }
-
-    IEnumerator<JToken> IEnumerable<JToken>.GetEnumerator()
-    {
-      return Children().GetEnumerator();
-    }
-
-    internal abstract int GetDeepHashCode();
-
-    IJEnumerable<JToken> IJEnumerable<JToken>.this[object key]
-    {
-      get { return this[key]; }
-    }
-
-    /// <summary>
-    /// Creates an <see cref="JsonReader"/> for this token.
-    /// </summary>
-    /// <returns>An <see cref="JsonReader"/> that can be used to read this token and its descendants.</returns>
-    public JsonReader CreateReader()
-    {
-      return new JTokenReader(this);
-    }
-
-    internal static JToken FromObjectInternal(object o, JsonSerializer jsonSerializer)
-    {
-      ValidationUtils.ArgumentNotNull(o, "o");
-      ValidationUtils.ArgumentNotNull(jsonSerializer, "jsonSerializer");
-
-      JToken token;
-      using (JTokenWriter jsonWriter = new JTokenWriter())
-      {
-        jsonSerializer.Serialize(jsonWriter, o);
-        token = jsonWriter.Token;
-      }
-
-      return token;
-    }
-
-    /// <summary>
-    /// Creates a <see cref="JToken"/> from an object.
-    /// </summary>
-    /// <param name="o">The object that will be used to create <see cref="JToken"/>.</param>
-    /// <returns>A <see cref="JToken"/> with the value of the specified object</returns>
-    public static JToken FromObject(object o)
-    {
-      return FromObjectInternal(o, new JsonSerializer());
-    }
-
-    /// <summary>
-    /// Creates a <see cref="JToken"/> from an object using the specified <see cref="JsonSerializer"/>.
-    /// </summary>
-    /// <param name="o">The object that will be used to create <see cref="JToken"/>.</param>
-    /// <param name="jsonSerializer">The <see cref="JsonSerializer"/> that will be used when reading the object.</param>
-    /// <returns>A <see cref="JToken"/> with the value of the specified object</returns>
-    public static JToken FromObject(object o, JsonSerializer jsonSerializer)
-    {
-      return FromObjectInternal(o, jsonSerializer);
-    }
-
-    /// <summary>
-    /// Creates a <see cref="JToken"/> from a <see cref="JsonReader"/>.
-    /// </summary>
-    /// <param name="reader">An <see cref="JsonReader"/> positioned at the token to read into this <see cref="JToken"/>.</param>
-    /// <returns>
-    /// An <see cref="JToken"/> that contains the token and its descendant tokens
-    /// that were read from the reader. The runtime type of the token is determined
-    /// by the token type of the first token encountered in the reader.
-    /// </returns>
-    public static JToken ReadFrom(JsonReader reader)
-    {
-      ValidationUtils.ArgumentNotNull(reader, "reader");
-
-      if (reader.TokenType == JsonToken.None)
-      {
-        if (!reader.Read())
-          throw new Exception("Error reading JToken from JsonReader.");
-      }
-
-      if (reader.TokenType == JsonToken.StartObject)
-        return JObject.Load(reader);
-
-      if (reader.TokenType == JsonToken.StartArray)
-        return JArray.Load(reader);
-
-      if (reader.TokenType == JsonToken.PropertyName)
-        return JProperty.Load(reader);
-
-      if (reader.TokenType == JsonToken.StartConstructor)
-        return JConstructor.Load(reader);
-
-      // hack. change to look at TokenType rather than using value
-      if (!JsonReader.IsStartToken(reader.TokenType))
-        return new JValue(reader.Value);
-
-      // TODO: loading constructor and parameters?
-      throw new Exception("Error reading JToken from JsonReader. Unexpected token: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
-    }
-
-    internal void SetLineInfo(IJsonLineInfo lineInfo)
-    {
-      if (lineInfo == null || !lineInfo.HasLineInfo())
-        return;
-
-      SetLineInfo(lineInfo.LineNumber, lineInfo.LinePosition);
-    }
-
-    internal void SetLineInfo(int lineNumber, int linePosition)
-    {
-      _lineNumber = lineNumber;
-      _linePosition = linePosition;
-    }
-
-    bool IJsonLineInfo.HasLineInfo()
-    {
-      return (_lineNumber != null && _linePosition != null);
-    }
-
-    int IJsonLineInfo.LineNumber
-    {
-      get { return _lineNumber ?? 0; }
-    }
-
-    int IJsonLineInfo.LinePosition
-    {
-      get { return _linePosition ?? 0; }
-    }
-
-    /// <summary>
-    /// Selects the token that matches the object path.
-    /// </summary>
-    /// <param name="path">
-    /// The object path from the current <see cref="JToken"/> to the <see cref="JToken"/>
-    /// to be returned. This must be a string of property names or array indexes separated
-    /// by periods, such as <code>Tables[0].DefaultView[0].Price</code> in C# or
-    /// <code>Tables(0).DefaultView(0).Price</code> in Visual Basic.
-    /// </param>
-    /// <returns>The <see cref="JToken"/> that matches the object path or a null reference if no matching token is found.</returns>
-    public JToken SelectToken(string path)
-    {
-      return SelectToken(path, false);
-    }
-
-    /// <summary>
-    /// Selects the token that matches the object path.
-    /// </summary>
-    /// <param name="path">
-    /// The object path from the current <see cref="JToken"/> to the <see cref="JToken"/>
-    /// to be returned. This must be a string of property names or array indexes separated
-    /// by periods, such as <code>Tables[0].DefaultView[0].Price</code> in C# or
-    /// <code>Tables(0).DefaultView(0).Price</code> in Visual Basic.
-    /// </param>
-    /// <param name="errorWhenNoMatch">A flag to indicate whether an error should be thrown if no token is found.</param>
-    /// <returns>The <see cref="JToken"/> that matches the object path.</returns>
-    public JToken SelectToken(string path, bool errorWhenNoMatch)
-    {
-      JPath p = new JPath(path);
-      return p.Evaluate(this, errorWhenNoMatch);
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
+using System.Dynamic;
+using System.Linq.Expressions;
+#endif
+using System.IO;
+using Newtonsoft.Json.Utilities;
+using System.Diagnostics;
+using System.Globalization;
+using System.Collections;
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#else
+using System.Linq;
+#endif
+
+namespace Newtonsoft.Json.Linq
+{
+  /// <summary>
+  /// Represents an abstract JSON token.
+  /// </summary>
+  public abstract class JToken : IJEnumerable<JToken>, IJsonLineInfo
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+, ICloneable
+#endif
+#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
+, IDynamicMetaObjectProvider
+#endif
+  {
+    private JContainer _parent;
+    private JToken _previous;
+    private JToken _next;
+    private static JTokenEqualityComparer _equalityComparer;
+
+    private int? _lineNumber;
+    private int? _linePosition;
+
+    /// <summary>
+    /// Gets a comparer that can compare two tokens for value equality.
+    /// </summary>
+    /// <value>A <see cref="JTokenEqualityComparer"/> that can compare two nodes for value equality.</value>
+    public static JTokenEqualityComparer EqualityComparer
+    {
+      get
+      {
+        if (_equalityComparer == null)
+          _equalityComparer = new JTokenEqualityComparer();
+
+        return _equalityComparer;
+      }
+    }
+
+    /// <summary>
+    /// Gets or sets the parent.
+    /// </summary>
+    /// <value>The parent.</value>
+    public JContainer Parent
+    {
+      [DebuggerStepThrough]
+      get { return _parent; }
+      internal set { _parent = value; }
+    }
+
+    /// <summary>
+    /// Gets the root <see cref="JToken"/> of this <see cref="JToken"/>.
+    /// </summary>
+    /// <value>The root <see cref="JToken"/> of this <see cref="JToken"/>.</value>
+    public JToken Root
+    {
+      get
+      {
+        JContainer parent = Parent;
+        if (parent == null)
+          return this;
+
+        while (parent.Parent != null)
+        {
+          parent = parent.Parent;
+        }
+
+        return parent;
+      }
+    }
+
+    internal abstract JToken CloneToken();
+    internal abstract bool DeepEquals(JToken node);
+
+    /// <summary>
+    /// Gets the node type for this <see cref="JToken"/>.
+    /// </summary>
+    /// <value>The type.</value>
+    public abstract JTokenType Type { get; }
+
+    /// <summary>
+    /// Gets a value indicating whether this token has childen tokens.
+    /// </summary>
+    /// <value>
+    /// 	<c>true</c> if this token has child values; otherwise, <c>false</c>.
+    /// </value>
+    public abstract bool HasValues { get; }
+
+    /// <summary>
+    /// Compares the values of two tokens, including the values of all descendant tokens.
+    /// </summary>
+    /// <param name="t1">The first <see cref="JToken"/> to compare.</param>
+    /// <param name="t2">The second <see cref="JToken"/> to compare.</param>
+    /// <returns>true if the tokens are equal; otherwise false.</returns>
+    public static bool DeepEquals(JToken t1, JToken t2)
+    {
+      return (t1 == t2 || (t1 != null && t2 != null && t1.DeepEquals(t2)));
+    }
+
+    /// <summary>
+    /// Gets the next sibling token of this node.
+    /// </summary>
+    /// <value>The <see cref="JToken"/> that contains the next sibling token.</value>
+    public JToken Next
+    {
+      get { return _next; }
+      internal set { _next = value; }
+    }
+
+    /// <summary>
+    /// Gets the previous sibling token of this node.
+    /// </summary>
+    /// <value>The <see cref="JToken"/> that contains the previous sibling token.</value>
+    public JToken Previous
+    {
+      get { return _previous; }
+      internal set { _previous = value; }
+    }
+
+    internal JToken()
+    {
+    }
+
+    /// <summary>
+    /// Adds the specified content immediately after this token.
+    /// </summary>
+    /// <param name="content">A content object that contains simple content or a collection of content objects to be added after this token.</param>
+    public void AddAfterSelf(object content)
+    {
+      if (_parent == null)
+        throw new InvalidOperationException("The parent is missing.");
+
+      int index = _parent.IndexOfItem(this);
+      _parent.AddInternal(index + 1, content, false);
+    }
+
+    /// <summary>
+    /// Adds the specified content immediately before this token.
+    /// </summary>
+    /// <param name="content">A content object that contains simple content or a collection of content objects to be added before this token.</param>
+    public void AddBeforeSelf(object content)
+    {
+      if (_parent == null)
+        throw new InvalidOperationException("The parent is missing.");
+
+      int index = _parent.IndexOfItem(this);
+      _parent.AddInternal(index, content, false);
+    }
+
+    /// <summary>
+    /// Returns a collection of the ancestor tokens of this token.
+    /// </summary>
+    /// <returns>A collection of the ancestor tokens of this token.</returns>
+    public IEnumerable<JToken> Ancestors()
+    {
+      for (JToken parent = Parent; parent != null; parent = parent.Parent)
+      {
+        yield return parent;
+      }
+    }
+
+    /// <summary>
+    /// Returns a collection of the sibling tokens after this token, in document order.
+    /// </summary>
+    /// <returns>A collection of the sibling tokens after this tokens, in document order.</returns>
+    public IEnumerable<JToken> AfterSelf()
+    {
+      if (Parent == null)
+        yield break;
+
+      for (JToken o = Next; o != null; o = o.Next)
+      {
+        yield return o;
+      }
+    }
+
+    /// <summary>
+    /// Returns a collection of the sibling tokens before this token, in document order.
+    /// </summary>
+    /// <returns>A collection of the sibling tokens before this token, in document order.</returns>
+    public IEnumerable<JToken> BeforeSelf()
+    {
+      for (JToken o = Parent.First; o != this; o = o.Next)
+      {
+        yield return o;
+      }
+    }
+
+    /// <summary>
+    /// Gets the <see cref="JToken"/> with the specified key.
+    /// </summary>
+    /// <value>The <see cref="JToken"/> with the specified key.</value>
+    public virtual JToken this[object key]
+    {
+      get { throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); }
+      set { throw new InvalidOperationException("Cannot set child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); }
+    }
+
+    /// <summary>
+    /// Gets the <see cref="JToken"/> with the specified key converted to the specified type.
+    /// </summary>
+    /// <typeparam name="T">The type to convert the token to.</typeparam>
+    /// <param name="key">The token key.</param>
+    /// <returns>The converted token value.</returns>
+    public virtual T Value<T>(object key)
+    {
+      JToken token = this[key];
+
+      return Extensions.Convert<JToken, T>(token);
+    }
+
+    /// <summary>
+    /// Get the first child token of this token.
+    /// </summary>
+    /// <value>A <see cref="JToken"/> containing the first child token of the <see cref="JToken"/>.</value>
+    public virtual JToken First
+    {
+      get { throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); }
+    }
+
+    /// <summary>
+    /// Get the last child token of this token.
+    /// </summary>
+    /// <value>A <see cref="JToken"/> containing the last child token of the <see cref="JToken"/>.</value>
+    public virtual JToken Last
+    {
+      get { throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); }
+    }
+
+    /// <summary>
+    /// Returns a collection of the child tokens of this token, in document order.
+    /// </summary>
+    /// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> containing the child tokens of this <see cref="JToken"/>, in document order.</returns>
+    public virtual JEnumerable<JToken> Children()
+    {
+      return JEnumerable<JToken>.Empty;
+    }
+
+    /// <summary>
+    /// Returns a collection of the child tokens of this token, in document order, filtered by the specified type.
+    /// </summary>
+    /// <typeparam name="T">The type to filter the child tokens on.</typeparam>
+    /// <returns>A <see cref="JEnumerable{T}"/> containing the child tokens of this <see cref="JToken"/>, in document order.</returns>
+    public JEnumerable<T> Children<T>() where T : JToken
+    {
+      return new JEnumerable<T>(Children().OfType<T>());
+    }
+
+    /// <summary>
+    /// Returns a collection of the child values of this token, in document order.
+    /// </summary>
+    /// <typeparam name="T">The type to convert the values to.</typeparam>
+    /// <returns>A <see cref="IEnumerable{T}"/> containing the child values of this <see cref="JToken"/>, in document order.</returns>
+    public virtual IEnumerable<T> Values<T>()
+    {
+      throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType()));
+    }
+
+    /// <summary>
+    /// Removes this token from its parent.
+    /// </summary>
+    public void Remove()
+    {
+      if (_parent == null)
+        throw new InvalidOperationException("The parent is missing.");
+
+      _parent.RemoveItem(this);
+    }
+
+    /// <summary>
+    /// Replaces this token with the specified token.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    public void Replace(JToken value)
+    {
+      if (_parent == null)
+        throw new InvalidOperationException("The parent is missing.");
+
+      _parent.ReplaceItem(this, value);
+    }
+
+    /// <summary>
+    /// Writes this token to a <see cref="JsonWriter"/>.
+    /// </summary>
+    /// <param name="writer">A <see cref="JsonWriter"/> into which this method will write.</param>
+    /// <param name="converters">A collection of <see cref="JsonConverter"/> which will be used when writing the token.</param>
+    public abstract void WriteTo(JsonWriter writer, params JsonConverter[] converters);
+
+    /// <summary>
+    /// Returns the indented JSON for this token.
+    /// </summary>
+    /// <returns>
+    /// The indented JSON for this token.
+    /// </returns>
+    public override string ToString()
+    {
+      return ToString(Formatting.Indented);
+    }
+
+    /// <summary>
+    /// Returns the JSON for this token using the given formatting and converters.
+    /// </summary>
+    /// <param name="formatting">Indicates how the output is formatted.</param>
+    /// <param name="converters">A collection of <see cref="JsonConverter"/> which will be used when writing the token.</param>
+    /// <returns>The JSON for this token using the given formatting and converters.</returns>
+    public string ToString(Formatting formatting, params JsonConverter[] converters)
+    {
+      using (StringWriter sw = new StringWriter(CultureInfo.InvariantCulture))
+      {
+        JsonTextWriter jw = new JsonTextWriter(sw);
+        jw.Formatting = formatting;
+
+        WriteTo(jw, converters);
+
+        return sw.ToString();
+      }
+    }
+
+    private static JValue EnsureValue(JToken value)
+    {
+      if (value == null)
+        throw new ArgumentNullException("value");
+
+      if (value is JProperty)
+        value = ((JProperty)value).Value;
+
+      JValue v = value as JValue;
+
+      return v;
+    }
+
+    private static string GetType(JToken token)
+    {
+      ValidationUtils.ArgumentNotNull(token, "token");
+
+      if (token is JProperty)
+        token = ((JProperty)token).Value;
+
+      return token.Type.ToString();
+    }
+
+    private static bool IsNullable(JToken o)
+    {
+      return (o.Type == JTokenType.Undefined || o.Type == JTokenType.Null);
+    }
+
+    private static bool ValidateFloat(JToken o, bool nullable)
+    {
+      return (o.Type == JTokenType.Float || o.Type == JTokenType.Integer || (nullable && IsNullable(o)));
+    }
+
+    private static bool ValidateInteger(JToken o, bool nullable)
+    {
+      return (o.Type == JTokenType.Integer || (nullable && IsNullable(o)));
+    }
+
+    private static bool ValidateDate(JToken o, bool nullable)
+    {
+      return (o.Type == JTokenType.Date || (nullable && IsNullable(o)));
+    }
+
+    private static bool ValidateBoolean(JToken o, bool nullable)
+    {
+      return (o.Type == JTokenType.Boolean || (nullable && IsNullable(o)));
+    }
+
+    private static bool ValidateString(JToken o)
+    {
+      return (o.Type == JTokenType.String || o.Type == JTokenType.Comment || o.Type == JTokenType.Raw || IsNullable(o));
+    }
+
+    private static bool ValidateBytes(JToken o)
+    {
+      return (o.Type == JTokenType.Bytes || IsNullable(o));
+    }
+
+    #region Cast from operators
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Boolean"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator bool(JToken value)
+    {
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateBoolean(v, false))
+        throw new ArgumentException("Can not convert {0} to Boolean.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return Convert.ToBoolean(v.Value, CultureInfo.InvariantCulture);
+    }
+
+#if !PocketPC && !NET20
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.DateTimeOffset"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator DateTimeOffset(JToken value)
+    {
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateDate(v, false))
+        throw new ArgumentException("Can not convert {0} to DateTimeOffset.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (DateTimeOffset)v.Value;
+    }
+#endif
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Boolean}"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator bool?(JToken value)
+    {
+      if (value == null)
+        return null;
+
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateBoolean(v, true))
+        throw new ArgumentException("Can not convert {0} to Boolean.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (v.Value != null) ? (bool?)Convert.ToBoolean(v.Value, CultureInfo.InvariantCulture) : null;
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Int64"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator long(JToken value)
+    {
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateInteger(v, false))
+        throw new ArgumentException("Can not convert {0} to Int64.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return Convert.ToInt64(v.Value, CultureInfo.InvariantCulture);
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{DateTime}"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator DateTime?(JToken value)
+    {
+      if (value == null)
+        return null;
+
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateDate(v, true))
+        throw new ArgumentException("Can not convert {0} to DateTime.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (v.Value != null) ? (DateTime?)Convert.ToDateTime(v.Value, CultureInfo.InvariantCulture) : null;
+    }
+
+#if !PocketPC && !NET20
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{DateTimeOffset}"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator DateTimeOffset?(JToken value)
+    {
+      if (value == null)
+        return null;
+
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateDate(v, true))
+        throw new ArgumentException("Can not convert {0} to DateTimeOffset.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (DateTimeOffset?)v.Value;
+    }
+#endif
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Decimal}"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator decimal?(JToken value)
+    {
+      if (value == null)
+        return null;
+
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateFloat(v, true))
+        throw new ArgumentException("Can not convert {0} to Decimal.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (v.Value != null) ? (decimal?)Convert.ToDecimal(v.Value, CultureInfo.InvariantCulture) : null;
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Double}"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator double?(JToken value)
+    {
+      if (value == null)
+        return null;
+
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateFloat(v, true))
+        throw new ArgumentException("Can not convert {0} to Double.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (double?)v.Value;
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Int32"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator int(JToken value)
+    {
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateInteger(v, false))
+        throw new ArgumentException("Can not convert {0} to Int32.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return Convert.ToInt32(v.Value, CultureInfo.InvariantCulture);
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Int16"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator short(JToken value)
+    {
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateInteger(v, false))
+        throw new ArgumentException("Can not convert {0} to Int16.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return Convert.ToInt16(v.Value, CultureInfo.InvariantCulture);
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.UInt16"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    [CLSCompliant(false)]
+    public static explicit operator ushort(JToken value)
+    {
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateInteger(v, false))
+        throw new ArgumentException("Can not convert {0} to UInt16.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return Convert.ToUInt16(v.Value, CultureInfo.InvariantCulture);
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Int32}"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator int?(JToken value)
+    {
+      if (value == null)
+        return null;
+
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateInteger(v, true))
+        throw new ArgumentException("Can not convert {0} to Int32.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (v.Value != null) ? (int?)Convert.ToInt32(v.Value, CultureInfo.InvariantCulture) : null;
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Int16}"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator short?(JToken value)
+    {
+      if (value == null)
+        return null;
+
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateInteger(v, true))
+        throw new ArgumentException("Can not convert {0} to Int16.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (v.Value != null) ? (short?)Convert.ToInt16(v.Value, CultureInfo.InvariantCulture) : null;
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{UInt16}"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    [CLSCompliant(false)]
+    public static explicit operator ushort?(JToken value)
+    {
+      if (value == null)
+        return null;
+
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateInteger(v, true))
+        throw new ArgumentException("Can not convert {0} to UInt16.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (v.Value != null) ? (ushort?)Convert.ToInt16(v.Value, CultureInfo.InvariantCulture) : null;
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.DateTime"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator DateTime(JToken value)
+    {
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateDate(v, false))
+        throw new ArgumentException("Can not convert {0} to DateTime.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return Convert.ToDateTime(v.Value, CultureInfo.InvariantCulture);
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Int64}"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator long?(JToken value)
+    {
+      if (value == null)
+        return null;
+
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateInteger(v, true))
+        throw new ArgumentException("Can not convert {0} to Int64.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (v.Value != null) ? (long?)Convert.ToInt64(v.Value, CultureInfo.InvariantCulture) : null;
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Single}"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator float?(JToken value)
+    {
+      if (value == null)
+        return null;
+
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateFloat(v, true))
+        throw new ArgumentException("Can not convert {0} to Single.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (v.Value != null) ? (float?)Convert.ToSingle(v.Value, CultureInfo.InvariantCulture) : null;
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Decimal"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator decimal(JToken value)
+    {
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateFloat(v, false))
+        throw new ArgumentException("Can not convert {0} to Decimal.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return Convert.ToDecimal(v.Value, CultureInfo.InvariantCulture);
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{UInt32}"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    [CLSCompliant(false)]
+    public static explicit operator uint?(JToken value)
+    {
+      if (value == null)
+        return null;
+
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateInteger(v, true))
+        throw new ArgumentException("Can not convert {0} to UInt32.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (v.Value != null) ? (uint?)Convert.ToUInt32(v.Value, CultureInfo.InvariantCulture) : null;
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{UInt64}"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    [CLSCompliant(false)]
+    public static explicit operator ulong?(JToken value)
+    {
+      if (value == null)
+        return null;
+
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateInteger(v, true))
+        throw new ArgumentException("Can not convert {0} to UInt64.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (v.Value != null) ? (ulong?)Convert.ToUInt64(v.Value, CultureInfo.InvariantCulture) : null;
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Double"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator double(JToken value)
+    {
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateFloat(v, false))
+        throw new ArgumentException("Can not convert {0} to Double.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return Convert.ToDouble(v.Value, CultureInfo.InvariantCulture);
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Single"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator float(JToken value)
+    {
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateFloat(v, false))
+        throw new ArgumentException("Can not convert {0} to Single.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return Convert.ToSingle(v.Value, CultureInfo.InvariantCulture);
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.String"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator string(JToken value)
+    {
+      if (value == null)
+        return null;
+
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateString(v))
+        throw new ArgumentException("Can not convert {0} to String.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (v.Value != null) ? Convert.ToString(v.Value, CultureInfo.InvariantCulture) : null;
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.UInt32"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    [CLSCompliant(false)]
+    public static explicit operator uint(JToken value)
+    {
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateInteger(v, false))
+        throw new ArgumentException("Can not convert {0} to UInt32.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return Convert.ToUInt32(v.Value, CultureInfo.InvariantCulture);
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.UInt64"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    [CLSCompliant(false)]
+    public static explicit operator ulong(JToken value)
+    {
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateInteger(v, false))
+        throw new ArgumentException("Can not convert {0} to UInt64.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return Convert.ToUInt64(v.Value, CultureInfo.InvariantCulture);
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="T:System.Byte[]"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator byte[](JToken value)
+    {
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateBytes(v))
+        throw new ArgumentException("Can not convert {0} to byte array.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (byte[])v.Value;
+    }
+    #endregion
+
+    #region Cast to operators
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Boolean"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(bool value)
+    {
+      return new JValue(value);
+    }
+
+#if !PocketPC && !NET20
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="DateTimeOffset"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(DateTimeOffset value)
+    {
+      return new JValue(value);
+    }
+#endif
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Nullable{Boolean}"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(bool? value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Nullable{Int64}"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(long value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Nullable{DateTime}"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(DateTime? value)
+    {
+      return new JValue(value);
+    }
+
+#if !PocketPC && !NET20
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Nullable{DateTimeOffset}"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(DateTimeOffset? value)
+    {
+      return new JValue(value);
+    }
+#endif
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Nullable{Decimal}"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(decimal? value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Nullable{Double}"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(double? value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Int16"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    [CLSCompliant(false)]
+    public static implicit operator JToken(short value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="UInt16"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    [CLSCompliant(false)]
+    public static implicit operator JToken(ushort value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Int32"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(int value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Nullable{Int32}"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(int? value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="DateTime"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(DateTime value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Nullable{Int64}"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(long? value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Nullable{Single}"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(float? value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Decimal"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(decimal value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Nullable{Int16}"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    [CLSCompliant(false)]
+    public static implicit operator JToken(short? value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Nullable{UInt16}"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    [CLSCompliant(false)]
+    public static implicit operator JToken(ushort? value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Nullable{UInt32}"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    [CLSCompliant(false)]
+    public static implicit operator JToken(uint? value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Nullable{UInt64}"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    [CLSCompliant(false)]
+    public static implicit operator JToken(ulong? value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Double"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(double value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Single"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(float value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="String"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(string value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="UInt32"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    [CLSCompliant(false)]
+    public static implicit operator JToken(uint value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="UInt64"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    [CLSCompliant(false)]
+    public static implicit operator JToken(ulong value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="T:System.Byte[]"/> to <see cref="Newtonsoft.Json.Linq.JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(byte[] value)
+    {
+      return new JValue(value);
+    }
+    #endregion
+
+    IEnumerator IEnumerable.GetEnumerator()
+    {
+      return ((IEnumerable<JToken>)this).GetEnumerator();
+    }
+
+    IEnumerator<JToken> IEnumerable<JToken>.GetEnumerator()
+    {
+      return Children().GetEnumerator();
+    }
+
+    internal abstract int GetDeepHashCode();
+
+    IJEnumerable<JToken> IJEnumerable<JToken>.this[object key]
+    {
+      get { return this[key]; }
+    }
+
+    /// <summary>
+    /// Creates an <see cref="JsonReader"/> for this token.
+    /// </summary>
+    /// <returns>An <see cref="JsonReader"/> that can be used to read this token and its descendants.</returns>
+    public JsonReader CreateReader()
+    {
+      return new JTokenReader(this);
+    }
+
+    internal static JToken FromObjectInternal(object o, JsonSerializer jsonSerializer)
+    {
+      ValidationUtils.ArgumentNotNull(o, "o");
+      ValidationUtils.ArgumentNotNull(jsonSerializer, "jsonSerializer");
+
+      JToken token;
+      using (JTokenWriter jsonWriter = new JTokenWriter())
+      {
+        jsonSerializer.Serialize(jsonWriter, o);
+        token = jsonWriter.Token;
+      }
+
+      return token;
+    }
+
+    /// <summary>
+    /// Creates a <see cref="JToken"/> from an object.
+    /// </summary>
+    /// <param name="o">The object that will be used to create <see cref="JToken"/>.</param>
+    /// <returns>A <see cref="JToken"/> with the value of the specified object</returns>
+    public static JToken FromObject(object o)
+    {
+      return FromObjectInternal(o, new JsonSerializer());
+    }
+
+    /// <summary>
+    /// Creates a <see cref="JToken"/> from an object using the specified <see cref="JsonSerializer"/>.
+    /// </summary>
+    /// <param name="o">The object that will be used to create <see cref="JToken"/>.</param>
+    /// <param name="jsonSerializer">The <see cref="JsonSerializer"/> that will be used when reading the object.</param>
+    /// <returns>A <see cref="JToken"/> with the value of the specified object</returns>
+    public static JToken FromObject(object o, JsonSerializer jsonSerializer)
+    {
+      return FromObjectInternal(o, jsonSerializer);
+    }
+
+    /// <summary>
+    /// Creates the specified .NET type from the <see cref="JToken"/>.
+    /// </summary>
+    /// <typeparam name="T">The object type that the token will be deserialized to.</typeparam>
+    /// <returns>The new object created from the JSON value.</returns>
+    public T ToObject<T>()
+    {
+      return ToObject<T>(new JsonSerializer());
+    }
+
+    /// <summary>
+    /// Creates the specified .NET type from the <see cref="JToken"/> using the specified <see cref="JsonSerializer"/>.
+    /// </summary>
+    /// <typeparam name="T">The object type that the token will be deserialized to.</typeparam>
+    /// <param name="jsonSerializer">The <see cref="JsonSerializer"/> that will be used when creating the object.</param>
+    /// <returns>The new object created from the JSON value.</returns>
+    public T ToObject<T>(JsonSerializer jsonSerializer)
+    {
+      ValidationUtils.ArgumentNotNull(jsonSerializer, "jsonSerializer");
+
+      using (JTokenReader jsonReader = new JTokenReader(this))
+      {
+        return jsonSerializer.Deserialize<T>(jsonReader);
+      }
+    }
+
+    /// <summary>
+    /// Creates a <see cref="JToken"/> from a <see cref="JsonReader"/>.
+    /// </summary>
+    /// <param name="reader">An <see cref="JsonReader"/> positioned at the token to read into this <see cref="JToken"/>.</param>
+    /// <returns>
+    /// An <see cref="JToken"/> that contains the token and its descendant tokens
+    /// that were read from the reader. The runtime type of the token is determined
+    /// by the token type of the first token encountered in the reader.
+    /// </returns>
+    public static JToken ReadFrom(JsonReader reader)
+    {
+      ValidationUtils.ArgumentNotNull(reader, "reader");
+
+      if (reader.TokenType == JsonToken.None)
+      {
+        if (!reader.Read())
+          throw JsonReaderException.Create(reader, "Error reading JToken from JsonReader.");
+      }
+
+      if (reader.TokenType == JsonToken.StartObject)
+        return JObject.Load(reader);
+
+      if (reader.TokenType == JsonToken.StartArray)
+        return JArray.Load(reader);
+
+      if (reader.TokenType == JsonToken.PropertyName)
+        return JProperty.Load(reader);
+
+      if (reader.TokenType == JsonToken.StartConstructor)
+        return JConstructor.Load(reader);
+
+      if (!JsonReader.IsStartToken(reader.TokenType))
+        return new JValue(reader.Value);
+
+      throw JsonReaderException.Create(reader, "Error reading JToken from JsonReader. Unexpected token: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
+    }
+
+    /// <summary>
+    /// Load a <see cref="JToken"/> from a string that contains JSON.
+    /// </summary>
+    /// <param name="json">A <see cref="String"/> that contains JSON.</param>
+    /// <returns>A <see cref="JToken"/> populated from the string that contains JSON.</returns>
+    public static JToken Parse(string json)
+    {
+      JsonReader reader = new JsonTextReader(new StringReader(json));
+
+      JToken t = Load(reader);
+
+      if (reader.Read() && reader.TokenType != JsonToken.Comment)
+        throw JsonReaderException.Create(reader, "Additional text found in JSON string after parsing content.");
+
+      return t;
+    }
+
+    /// <summary>
+    /// Creates a <see cref="JToken"/> from a <see cref="JsonReader"/>.
+    /// </summary>
+    /// <param name="reader">An <see cref="JsonReader"/> positioned at the token to read into this <see cref="JToken"/>.</param>
+    /// <returns>
+    /// An <see cref="JToken"/> that contains the token and its descendant tokens
+    /// that were read from the reader. The runtime type of the token is determined
+    /// by the token type of the first token encountered in the reader.
+    /// </returns>
+    public static JToken Load(JsonReader reader)
+    {
+      return ReadFrom(reader);
+    }
+
+    internal void SetLineInfo(IJsonLineInfo lineInfo)
+    {
+      if (lineInfo == null || !lineInfo.HasLineInfo())
+        return;
+
+      SetLineInfo(lineInfo.LineNumber, lineInfo.LinePosition);
+    }
+
+    internal void SetLineInfo(int lineNumber, int linePosition)
+    {
+      _lineNumber = lineNumber;
+      _linePosition = linePosition;
+    }
+
+    bool IJsonLineInfo.HasLineInfo()
+    {
+      return (_lineNumber != null && _linePosition != null);
+    }
+
+    int IJsonLineInfo.LineNumber
+    {
+      get { return _lineNumber ?? 0; }
+    }
+
+    int IJsonLineInfo.LinePosition
+    {
+      get { return _linePosition ?? 0; }
+    }
+
+    /// <summary>
+    /// Selects the token that matches the object path.
+    /// </summary>
+    /// <param name="path">
+    /// The object path from the current <see cref="JToken"/> to the <see cref="JToken"/>
+    /// to be returned. This must be a string of property names or array indexes separated
+    /// by periods, such as <code>Tables[0].DefaultView[0].Price</code> in C# or
+    /// <code>Tables(0).DefaultView(0).Price</code> in Visual Basic.
+    /// </param>
+    /// <returns>The <see cref="JToken"/> that matches the object path or a null reference if no matching token is found.</returns>
+    public JToken SelectToken(string path)
+    {
+      return SelectToken(path, false);
+    }
+
+    /// <summary>
+    /// Selects the token that matches the object path.
+    /// </summary>
+    /// <param name="path">
+    /// The object path from the current <see cref="JToken"/> to the <see cref="JToken"/>
+    /// to be returned. This must be a string of property names or array indexes separated
+    /// by periods, such as <code>Tables[0].DefaultView[0].Price</code> in C# or
+    /// <code>Tables(0).DefaultView(0).Price</code> in Visual Basic.
+    /// </param>
+    /// <param name="errorWhenNoMatch">A flag to indicate whether an error should be thrown if no token is found.</param>
+    /// <returns>The <see cref="JToken"/> that matches the object path.</returns>
+    public JToken SelectToken(string path, bool errorWhenNoMatch)
+    {
+      JPath p = new JPath(path);
+      return p.Evaluate(this, errorWhenNoMatch);
+    }
+
+#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
+    /// <summary>
+    /// Returns the <see cref="T:System.Dynamic.DynamicMetaObject"/> responsible for binding operations performed on this object.
+    /// </summary>
+    /// <param name="parameter">The expression tree representation of the runtime value.</param>
+    /// <returns>
+    /// The <see cref="T:System.Dynamic.DynamicMetaObject"/> to bind this object.
+    /// </returns>
+    protected virtual DynamicMetaObject GetMetaObject(Expression parameter)
+    {
+      return new DynamicProxyMetaObject<JToken>(parameter, this, new DynamicProxy<JToken>(), true);
+    }
+
+    /// <summary>
+    /// Returns the <see cref="T:System.Dynamic.DynamicMetaObject"/> responsible for binding operations performed on this object.
+    /// </summary>
+    /// <param name="parameter">The expression tree representation of the runtime value.</param>
+    /// <returns>
+    /// The <see cref="T:System.Dynamic.DynamicMetaObject"/> to bind this object.
+    /// </returns>
+    DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression parameter)
+    {
+      return GetMetaObject(parameter);
+    }
+#endif
+
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+    object ICloneable.Clone()
+    {
+      return DeepClone();
+    }
+#endif
+
+    /// <summary>
+    /// Creates a new instance of the <see cref="JToken"/>. All child tokens are recursively cloned.
+    /// </summary>
+    /// <returns>A new instance of the <see cref="JToken"/>.</returns>
+    public JToken DeepClone()
+    {
+      return CloneToken();
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JTokenEqualityComparer.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JTokenEqualityComparer.cs
index 0bc3efb..25a2eeb 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JTokenEqualityComparer.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JTokenEqualityComparer.cs
@@ -1,40 +1,62 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Newtonsoft.Json.Linq
-{
-  /// <summary>
-  /// Compares tokens to determine whether they are equal.
-  /// </summary>
-  public class JTokenEqualityComparer : IEqualityComparer<JToken>
-  {
-    /// <summary>
-    /// Determines whether the specified objects are equal.
-    /// </summary>
-    /// <param name="x">The first object of type <paramref name="T"/> to compare.</param>
-    /// <param name="y">The second object of type <paramref name="T"/> to compare.</param>
-    /// <returns>
-    /// true if the specified objects are equal; otherwise, false.
-    /// </returns>
-    public bool Equals(JToken x, JToken y)
-    {
-      return JToken.DeepEquals(x, y);
-    }
-
-    /// <summary>
-    /// Returns a hash code for the specified object.
-    /// </summary>
-    /// <param name="obj">The <see cref="T:System.Object"/> for which a hash code is to be returned.</param>
-    /// <returns>A hash code for the specified object.</returns>
-    /// <exception cref="T:System.ArgumentNullException">The type of <paramref name="obj"/> is a reference type and <paramref name="obj"/> is null.</exception>
-    public int GetHashCode(JToken obj)
-    {
-      if (obj == null)
-        return 0;
-
-      return obj.GetDeepHashCode();
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System.Collections.Generic;
+
+namespace Newtonsoft.Json.Linq
+{
+  /// <summary>
+  /// Compares tokens to determine whether they are equal.
+  /// </summary>
+  public class JTokenEqualityComparer : IEqualityComparer<JToken>
+  {
+    /// <summary>
+    /// Determines whether the specified objects are equal.
+    /// </summary>
+    /// <param name="x">The first object of type <see cref="JToken"/> to compare.</param>
+    /// <param name="y">The second object of type <see cref="JToken"/> to compare.</param>
+    /// <returns>
+    /// true if the specified objects are equal; otherwise, false.
+    /// </returns>
+    public bool Equals(JToken x, JToken y)
+    {
+      return JToken.DeepEquals(x, y);
+    }
+
+    /// <summary>
+    /// Returns a hash code for the specified object.
+    /// </summary>
+    /// <param name="obj">The <see cref="T:System.Object"/> for which a hash code is to be returned.</param>
+    /// <returns>A hash code for the specified object.</returns>
+    /// <exception cref="T:System.ArgumentNullException">The type of <paramref name="obj"/> is a reference type and <paramref name="obj"/> is null.</exception>
+    public int GetHashCode(JToken obj)
+    {
+      if (obj == null)
+        return 0;
+
+      return obj.GetDeepHashCode();
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JTokenReader.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JTokenReader.cs
index b09037d..0198d66 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JTokenReader.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JTokenReader.cs
@@ -1,249 +1,323 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Newtonsoft.Json.Utilities;
-using System.Globalization;
-
-namespace Newtonsoft.Json.Linq
-{
-  /// <summary>
-  /// Represents a reader that provides fast, non-cached, forward-only access to serialized Json data.
-  /// </summary>
-  public class JTokenReader : JsonReader, IJsonLineInfo
-  {
-    private readonly JToken _root;
-    private JToken _parent;
-    private JToken _current;
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JTokenReader"/> class.
-    /// </summary>
-    /// <param name="token">The token to read from.</param>
-    public JTokenReader(JToken token)
-    {
-      ValidationUtils.ArgumentNotNull(token, "token");
-
-      _root = token;
-      _current = token;
-    }
-
-    /// <summary>
-    /// Reads the next JSON token from the stream as a <see cref="T:Byte[]"/>.
-    /// </summary>
-    /// <returns>
-    /// A <see cref="T:Byte[]"/> or a null reference if the next JSON token is null.
-    /// </returns>
-    public override byte[] ReadAsBytes()
-    {
-      Read();
-
-      // attempt to convert possible base 64 string to bytes
-      if (TokenType == JsonToken.String)
-      {
-        string s = (string) Value;
-        byte[] data = (s.Length == 0) ? new byte[0] : Convert.FromBase64String(s);
-        SetToken(JsonToken.Bytes, data);
-      }
-
-      if (TokenType == JsonToken.Bytes)
-        return (byte[])Value;
-      if (TokenType == JsonToken.Null)
-        return null;
-
-      throw new JsonReaderException("Error reading bytes. Expected bytes but got {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
-    }
-
-    /// <summary>
-    /// Reads the next JSON token from the stream.
-    /// </summary>
-    /// <returns>
-    /// true if the next token was read successfully; false if there are no more tokens to read.
-    /// </returns>
-    public override bool Read()
-    {
-      if (CurrentState != State.Start)
-      {
-        JContainer container = _current as JContainer;
-        if (container != null && _parent != container)
-          return ReadInto(container);
-        else
-          return ReadOver(_current);
-      }
-
-      SetToken(_current);
-      return true;
-    }
-
-    private bool ReadOver(JToken t)
-    {
-      if (t == _root)
-        return ReadToEnd();
-
-      JToken next = t.Next;
-      if ((next == null || next == t) || t == t.Parent.Last)
-      {
-        if (t.Parent == null)
-          return ReadToEnd();
-
-        return SetEnd(t.Parent);
-      }
-      else
-      {
-        _current = next;
-        SetToken(_current);
-        return true;
-      }
-    }
-
-    private bool ReadToEnd()
-    {
-      //CurrentState = State.Finished;
-      return false;
-    }
-
-    private bool IsEndElement
-    {
-      get { return (_current == _parent); }
-    }
-
-    private JsonToken? GetEndToken(JContainer c)
-    {
-      switch (c.Type)
-      {
-        case JTokenType.Object:
-          return JsonToken.EndObject;
-        case JTokenType.Array:
-          return JsonToken.EndArray;
-        case JTokenType.Constructor:
-          return JsonToken.EndConstructor;
-        case JTokenType.Property:
-          return null;
-        default:
-          throw MiscellaneousUtils.CreateArgumentOutOfRangeException("Type", c.Type, "Unexpected JContainer type.");
-      }
-    }
-
-    private bool ReadInto(JContainer c)
-    {
-      JToken firstChild = c.First;
-      if (firstChild == null)
-      {
-        return SetEnd(c);
-      }
-      else
-      {
-        SetToken(firstChild);
-        _current = firstChild;
-        _parent = c;
-        return true;
-      }
-    }
-
-    private bool SetEnd(JContainer c)
-    {
-      JsonToken? endToken = GetEndToken(c);
-      if (endToken != null)
-      {
-        SetToken(endToken.Value);
-        _current = c;
-        _parent = c;
-        return true;
-      }
-      else
-      {
-        return ReadOver(c);
-      }
-    }
-
-    private void SetToken(JToken token)
-    {
-      switch (token.Type)
-      {
-        case JTokenType.Object:
-          SetToken(JsonToken.StartObject);
-          break;
-        case JTokenType.Array:
-          SetToken(JsonToken.StartArray);
-          break;
-        case JTokenType.Constructor:
-          SetToken(JsonToken.StartConstructor);
-          break;
-        case JTokenType.Property:
-          SetToken(JsonToken.PropertyName, ((JProperty)token).Name);
-          break;
-        case JTokenType.Comment:
-          SetToken(JsonToken.Comment, ((JValue)token).Value);
-          break;
-        case JTokenType.Integer:
-          SetToken(JsonToken.Integer, ((JValue)token).Value);
-          break;
-        case JTokenType.Float:
-          SetToken(JsonToken.Float, ((JValue)token).Value);
-          break;
-        case JTokenType.String:
-          SetToken(JsonToken.String, ((JValue)token).Value);
-          break;
-        case JTokenType.Boolean:
-          SetToken(JsonToken.Boolean, ((JValue)token).Value);
-          break;
-        case JTokenType.Null:
-          SetToken(JsonToken.Null, ((JValue)token).Value);
-          break;
-        case JTokenType.Undefined:
-          SetToken(JsonToken.Undefined, ((JValue)token).Value);
-          break;
-        case JTokenType.Date:
-          SetToken(JsonToken.Date, ((JValue)token).Value);
-          break;
-        case JTokenType.Raw:
-          SetToken(JsonToken.Raw, ((JValue)token).Value);
-          break;
-        case JTokenType.Bytes:
-          SetToken(JsonToken.Bytes, ((JValue)token).Value);
-          break;
-        default:
-          throw MiscellaneousUtils.CreateArgumentOutOfRangeException("Type", token.Type, "Unexpected JTokenType.");
-      }
-    }
-
-    bool IJsonLineInfo.HasLineInfo()
-    {
-      if (CurrentState == State.Start)
-        return false;
-
-      IJsonLineInfo info = IsEndElement ? null : _current;
-      return (info != null && info.HasLineInfo());
-    }
-
-    int IJsonLineInfo.LineNumber
-    {
-      get
-      {
-        if (CurrentState == State.Start)
-          return 0;
-
-        IJsonLineInfo info = IsEndElement ? null : _current;
-        if (info != null)
-          return info.LineNumber;
-        
-        return 0;
-      }
-    }
-
-    int IJsonLineInfo.LinePosition
-    {
-      get
-      {
-        if (CurrentState == State.Start)
-          return 0;
-
-        IJsonLineInfo info = IsEndElement ? null : _current;
-        if (info != null)
-          return info.LinePosition;
-
-        return 0;
-      }
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Linq
+{
+  /// <summary>
+  /// Represents a reader that provides fast, non-cached, forward-only access to serialized Json data.
+  /// </summary>
+  public class JTokenReader : JsonReader, IJsonLineInfo
+  {
+    private readonly JToken _root;
+    private JToken _parent;
+    private JToken _current;
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JTokenReader"/> class.
+    /// </summary>
+    /// <param name="token">The token to read from.</param>
+    public JTokenReader(JToken token)
+    {
+      ValidationUtils.ArgumentNotNull(token, "token");
+
+      _root = token;
+      _current = token;
+    }
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="T:Byte[]"/>.
+    /// </summary>
+    /// <returns>
+    /// A <see cref="T:Byte[]"/> or a null reference if the next JSON token is null. This method will return <c>null</c> at the end of an array.
+    /// </returns>
+    public override byte[] ReadAsBytes()
+    {
+      return ReadAsBytesInternal();
+    }
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="Nullable{Decimal}"/>.
+    /// </summary>
+    /// <returns>A <see cref="Nullable{Decimal}"/>. This method will return <c>null</c> at the end of an array.</returns>
+    public override decimal? ReadAsDecimal()
+    {
+      return ReadAsDecimalInternal();
+    }
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="Nullable{Int32}"/>.
+    /// </summary>
+    /// <returns>A <see cref="Nullable{Int32}"/>. This method will return <c>null</c> at the end of an array.</returns>
+    public override int? ReadAsInt32()
+    {
+      return ReadAsInt32Internal();
+    }
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="String"/>.
+    /// </summary>
+    /// <returns>A <see cref="String"/>. This method will return <c>null</c> at the end of an array.</returns>
+    public override string ReadAsString()
+    {
+      return ReadAsStringInternal();
+    }
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="Nullable{DateTime}"/>.
+    /// </summary>
+    /// <returns>A <see cref="String"/>. This method will return <c>null</c> at the end of an array.</returns>
+    public override DateTime? ReadAsDateTime()
+    {
+      return ReadAsDateTimeInternal();
+    }
+
+#if !NET20
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="Nullable{DateTimeOffset}"/>.
+    /// </summary>
+    /// <returns>A <see cref="Nullable{DateTimeOffset}"/>. This method will return <c>null</c> at the end of an array.</returns>
+    public override DateTimeOffset? ReadAsDateTimeOffset()
+    {
+      return ReadAsDateTimeOffsetInternal();
+    }
+#endif
+
+    internal override bool ReadInternal()
+    {
+      if (CurrentState != State.Start)
+      {
+        JContainer container = _current as JContainer;
+        if (container != null && _parent != container)
+          return ReadInto(container);
+        else
+          return ReadOver(_current);
+      }
+
+      SetToken(_current);
+      return true;
+    }
+
+    /// <summary>
+    /// Reads the next JSON token from the stream.
+    /// </summary>
+    /// <returns>
+    /// true if the next token was read successfully; false if there are no more tokens to read.
+    /// </returns>
+    public override bool Read()
+    {
+      _readType = ReadType.Read;
+
+      return ReadInternal();
+    }
+
+    private bool ReadOver(JToken t)
+    {
+      if (t == _root)
+        return ReadToEnd();
+
+      JToken next = t.Next;
+      if ((next == null || next == t) || t == t.Parent.Last)
+      {
+        if (t.Parent == null)
+          return ReadToEnd();
+
+        return SetEnd(t.Parent);
+      }
+      else
+      {
+        _current = next;
+        SetToken(_current);
+        return true;
+      }
+    }
+
+    private bool ReadToEnd()
+    {
+      SetToken(JsonToken.None);
+      return false;
+    }
+
+    private bool IsEndElement
+    {
+      get { return (_current == _parent); }
+    }
+
+    private JsonToken? GetEndToken(JContainer c)
+    {
+      switch (c.Type)
+      {
+        case JTokenType.Object:
+          return JsonToken.EndObject;
+        case JTokenType.Array:
+          return JsonToken.EndArray;
+        case JTokenType.Constructor:
+          return JsonToken.EndConstructor;
+        case JTokenType.Property:
+          return null;
+        default:
+          throw MiscellaneousUtils.CreateArgumentOutOfRangeException("Type", c.Type, "Unexpected JContainer type.");
+      }
+    }
+
+    private bool ReadInto(JContainer c)
+    {
+      JToken firstChild = c.First;
+      if (firstChild == null)
+      {
+        return SetEnd(c);
+      }
+      else
+      {
+        SetToken(firstChild);
+        _current = firstChild;
+        _parent = c;
+        return true;
+      }
+    }
+
+    private bool SetEnd(JContainer c)
+    {
+      JsonToken? endToken = GetEndToken(c);
+      if (endToken != null)
+      {
+        SetToken(endToken.Value);
+        _current = c;
+        _parent = c;
+        return true;
+      }
+      else
+      {
+        return ReadOver(c);
+      }
+    }
+
+    private void SetToken(JToken token)
+    {
+      switch (token.Type)
+      {
+        case JTokenType.Object:
+          SetToken(JsonToken.StartObject);
+          break;
+        case JTokenType.Array:
+          SetToken(JsonToken.StartArray);
+          break;
+        case JTokenType.Constructor:
+          SetToken(JsonToken.StartConstructor);
+          break;
+        case JTokenType.Property:
+          SetToken(JsonToken.PropertyName, ((JProperty)token).Name);
+          break;
+        case JTokenType.Comment:
+          SetToken(JsonToken.Comment, ((JValue)token).Value);
+          break;
+        case JTokenType.Integer:
+          SetToken(JsonToken.Integer, ((JValue)token).Value);
+          break;
+        case JTokenType.Float:
+          SetToken(JsonToken.Float, ((JValue)token).Value);
+          break;
+        case JTokenType.String:
+          SetToken(JsonToken.String, ((JValue)token).Value);
+          break;
+        case JTokenType.Boolean:
+          SetToken(JsonToken.Boolean, ((JValue)token).Value);
+          break;
+        case JTokenType.Null:
+          SetToken(JsonToken.Null, ((JValue)token).Value);
+          break;
+        case JTokenType.Undefined:
+          SetToken(JsonToken.Undefined, ((JValue)token).Value);
+          break;
+        case JTokenType.Date:
+          SetToken(JsonToken.Date, ((JValue)token).Value);
+          break;
+        case JTokenType.Raw:
+          SetToken(JsonToken.Raw, ((JValue)token).Value);
+          break;
+        case JTokenType.Bytes:
+          SetToken(JsonToken.Bytes, ((JValue)token).Value);
+          break;
+        case JTokenType.Guid:
+          SetToken(JsonToken.String, SafeToString(((JValue)token).Value));
+          break;
+        case JTokenType.Uri:
+          SetToken(JsonToken.String, SafeToString(((JValue)token).Value));
+          break;
+        case JTokenType.TimeSpan:
+          SetToken(JsonToken.String, SafeToString(((JValue)token).Value));
+          break;
+        default:
+          throw MiscellaneousUtils.CreateArgumentOutOfRangeException("Type", token.Type, "Unexpected JTokenType.");
+      }
+    }
+
+    private string SafeToString(object value)
+    {
+      return (value != null) ? value.ToString() : null;
+    }
+
+    bool IJsonLineInfo.HasLineInfo()
+    {
+      if (CurrentState == State.Start)
+        return false;
+
+      IJsonLineInfo info = IsEndElement ? null : _current;
+      return (info != null && info.HasLineInfo());
+    }
+
+    int IJsonLineInfo.LineNumber
+    {
+      get
+      {
+        if (CurrentState == State.Start)
+          return 0;
+
+        IJsonLineInfo info = IsEndElement ? null : _current;
+        if (info != null)
+          return info.LineNumber;
+        
+        return 0;
+      }
+    }
+
+    int IJsonLineInfo.LinePosition
+    {
+      get
+      {
+        if (CurrentState == State.Start)
+          return 0;
+
+        IJsonLineInfo info = IsEndElement ? null : _current;
+        if (info != null)
+          return info.LinePosition;
+
+        return 0;
+      }
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JTokenType.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JTokenType.cs
index dafb7e1..20585ba 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JTokenType.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JTokenType.cs
@@ -1,94 +1,106 @@
-#region License
-// 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.
-#endregion
-
-namespace Newtonsoft.Json.Linq
-{
-  /// <summary>
-  /// Specifies the type of token.
-  /// </summary>
-  public enum JTokenType
-  {
-    /// <summary>
-    /// No token type has been set.
-    /// </summary>
-    None,
-    /// <summary>
-    /// A JSON object.
-    /// </summary>
-    Object,
-    /// <summary>
-    /// A JSON array.
-    /// </summary>
-    Array,
-    /// <summary>
-    /// A JSON constructor.
-    /// </summary>
-    Constructor,
-    /// <summary>
-    /// A JSON object property.
-    /// </summary>
-    Property,
-    /// <summary>
-    /// A comment.
-    /// </summary>
-    Comment,
-    /// <summary>
-    /// An integer value.
-    /// </summary>
-    Integer,
-    /// <summary>
-    /// A float value.
-    /// </summary>
-    Float,
-    /// <summary>
-    /// A string value.
-    /// </summary>
-    String,
-    /// <summary>
-    /// A boolean value.
-    /// </summary>
-    Boolean,
-    /// <summary>
-    /// A null value.
-    /// </summary>
-    Null,
-    /// <summary>
-    /// An undefined value.
-    /// </summary>
-    Undefined,
-    /// <summary>
-    /// A date value.
-    /// </summary>
-    Date,
-    /// <summary>
-    /// A raw JSON value.
-    /// </summary>
-    Raw,
-    /// <summary>
-    /// A collection of bytes value.
-    /// </summary>
-    Bytes
-  }
+#region License
+// 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.
+#endregion
+
+namespace Newtonsoft.Json.Linq
+{
+  /// <summary>
+  /// Specifies the type of token.
+  /// </summary>
+  public enum JTokenType
+  {
+    /// <summary>
+    /// No token type has been set.
+    /// </summary>
+    None,
+    /// <summary>
+    /// A JSON object.
+    /// </summary>
+    Object,
+    /// <summary>
+    /// A JSON array.
+    /// </summary>
+    Array,
+    /// <summary>
+    /// A JSON constructor.
+    /// </summary>
+    Constructor,
+    /// <summary>
+    /// A JSON object property.
+    /// </summary>
+    Property,
+    /// <summary>
+    /// A comment.
+    /// </summary>
+    Comment,
+    /// <summary>
+    /// An integer value.
+    /// </summary>
+    Integer,
+    /// <summary>
+    /// A float value.
+    /// </summary>
+    Float,
+    /// <summary>
+    /// A string value.
+    /// </summary>
+    String,
+    /// <summary>
+    /// A boolean value.
+    /// </summary>
+    Boolean,
+    /// <summary>
+    /// A null value.
+    /// </summary>
+    Null,
+    /// <summary>
+    /// An undefined value.
+    /// </summary>
+    Undefined,
+    /// <summary>
+    /// A date value.
+    /// </summary>
+    Date,
+    /// <summary>
+    /// A raw JSON value.
+    /// </summary>
+    Raw,
+    /// <summary>
+    /// A collection of bytes value.
+    /// </summary>
+    Bytes,
+    /// <summary>
+    /// A Guid value.
+    /// </summary>
+    Guid,
+    /// <summary>
+    /// A Uri value.
+    /// </summary>
+    Uri,
+    /// <summary>
+    /// A TimeSpan value.
+    /// </summary>
+    TimeSpan
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JTokenWriter.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JTokenWriter.cs
index ecb208d..b54bdf7 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JTokenWriter.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JTokenWriter.cs
@@ -1,373 +1,433 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Newtonsoft.Json.Utilities;
-
-namespace Newtonsoft.Json.Linq
-{
-  /// <summary>
-  /// Represents a writer that provides a fast, non-cached, forward-only way of generating Json data.
-  /// </summary>
-  public class JTokenWriter : JsonWriter
-  {
-    private JContainer _token;
-    private JContainer _parent;
-    // used when writer is writing single value and the value has no containing parent
-    private JValue _value;
-
-    /// <summary>
-    /// Gets the token being writen.
-    /// </summary>
-    /// <value>The token being writen.</value>
-    public JToken Token
-    {
-      get
-      {
-        if (_token != null)
-          return _token;
-
-        return _value;
-      }
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JTokenWriter"/> class writing to the given <see cref="JContainer"/>.
-    /// </summary>
-    /// <param name="container">The container being written to.</param>
-    public JTokenWriter(JContainer container)
-    {
-      ValidationUtils.ArgumentNotNull(container, "container");
-
-      _token = container;
-      _parent = container;
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JTokenWriter"/> class.
-    /// </summary>
-    public JTokenWriter()
-    {
-    }
-
-    /// <summary>
-    /// Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream.
-    /// </summary>
-    public override void Flush()
-    {
-    }
-
-    /// <summary>
-    /// Closes this stream and the underlying stream.
-    /// </summary>
-    public override void Close()
-    {
-      base.Close();
-    }
-
-    /// <summary>
-    /// Writes the beginning of a Json object.
-    /// </summary>
-    public override void WriteStartObject()
-    {
-      base.WriteStartObject();
-
-      AddParent(new JObject());
-    }
-
-    private void AddParent(JContainer container)
-    {
-      if (_parent == null)
-        _token = container;
-      else
-        _parent.Add(container);
-
-      _parent = container;
-    }
-
-    private void RemoveParent()
-    {
-      _parent = _parent.Parent;
-
-      if (_parent != null && _parent.Type == JTokenType.Property)
-        _parent = _parent.Parent;
-    }
-
-    /// <summary>
-    /// Writes the beginning of a Json array.
-    /// </summary>
-    public override void WriteStartArray()
-    {
-      base.WriteStartArray();
-
-      AddParent(new JArray());
-    }
-
-    /// <summary>
-    /// Writes the start of a constructor with the given name.
-    /// </summary>
-    /// <param name="name">The name of the constructor.</param>
-    public override void WriteStartConstructor(string name)
-    {
-      base.WriteStartConstructor(name);
-
-      AddParent(new JConstructor(name));
-    }
-
-    /// <summary>
-    /// Writes the end.
-    /// </summary>
-    /// <param name="token">The token.</param>
-    protected override void WriteEnd(JsonToken token)
-    {
-      RemoveParent();
-    }
-
-    /// <summary>
-    /// Writes the property name of a name/value pair on a Json object.
-    /// </summary>
-    /// <param name="name">The name of the property.</param>
-    public override void WritePropertyName(string name)
-    {
-      base.WritePropertyName(name);
-
-      AddParent(new JProperty(name));
-    }
-
-    private void AddValue(object value, JsonToken token)
-    {
-      AddValue(new JValue(value), token);
-    }
-
-    internal void AddValue(JValue value, JsonToken token)
-    {
-      if (_parent != null)
-      {
-        _parent.Add(value);
-
-        if (_parent.Type == JTokenType.Property)
-          _parent = _parent.Parent;
-      }
-      else
-      {
-        _value = value;
-      }
-    }
-
-    #region WriteValue methods
-    /// <summary>
-    /// Writes a null value.
-    /// </summary>
-    public override void WriteNull()
-    {
-      base.WriteNull();
-      AddValue(null, JsonToken.Null);
-    }
-
-    /// <summary>
-    /// Writes an undefined value.
-    /// </summary>
-    public override void WriteUndefined()
-    {
-      base.WriteUndefined();
-      AddValue(null, JsonToken.Undefined);
-    }
-
-    /// <summary>
-    /// Writes raw JSON.
-    /// </summary>
-    /// <param name="json">The raw JSON to write.</param>
-    public override void WriteRaw(string json)
-    {
-      base.WriteRaw(json);
-      AddValue(new JRaw(json), JsonToken.Raw);
-    }
-
-    /// <summary>
-    /// Writes out a comment <code>/*...*/</code> containing the specified text.
-    /// </summary>
-    /// <param name="text">Text to place inside the comment.</param>
-    public override void WriteComment(string text)
-    {
-      base.WriteComment(text);
-      AddValue(JValue.CreateComment(text), JsonToken.Comment);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="String"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="String"/> value to write.</param>
-    public override void WriteValue(string value)
-    {
-      base.WriteValue(value);
-      AddValue(value ?? string.Empty, JsonToken.String);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Int32"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Int32"/> value to write.</param>
-    public override void WriteValue(int value)
-    {
-      base.WriteValue(value);
-      AddValue(value, JsonToken.Integer);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="UInt32"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="UInt32"/> value to write.</param>
-    [CLSCompliant(false)]
-    public override void WriteValue(uint value)
-    {
-      base.WriteValue(value);
-      AddValue(value, JsonToken.Integer);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Int64"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Int64"/> value to write.</param>
-    public override void WriteValue(long value)
-    {
-      base.WriteValue(value);
-      AddValue(value, JsonToken.Integer);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="UInt64"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="UInt64"/> value to write.</param>
-    [CLSCompliant(false)]
-    public override void WriteValue(ulong value)
-    {
-      base.WriteValue(value);
-      AddValue(value, JsonToken.Integer);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Single"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Single"/> value to write.</param>
-    public override void WriteValue(float value)
-    {
-      base.WriteValue(value);
-      AddValue(value, JsonToken.Float);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Double"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Double"/> value to write.</param>
-    public override void WriteValue(double value)
-    {
-      base.WriteValue(value);
-      AddValue(value, JsonToken.Float);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Boolean"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Boolean"/> value to write.</param>
-    public override void WriteValue(bool value)
-    {
-      base.WriteValue(value);
-      AddValue(value, JsonToken.Boolean);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Int16"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Int16"/> value to write.</param>
-    public override void WriteValue(short value)
-    {
-      base.WriteValue(value);
-      AddValue(value, JsonToken.Integer);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="UInt16"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="UInt16"/> value to write.</param>
-    [CLSCompliant(false)]
-    public override void WriteValue(ushort value)
-    {
-      base.WriteValue(value);
-      AddValue(value, JsonToken.Integer);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Char"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Char"/> value to write.</param>
-    public override void WriteValue(char value)
-    {
-      base.WriteValue(value);
-      AddValue(value.ToString(), JsonToken.String);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Byte"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Byte"/> value to write.</param>
-    public override void WriteValue(byte value)
-    {
-      base.WriteValue(value);
-      AddValue(value, JsonToken.Integer);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="SByte"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="SByte"/> value to write.</param>
-    [CLSCompliant(false)]
-    public override void WriteValue(sbyte value)
-    {
-      base.WriteValue(value);
-      AddValue(value, JsonToken.Integer);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="Decimal"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="Decimal"/> value to write.</param>
-    public override void WriteValue(decimal value)
-    {
-      base.WriteValue(value);
-      AddValue(value, JsonToken.Float);
-    }
-
-    /// <summary>
-    /// Writes a <see cref="DateTime"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="DateTime"/> value to write.</param>
-    public override void WriteValue(DateTime value)
-    {
-      base.WriteValue(value);
-      AddValue(value, JsonToken.Date);
-    }
-
-#if !PocketPC && !NET20
-    /// <summary>
-    /// Writes a <see cref="DateTimeOffset"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="DateTimeOffset"/> value to write.</param>
-    public override void WriteValue(DateTimeOffset value)
-    {
-      base.WriteValue(value);
-      AddValue(value, JsonToken.Date);
-    }
-#endif
-
-    /// <summary>
-    /// Writes a <see cref="T:Byte[]"/> value.
-    /// </summary>
-    /// <param name="value">The <see cref="T:Byte[]"/> value to write.</param>
-    public override void WriteValue(byte[] value)
-    {
-      base.WriteValue(value);
-      AddValue(value, JsonToken.Bytes);
-    }
-    #endregion
-  }
-}
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Globalization;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Linq
+{
+  /// <summary>
+  /// Represents a writer that provides a fast, non-cached, forward-only way of generating Json data.
+  /// </summary>
+  public class JTokenWriter : JsonWriter
+  {
+    private JContainer _token;
+    private JContainer _parent;
+    // used when writer is writing single value and the value has no containing parent
+    private JValue _value;
+
+    /// <summary>
+    /// Gets the token being writen.
+    /// </summary>
+    /// <value>The token being writen.</value>
+    public JToken Token
+    {
+      get
+      {
+        if (_token != null)
+          return _token;
+
+        return _value;
+      }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JTokenWriter"/> class writing to the given <see cref="JContainer"/>.
+    /// </summary>
+    /// <param name="container">The container being written to.</param>
+    public JTokenWriter(JContainer container)
+    {
+      ValidationUtils.ArgumentNotNull(container, "container");
+
+      _token = container;
+      _parent = container;
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JTokenWriter"/> class.
+    /// </summary>
+    public JTokenWriter()
+    {
+    }
+
+    /// <summary>
+    /// Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream.
+    /// </summary>
+    public override void Flush()
+    {
+    }
+
+    /// <summary>
+    /// Closes this stream and the underlying stream.
+    /// </summary>
+    public override void Close()
+    {
+      base.Close();
+    }
+
+    /// <summary>
+    /// Writes the beginning of a Json object.
+    /// </summary>
+    public override void WriteStartObject()
+    {
+      base.WriteStartObject();
+
+      AddParent(new JObject());
+    }
+
+    private void AddParent(JContainer container)
+    {
+      if (_parent == null)
+        _token = container;
+      else
+        _parent.AddAndSkipParentCheck(container);
+
+      _parent = container;
+    }
+
+    private void RemoveParent()
+    {
+      _parent = _parent.Parent;
+
+      if (_parent != null && _parent.Type == JTokenType.Property)
+        _parent = _parent.Parent;
+    }
+
+    /// <summary>
+    /// Writes the beginning of a Json array.
+    /// </summary>
+    public override void WriteStartArray()
+    {
+      base.WriteStartArray();
+
+      AddParent(new JArray());
+    }
+
+    /// <summary>
+    /// Writes the start of a constructor with the given name.
+    /// </summary>
+    /// <param name="name">The name of the constructor.</param>
+    public override void WriteStartConstructor(string name)
+    {
+      base.WriteStartConstructor(name);
+
+      AddParent(new JConstructor(name));
+    }
+
+    /// <summary>
+    /// Writes the end.
+    /// </summary>
+    /// <param name="token">The token.</param>
+    protected override void WriteEnd(JsonToken token)
+    {
+      RemoveParent();
+    }
+
+    /// <summary>
+    /// Writes the property name of a name/value pair on a Json object.
+    /// </summary>
+    /// <param name="name">The name of the property.</param>
+    public override void WritePropertyName(string name)
+    {
+      base.WritePropertyName(name);
+
+      AddParent(new JProperty(name));
+    }
+
+    private void AddValue(object value, JsonToken token)
+    {
+      AddValue(new JValue(value), token);
+    }
+
+    internal void AddValue(JValue value, JsonToken token)
+    {
+      if (_parent != null)
+      {
+        _parent.Add(value);
+
+        if (_parent.Type == JTokenType.Property)
+          _parent = _parent.Parent;
+      }
+      else
+      {
+        _value = value;
+      }
+    }
+
+    #region WriteValue methods
+    /// <summary>
+    /// Writes a null value.
+    /// </summary>
+    public override void WriteNull()
+    {
+      base.WriteNull();
+      AddValue(null, JsonToken.Null);
+    }
+
+    /// <summary>
+    /// Writes an undefined value.
+    /// </summary>
+    public override void WriteUndefined()
+    {
+      base.WriteUndefined();
+      AddValue(null, JsonToken.Undefined);
+    }
+
+    /// <summary>
+    /// Writes raw JSON.
+    /// </summary>
+    /// <param name="json">The raw JSON to write.</param>
+    public override void WriteRaw(string json)
+    {
+      base.WriteRaw(json);
+      AddValue(new JRaw(json), JsonToken.Raw);
+    }
+
+    /// <summary>
+    /// Writes out a comment <code>/*...*/</code> containing the specified text.
+    /// </summary>
+    /// <param name="text">Text to place inside the comment.</param>
+    public override void WriteComment(string text)
+    {
+      base.WriteComment(text);
+      AddValue(JValue.CreateComment(text), JsonToken.Comment);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="String"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="String"/> value to write.</param>
+    public override void WriteValue(string value)
+    {
+      base.WriteValue(value);
+      AddValue(value ?? string.Empty, JsonToken.String);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Int32"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Int32"/> value to write.</param>
+    public override void WriteValue(int value)
+    {
+      base.WriteValue(value);
+      AddValue(value, JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="UInt32"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="UInt32"/> value to write.</param>
+    [CLSCompliant(false)]
+    public override void WriteValue(uint value)
+    {
+      base.WriteValue(value);
+      AddValue(value, JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Int64"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Int64"/> value to write.</param>
+    public override void WriteValue(long value)
+    {
+      base.WriteValue(value);
+      AddValue(value, JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="UInt64"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="UInt64"/> value to write.</param>
+    [CLSCompliant(false)]
+    public override void WriteValue(ulong value)
+    {
+      base.WriteValue(value);
+      AddValue(value, JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Single"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Single"/> value to write.</param>
+    public override void WriteValue(float value)
+    {
+      base.WriteValue(value);
+      AddValue(value, JsonToken.Float);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Double"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Double"/> value to write.</param>
+    public override void WriteValue(double value)
+    {
+      base.WriteValue(value);
+      AddValue(value, JsonToken.Float);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Boolean"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Boolean"/> value to write.</param>
+    public override void WriteValue(bool value)
+    {
+      base.WriteValue(value);
+      AddValue(value, JsonToken.Boolean);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Int16"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Int16"/> value to write.</param>
+    public override void WriteValue(short value)
+    {
+      base.WriteValue(value);
+      AddValue(value, JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="UInt16"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="UInt16"/> value to write.</param>
+    [CLSCompliant(false)]
+    public override void WriteValue(ushort value)
+    {
+      base.WriteValue(value);
+      AddValue(value, JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Char"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Char"/> value to write.</param>
+    public override void WriteValue(char value)
+    {
+      base.WriteValue(value);
+      string s = null;
+#if !(NETFX_CORE || PORTABLE)
+      s = value.ToString(CultureInfo.InvariantCulture);
+#else
+      s = value.ToString();
+#endif
+      AddValue(s, JsonToken.String);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Byte"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Byte"/> value to write.</param>
+    public override void WriteValue(byte value)
+    {
+      base.WriteValue(value);
+      AddValue(value, JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="SByte"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="SByte"/> value to write.</param>
+    [CLSCompliant(false)]
+    public override void WriteValue(sbyte value)
+    {
+      base.WriteValue(value);
+      AddValue(value, JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Decimal"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Decimal"/> value to write.</param>
+    public override void WriteValue(decimal value)
+    {
+      base.WriteValue(value);
+      AddValue(value, JsonToken.Float);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="DateTime"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="DateTime"/> value to write.</param>
+    public override void WriteValue(DateTime value)
+    {
+      base.WriteValue(value);
+      value = JsonConvert.EnsureDateTime(value, DateTimeZoneHandling);
+      AddValue(value, JsonToken.Date);
+    }
+
+#if !PocketPC && !NET20
+    /// <summary>
+    /// Writes a <see cref="DateTimeOffset"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="DateTimeOffset"/> value to write.</param>
+    public override void WriteValue(DateTimeOffset value)
+    {
+      base.WriteValue(value);
+      AddValue(value, JsonToken.Date);
+    }
+#endif
+
+    /// <summary>
+    /// Writes a <see cref="T:Byte[]"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="T:Byte[]"/> value to write.</param>
+    public override void WriteValue(byte[] value)
+    {
+      base.WriteValue(value);
+      AddValue(value, JsonToken.Bytes);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="TimeSpan"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="TimeSpan"/> value to write.</param>
+    public override void WriteValue(TimeSpan value)
+    {
+      base.WriteValue(value);
+      AddValue(value, JsonToken.String);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Guid"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Guid"/> value to write.</param>
+    public override void WriteValue(Guid value)
+    {
+      base.WriteValue(value);
+      AddValue(value, JsonToken.String);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Uri"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Uri"/> value to write.</param>
+    public override void WriteValue(Uri value)
+    {
+      base.WriteValue(value);
+      AddValue(value, JsonToken.String);
+    }
+    #endregion
+  }
+}
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JValue.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JValue.cs
index 293749f..a164cd4 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JValue.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JValue.cs
@@ -1,398 +1,813 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Newtonsoft.Json.Utilities;
-using System.Globalization;
-
-namespace Newtonsoft.Json.Linq
-{
-  /// <summary>
-  /// Represents a value in JSON (string, integer, date, etc).
-  /// </summary>
-  public class JValue : JToken, IEquatable<JValue>
-  {
-    private JTokenType _valueType;
-    private object _value;
-
-    internal JValue(object value, JTokenType type)
-    {
-      _value = value;
-      _valueType = type;
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JValue"/> class from another <see cref="JValue"/> object.
-    /// </summary>
-    /// <param name="other">A <see cref="JValue"/> object to copy from.</param>
-    public JValue(JValue other)
-      : this(other.Value, other.Type)
-    {
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JValue"/> class with the given value.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    public JValue(long value)
-      : this(value, JTokenType.Integer)
-    {
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JValue"/> class with the given value.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    [CLSCompliant(false)]
-    public JValue(ulong value)
-      : this(value, JTokenType.Integer)
-    {
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JValue"/> class with the given value.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    public JValue(double value)
-      : this(value, JTokenType.Float)
-    {
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JValue"/> class with the given value.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    public JValue(DateTime value)
-      : this(value, JTokenType.Date)
-    {
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JValue"/> class with the given value.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    public JValue(bool value)
-      : this(value, JTokenType.Boolean)
-    {
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JValue"/> class with the given value.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    public JValue(string value)
-      : this(value, JTokenType.String)
-    {
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JValue"/> class with the given value.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    public JValue(object value)
-      : this(value, GetValueType(null, value))
-    {
-    }
-
-    internal override bool DeepEquals(JToken node)
-    {
-      JValue other = node as JValue;
-      if (other == null)
-        return false;
-
-      return ValuesEquals(this, other);
-    }
-
-    /// <summary>
-    /// Gets a value indicating whether this token has childen tokens.
-    /// </summary>
-    /// <value>
-    /// 	<c>true</c> if this token has child values; otherwise, <c>false</c>.
-    /// </value>
-    public override bool HasValues
-    {
-      get { return false; }
-    }
-
-    private static bool Compare(JTokenType valueType, object objA, object objB)
-    {
-      if (objA == null && objB == null)
-        return true;
-      if (objA == null || objB == null)
-        return false;
-
-      switch (valueType)
-      {
-        case JTokenType.Integer:
-          if (objA is ulong || objB is ulong)
-            return Convert.ToDecimal(objA, CultureInfo.InvariantCulture).Equals(Convert.ToDecimal(objB, CultureInfo.InvariantCulture));
-          else
-            return Convert.ToInt64(objA, CultureInfo.InvariantCulture).Equals(Convert.ToInt64(objB, CultureInfo.InvariantCulture));
-        case JTokenType.Float:
-          return Convert.ToDouble(objA, CultureInfo.InvariantCulture).Equals(Convert.ToDouble(objB, CultureInfo.InvariantCulture));
-        case JTokenType.Comment:
-        case JTokenType.String:
-        case JTokenType.Boolean:
-        case JTokenType.Raw:
-          return objA.Equals(objB);
-        case JTokenType.Date:
-          return objA.Equals(objB);
-        case JTokenType.Bytes:
-          byte[] b1 = objA as byte[];
-          byte[] b2 = objB as byte[];
-          if (b1 == null || b2 == null)
-            return false;
-
-          return MiscellaneousUtils.ByteArrayCompare(b1, b2);
-        default:
-          throw MiscellaneousUtils.CreateArgumentOutOfRangeException("valueType", valueType, "Unexpected value type: {0}".FormatWith(CultureInfo.InvariantCulture, valueType));
-      }
-    }
-
-    internal override JToken CloneToken()
-    {
-      return new JValue(this);
-    }
-
-    /// <summary>
-    /// Creates a <see cref="JValue"/> comment with the given value.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    /// <returns>A <see cref="JValue"/> comment with the given value.</returns>
-    public static JValue CreateComment(string value)
-    {
-      return new JValue(value, JTokenType.Comment);
-    }
-
-    /// <summary>
-    /// Creates a <see cref="JValue"/> string with the given value.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    /// <returns>A <see cref="JValue"/> string with the given value.</returns>
-    public static JValue CreateString(string value)
-    {
-      return new JValue(value, JTokenType.String);
-    }
-
-    private static JTokenType GetValueType(JTokenType? current, object value)
-    {
-      if (value == null)
-        return JTokenType.Null;
-      else if (value == DBNull.Value)
-        return JTokenType.Null;
-      else if (value is string)
-        return GetStringValueType(current);
-      else if (value is long || value is int || value is short || value is sbyte
-        || value is ulong || value is uint || value is ushort || value is byte)
-        return JTokenType.Integer;
-      else if (value is Enum)
-        return JTokenType.Integer;
-      else if (value is double || value is float || value is decimal)
-        return JTokenType.Float;
-      else if (value is DateTime)
-        return JTokenType.Date;
-#if !PocketPC && !NET20
-      else if (value is DateTimeOffset)
-        return JTokenType.Date;
-#endif
-      else if (value is byte[])
-        return JTokenType.Bytes;
-      else if (value is bool)
-        return JTokenType.Boolean;
-
-      throw new ArgumentException("Could not determine JSON object type for type {0}.".FormatWith(CultureInfo.InvariantCulture, value.GetType()));
-    }
-
-    private static JTokenType GetStringValueType(JTokenType? current)
-    {
-      if (current == null)
-        return JTokenType.String;
-
-      switch (current.Value)
-      {
-        case JTokenType.Comment:
-        case JTokenType.String:
-        case JTokenType.Raw:
-          return current.Value;
-        default:
-          return JTokenType.String;
-      }
-    }
-
-    /// <summary>
-    /// Gets the node type for this <see cref="JToken"/>.
-    /// </summary>
-    /// <value>The type.</value>
-    public override JTokenType Type
-    {
-      get { return _valueType; }
-    }
-
-    /// <summary>
-    /// Gets or sets the underlying token value.
-    /// </summary>
-    /// <value>The underlying token value.</value>
-    public object Value
-    {
-      get { return _value; }
-      set
-      {
-        Type currentType = (_value != null) ? _value.GetType() : null;
-        Type newType = (value != null) ? value.GetType() : null;
-
-        if (currentType != newType)
-          _valueType = GetValueType(_valueType, value);
-
-        _value = value;
-      }
-    }
-
-    /// <summary>
-    /// Writes this token to a <see cref="JsonWriter"/>.
-    /// </summary>
-    /// <param name="writer">A <see cref="JsonWriter"/> into which this method will write.</param>
-    /// <param name="converters">A collection of <see cref="JsonConverter"/> which will be used when writing the token.</param>
-    public override void WriteTo(JsonWriter writer, params JsonConverter[] converters)
-    {
-      switch (_valueType)
-      {
-        case JTokenType.Comment:
-          writer.WriteComment(_value.ToString());
-          return;
-        case JTokenType.Raw:
-          writer.WriteRawValue((_value != null) ? _value.ToString() : null);
-          return;
-        case JTokenType.Null:
-          writer.WriteNull();
-          return;
-        case JTokenType.Undefined:
-          writer.WriteUndefined();
-          return;
-      }
-
-      JsonConverter matchingConverter;
-      if (_value != null && ((matchingConverter = JsonSerializer.GetMatchingConverter(converters, _value.GetType())) != null))
-      {
-        matchingConverter.WriteJson(writer, _value, new JsonSerializer());
-        return;
-      }
-
-      switch (_valueType)
-      {
-        case JTokenType.Integer:
-          writer.WriteValue(Convert.ToInt64(_value, CultureInfo.InvariantCulture));
-          return;
-        case JTokenType.Float:
-          writer.WriteValue(Convert.ToDouble(_value, CultureInfo.InvariantCulture));
-          return;
-        case JTokenType.String:
-          writer.WriteValue((_value != null) ? _value.ToString() : null);
-          return;
-        case JTokenType.Boolean:
-          writer.WriteValue(Convert.ToBoolean(_value, CultureInfo.InvariantCulture));
-          return;
-        case JTokenType.Date:
-#if !PocketPC && !NET20
-          if (_value is DateTimeOffset)
-            writer.WriteValue((DateTimeOffset)_value);
-          else
-#endif
-            writer.WriteValue(Convert.ToDateTime(_value, CultureInfo.InvariantCulture)); ;
-          return;
-        case JTokenType.Bytes:
-          writer.WriteValue((byte[])_value);
-          return;
-      }
-
-      throw MiscellaneousUtils.CreateArgumentOutOfRangeException("TokenType", _valueType, "Unexpected token type.");
-    }
-
-    internal override int GetDeepHashCode()
-    {
-      int valueHashCode = (_value != null) ? _value.GetHashCode() : 0;
-      
-      return _valueType.GetHashCode() ^ valueHashCode;
-    }
-
-    private static bool ValuesEquals(JValue v1, JValue v2)
-    {
-      return (v1 == v2|| (v1._valueType == v2._valueType && Compare(v1._valueType, v1._value, v2._value)));
-    }
-
-    /// <summary>
-    /// Indicates whether the current object is equal to another object of the same type.
-    /// </summary>
-    /// <returns>
-    /// true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.
-    /// </returns>
-    /// <param name="other">An object to compare with this object.</param>
-    public bool Equals(JValue other)
-    {
-      if (other == null)
-        return false;
-
-      return ValuesEquals(this, other);
-    }
-
-    /// <summary>
-    /// Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>.
-    /// </summary>
-    /// <param name="obj">The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>.</param>
-    /// <returns>
-    /// true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false.
-    /// </returns>
-    /// <exception cref="T:System.NullReferenceException">
-    /// The <paramref name="obj"/> parameter is null.
-    /// </exception>
-    public override bool Equals(object obj)
-    {
-      if (obj == null)
-        return false;
-
-      JValue otherValue = obj as JValue;
-      if (otherValue != null)
-        return Equals(otherValue);
-
-      return base.Equals(obj);
-    }
-
-    /// <summary>
-    /// Serves as a hash function for a particular type.
-    /// </summary>
-    /// <returns>
-    /// A hash code for the current <see cref="T:System.Object"/>.
-    /// </returns>
-    public override int GetHashCode()
-    {
-      if (_value == null)
-        return 0;
-
-      return _value.GetHashCode();
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using Newtonsoft.Json.Utilities;
+using System.Globalization;
+#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
+using System.Dynamic;
+using System.Linq.Expressions;
+#endif
+
+namespace Newtonsoft.Json.Linq
+{
+  /// <summary>
+  /// Represents a value in JSON (string, integer, date, etc).
+  /// </summary>
+  public class JValue : JToken, IEquatable<JValue>, IFormattable, IComparable, IComparable<JValue>
+  {
+    private JTokenType _valueType;
+    private object _value;
+
+    internal JValue(object value, JTokenType type)
+    {
+      _value = value;
+      _valueType = type;
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JValue"/> class from another <see cref="JValue"/> object.
+    /// </summary>
+    /// <param name="other">A <see cref="JValue"/> object to copy from.</param>
+    public JValue(JValue other)
+      : this(other.Value, other.Type)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JValue"/> class with the given value.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    public JValue(long value)
+      : this(value, JTokenType.Integer)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JValue"/> class with the given value.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    [CLSCompliant(false)]
+    public JValue(ulong value)
+      : this(value, JTokenType.Integer)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JValue"/> class with the given value.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    public JValue(double value)
+      : this(value, JTokenType.Float)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JValue"/> class with the given value.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    public JValue(float value)
+      : this(value, JTokenType.Float)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JValue"/> class with the given value.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    public JValue(DateTime value)
+      : this(value, JTokenType.Date)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JValue"/> class with the given value.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    public JValue(bool value)
+      : this(value, JTokenType.Boolean)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JValue"/> class with the given value.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    public JValue(string value)
+      : this(value, JTokenType.String)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JValue"/> class with the given value.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    public JValue(Guid value)
+      : this(value, JTokenType.String)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JValue"/> class with the given value.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    public JValue(Uri value)
+      : this(value, JTokenType.String)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JValue"/> class with the given value.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    public JValue(TimeSpan value)
+      : this(value, JTokenType.String)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JValue"/> class with the given value.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    public JValue(object value)
+      : this(value, GetValueType(null, value))
+    {
+    }
+
+    internal override bool DeepEquals(JToken node)
+    {
+      JValue other = node as JValue;
+      if (other == null)
+        return false;
+      if (other == this)
+        return true;
+
+      return ValuesEquals(this, other);
+    }
+
+    /// <summary>
+    /// Gets a value indicating whether this token has childen tokens.
+    /// </summary>
+    /// <value>
+    /// 	<c>true</c> if this token has child values; otherwise, <c>false</c>.
+    /// </value>
+    public override bool HasValues
+    {
+      get { return false; }
+    }
+
+    private static int Compare(JTokenType valueType, object objA, object objB)
+    {
+      if (objA == null && objB == null)
+        return 0;
+      if (objA != null && objB == null)
+        return 1;
+      if (objA == null && objB != null)
+        return -1;
+
+      switch (valueType)
+      {
+        case JTokenType.Integer:
+          if (objA is ulong || objB is ulong || objA is decimal || objB is decimal)
+            return Convert.ToDecimal(objA, CultureInfo.InvariantCulture).CompareTo(Convert.ToDecimal(objB, CultureInfo.InvariantCulture));
+          else if (objA is float || objB is float || objA is double || objB is double)
+            return CompareFloat(objA, objB);
+          else
+            return Convert.ToInt64(objA, CultureInfo.InvariantCulture).CompareTo(Convert.ToInt64(objB, CultureInfo.InvariantCulture));
+        case JTokenType.Float:
+          return CompareFloat(objA, objB);
+        case JTokenType.Comment:
+        case JTokenType.String:
+        case JTokenType.Raw:
+          string s1 = Convert.ToString(objA, CultureInfo.InvariantCulture);
+          string s2 = Convert.ToString(objB, CultureInfo.InvariantCulture);
+
+          return string.CompareOrdinal(s1, s2);
+        case JTokenType.Boolean:
+          bool b1 = Convert.ToBoolean(objA, CultureInfo.InvariantCulture);
+          bool b2 = Convert.ToBoolean(objB, CultureInfo.InvariantCulture);
+
+          return b1.CompareTo(b2);
+        case JTokenType.Date:
+#if !NET20
+          if (objA is DateTime)
+          {
+#endif
+            DateTime date1 = Convert.ToDateTime(objA, CultureInfo.InvariantCulture);
+            DateTime date2 = Convert.ToDateTime(objB, CultureInfo.InvariantCulture);
+
+            return date1.CompareTo(date2);
+#if !NET20
+          }
+          else
+          {
+            if (!(objB is DateTimeOffset))
+              throw new ArgumentException("Object must be of type DateTimeOffset.");
+
+            DateTimeOffset date1 = (DateTimeOffset) objA;
+            DateTimeOffset date2 = (DateTimeOffset) objB;
+
+            return date1.CompareTo(date2);
+          }
+#endif
+        case JTokenType.Bytes:
+          if (!(objB is byte[]))
+            throw new ArgumentException("Object must be of type byte[].");
+
+          byte[] bytes1 = objA as byte[];
+          byte[] bytes2 = objB as byte[];
+          if (bytes1 == null)
+            return -1;
+          if (bytes2 == null)
+            return 1;
+
+          return MiscellaneousUtils.ByteArrayCompare(bytes1, bytes2);
+        case JTokenType.Guid:
+          if (!(objB is Guid))
+            throw new ArgumentException("Object must be of type Guid.");
+
+          Guid guid1 = (Guid) objA;
+          Guid guid2 = (Guid) objB;
+
+          return guid1.CompareTo(guid2);
+        case JTokenType.Uri:
+          if (!(objB is Uri))
+            throw new ArgumentException("Object must be of type Uri.");
+
+          Uri uri1 = (Uri)objA;
+          Uri uri2 = (Uri)objB;
+
+          return Comparer<string>.Default.Compare(uri1.ToString(), uri2.ToString());
+        case JTokenType.TimeSpan:
+          if (!(objB is TimeSpan))
+            throw new ArgumentException("Object must be of type TimeSpan.");
+
+          TimeSpan ts1 = (TimeSpan)objA;
+          TimeSpan ts2 = (TimeSpan)objB;
+
+          return ts1.CompareTo(ts2);
+        default:
+          throw MiscellaneousUtils.CreateArgumentOutOfRangeException("valueType", valueType, "Unexpected value type: {0}".FormatWith(CultureInfo.InvariantCulture, valueType));
+      }
+    }
+
+    private static int CompareFloat(object objA, object objB)
+    {
+      double d1 = Convert.ToDouble(objA, CultureInfo.InvariantCulture);
+      double d2 = Convert.ToDouble(objB, CultureInfo.InvariantCulture);
+
+      // take into account possible floating point errors
+      if (MathUtils.ApproxEquals(d1, d2))
+        return 0;
+
+      return d1.CompareTo(d2);
+    }
+
+#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
+    private static bool Operation(ExpressionType operation, object objA, object objB, out object result)
+    {
+      if (objA is string || objB is string)
+      {
+        if (operation == ExpressionType.Add || operation == ExpressionType.AddAssign)
+        {
+          result = ((objA != null) ? objA.ToString() : null) + ((objB != null) ? objB.ToString() : null);
+          return true;
+        }
+      }
+
+      if (objA is ulong || objB is ulong || objA is decimal || objB is decimal)
+      {
+        if (objA == null || objB == null)
+        {
+          result = null;
+          return true;
+        }
+
+        decimal d1 = Convert.ToDecimal(objA, CultureInfo.InvariantCulture);
+        decimal d2 = Convert.ToDecimal(objB, CultureInfo.InvariantCulture);
+
+        switch (operation)
+        {
+          case ExpressionType.Add:
+          case ExpressionType.AddAssign:
+            result = d1 + d2;
+            return true;
+          case ExpressionType.Subtract:
+          case ExpressionType.SubtractAssign:
+            result = d1 - d2;
+            return true;
+          case ExpressionType.Multiply:
+          case ExpressionType.MultiplyAssign:
+            result = d1 * d2;
+            return true;
+          case ExpressionType.Divide:
+          case ExpressionType.DivideAssign:
+            result = d1 / d2;
+            return true;
+        }
+      }
+      else if (objA is float || objB is float || objA is double || objB is double)
+      {
+        if (objA == null || objB == null)
+        {
+          result = null;
+          return true;
+        }
+
+        double d1 = Convert.ToDouble(objA, CultureInfo.InvariantCulture);
+        double d2 = Convert.ToDouble(objB, CultureInfo.InvariantCulture);
+
+        switch (operation)
+        {
+          case ExpressionType.Add:
+          case ExpressionType.AddAssign:
+            result = d1 + d2;
+            return true;
+          case ExpressionType.Subtract:
+          case ExpressionType.SubtractAssign:
+            result = d1 - d2;
+            return true;
+          case ExpressionType.Multiply:
+          case ExpressionType.MultiplyAssign:
+            result = d1 * d2;
+            return true;
+          case ExpressionType.Divide:
+          case ExpressionType.DivideAssign:
+            result = d1 / d2;
+            return true;
+        }
+      }
+      else if (objA is int || objA is uint || objA is long || objA is short || objA is ushort || objA is sbyte || objA is byte ||
+        objB is int || objB is uint || objB is long || objB is short || objB is ushort || objB is sbyte || objB is byte)
+      {
+        if (objA == null || objB == null)
+        {
+          result = null;
+          return true;
+        }
+
+        long l1 = Convert.ToInt64(objA, CultureInfo.InvariantCulture);
+        long l2 = Convert.ToInt64(objB, CultureInfo.InvariantCulture);
+
+        switch (operation)
+        {
+          case ExpressionType.Add:
+          case ExpressionType.AddAssign:
+            result = l1 + l2;
+            return true;
+          case ExpressionType.Subtract:
+          case ExpressionType.SubtractAssign:
+            result = l1 - l2;
+            return true;
+          case ExpressionType.Multiply:
+          case ExpressionType.MultiplyAssign:
+            result = l1 * l2;
+            return true;
+          case ExpressionType.Divide:
+          case ExpressionType.DivideAssign:
+            result = l1 / l2;
+            return true;
+        }
+      }
+
+      result = null;
+      return false;
+    }
+#endif
+
+    internal override JToken CloneToken()
+    {
+      return new JValue(this);
+    }
+
+    /// <summary>
+    /// Creates a <see cref="JValue"/> comment with the given value.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>A <see cref="JValue"/> comment with the given value.</returns>
+    public static JValue CreateComment(string value)
+    {
+      return new JValue(value, JTokenType.Comment);
+    }
+
+    /// <summary>
+    /// Creates a <see cref="JValue"/> string with the given value.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>A <see cref="JValue"/> string with the given value.</returns>
+    public static JValue CreateString(string value)
+    {
+      return new JValue(value, JTokenType.String);
+    }
+
+    private static JTokenType GetValueType(JTokenType? current, object value)
+    {
+      if (value == null)
+        return JTokenType.Null;
+#if !(NETFX_CORE || PORTABLE)
+      else if (value == DBNull.Value)
+        return JTokenType.Null;
+#endif
+      else if (value is string)
+        return GetStringValueType(current);
+      else if (value is long || value is int || value is short || value is sbyte
+        || value is ulong || value is uint || value is ushort || value is byte)
+        return JTokenType.Integer;
+      else if (value is Enum)
+        return JTokenType.Integer;
+      else if (value is double || value is float || value is decimal)
+        return JTokenType.Float;
+      else if (value is DateTime)
+        return JTokenType.Date;
+#if !PocketPC && !NET20
+      else if (value is DateTimeOffset)
+        return JTokenType.Date;
+#endif
+      else if (value is byte[])
+        return JTokenType.Bytes;
+      else if (value is bool)
+        return JTokenType.Boolean;
+      else if (value is Guid)
+        return JTokenType.Guid;
+      else if (value is Uri)
+        return JTokenType.Uri;
+      else if (value is TimeSpan)
+        return JTokenType.TimeSpan;
+
+      throw new ArgumentException("Could not determine JSON object type for type {0}.".FormatWith(CultureInfo.InvariantCulture, value.GetType()));
+    }
+
+    private static JTokenType GetStringValueType(JTokenType? current)
+    {
+      if (current == null)
+        return JTokenType.String;
+
+      switch (current.Value)
+      {
+        case JTokenType.Comment:
+        case JTokenType.String:
+        case JTokenType.Raw:
+          return current.Value;
+        default:
+          return JTokenType.String;
+      }
+    }
+
+    /// <summary>
+    /// Gets the node type for this <see cref="JToken"/>.
+    /// </summary>
+    /// <value>The type.</value>
+    public override JTokenType Type
+    {
+      get { return _valueType; }
+    }
+
+    /// <summary>
+    /// Gets or sets the underlying token value.
+    /// </summary>
+    /// <value>The underlying token value.</value>
+    public object Value
+    {
+      get { return _value; }
+      set
+      {
+        Type currentType = (_value != null) ? _value.GetType() : null;
+        Type newType = (value != null) ? value.GetType() : null;
+
+        if (currentType != newType)
+          _valueType = GetValueType(_valueType, value);
+
+        _value = value;
+      }
+    }
+
+    /// <summary>
+    /// Writes this token to a <see cref="JsonWriter"/>.
+    /// </summary>
+    /// <param name="writer">A <see cref="JsonWriter"/> into which this method will write.</param>
+    /// <param name="converters">A collection of <see cref="JsonConverter"/> which will be used when writing the token.</param>
+    public override void WriteTo(JsonWriter writer, params JsonConverter[] converters)
+    {
+      switch (_valueType)
+      {
+        case JTokenType.Comment:
+          writer.WriteComment(_value.ToString());
+          return;
+        case JTokenType.Raw:
+          writer.WriteRawValue((_value != null) ? _value.ToString() : null);
+          return;
+        case JTokenType.Null:
+          writer.WriteNull();
+          return;
+        case JTokenType.Undefined:
+          writer.WriteUndefined();
+          return;
+      }
+
+      JsonConverter matchingConverter;
+      if (_value != null && ((matchingConverter = JsonSerializer.GetMatchingConverter(converters, _value.GetType())) != null))
+      {
+        matchingConverter.WriteJson(writer, _value, new JsonSerializer());
+        return;
+      }
+
+      switch (_valueType)
+      {
+        case JTokenType.Integer:
+          writer.WriteValue(Convert.ToInt64(_value, CultureInfo.InvariantCulture));
+          return;
+        case JTokenType.Float:
+          if (_value is float)
+            writer.WriteValue(_value);
+          else
+            writer.WriteValue(Convert.ToDouble(_value, CultureInfo.InvariantCulture));
+          return;
+        case JTokenType.String:
+          writer.WriteValue((_value != null) ? _value.ToString() : null);
+          return;
+        case JTokenType.Boolean:
+          writer.WriteValue(Convert.ToBoolean(_value, CultureInfo.InvariantCulture));
+          return;
+        case JTokenType.Date:
+#if !PocketPC && !NET20
+          if (_value is DateTimeOffset)
+            writer.WriteValue((DateTimeOffset)_value);
+          else
+#endif
+            writer.WriteValue(Convert.ToDateTime(_value, CultureInfo.InvariantCulture));
+          return;
+        case JTokenType.Bytes:
+          writer.WriteValue((byte[])_value);
+          return;
+        case JTokenType.Guid:
+        case JTokenType.Uri:
+        case JTokenType.TimeSpan:
+          writer.WriteValue((_value != null) ? _value.ToString() : null);
+          return;
+      }
+
+      throw MiscellaneousUtils.CreateArgumentOutOfRangeException("TokenType", _valueType, "Unexpected token type.");
+    }
+
+    internal override int GetDeepHashCode()
+    {
+      int valueHashCode = (_value != null) ? _value.GetHashCode() : 0;
+
+      return _valueType.GetHashCode() ^ valueHashCode;
+    }
+
+    private static bool ValuesEquals(JValue v1, JValue v2)
+    {
+      return (v1 == v2 || (v1._valueType == v2._valueType && Compare(v1._valueType, v1._value, v2._value) == 0));
+    }
+
+    /// <summary>
+    /// Indicates whether the current object is equal to another object of the same type.
+    /// </summary>
+    /// <returns>
+    /// true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.
+    /// </returns>
+    /// <param name="other">An object to compare with this object.</param>
+    public bool Equals(JValue other)
+    {
+      if (other == null)
+        return false;
+
+      return ValuesEquals(this, other);
+    }
+
+    /// <summary>
+    /// Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>.
+    /// </summary>
+    /// <param name="obj">The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>.</param>
+    /// <returns>
+    /// true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false.
+    /// </returns>
+    /// <exception cref="T:System.NullReferenceException">
+    /// The <paramref name="obj"/> parameter is null.
+    /// </exception>
+    public override bool Equals(object obj)
+    {
+      if (obj == null)
+        return false;
+
+      JValue otherValue = obj as JValue;
+      if (otherValue != null)
+        return Equals(otherValue);
+
+      return base.Equals(obj);
+    }
+
+    /// <summary>
+    /// Serves as a hash function for a particular type.
+    /// </summary>
+    /// <returns>
+    /// A hash code for the current <see cref="T:System.Object"/>.
+    /// </returns>
+    public override int GetHashCode()
+    {
+      if (_value == null)
+        return 0;
+
+      return _value.GetHashCode();
+    }
+
+    /// <summary>
+    /// Returns a <see cref="System.String"/> that represents this instance.
+    /// </summary>
+    /// <returns>
+    /// A <see cref="System.String"/> that represents this instance.
+    /// </returns>
+    public override string ToString()
+    {
+      if (_value == null)
+        return string.Empty;
+
+      return _value.ToString();
+    }
+
+    /// <summary>
+    /// Returns a <see cref="System.String"/> that represents this instance.
+    /// </summary>
+    /// <param name="format">The format.</param>
+    /// <returns>
+    /// A <see cref="System.String"/> that represents this instance.
+    /// </returns>
+    public string ToString(string format)
+    {
+      return ToString(format, CultureInfo.CurrentCulture);
+    }
+
+    /// <summary>
+    /// Returns a <see cref="System.String"/> that represents this instance.
+    /// </summary>
+    /// <param name="formatProvider">The format provider.</param>
+    /// <returns>
+    /// A <see cref="System.String"/> that represents this instance.
+    /// </returns>
+    public string ToString(IFormatProvider formatProvider)
+    {
+      return ToString(null, formatProvider);
+    }
+
+    /// <summary>
+    /// Returns a <see cref="System.String"/> that represents this instance.
+    /// </summary>
+    /// <param name="format">The format.</param>
+    /// <param name="formatProvider">The format provider.</param>
+    /// <returns>
+    /// A <see cref="System.String"/> that represents this instance.
+    /// </returns>
+    public string ToString(string format, IFormatProvider formatProvider)
+    {
+      if (_value == null)
+        return string.Empty;
+
+      IFormattable formattable = _value as IFormattable;
+      if (formattable != null)
+        return formattable.ToString(format, formatProvider);
+      else
+        return _value.ToString();
+    }
+
+#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
+    /// <summary>
+    /// Returns the <see cref="T:System.Dynamic.DynamicMetaObject"/> responsible for binding operations performed on this object.
+    /// </summary>
+    /// <param name="parameter">The expression tree representation of the runtime value.</param>
+    /// <returns>
+    /// The <see cref="T:System.Dynamic.DynamicMetaObject"/> to bind this object.
+    /// </returns>
+    protected override DynamicMetaObject GetMetaObject(Expression parameter)
+    {
+      return new DynamicProxyMetaObject<JValue>(parameter, this, new JValueDynamicProxy(), true);
+    }
+
+    private class JValueDynamicProxy : DynamicProxy<JValue>
+    {
+      public override bool TryConvert(JValue instance, ConvertBinder binder, out object result)
+      {
+        if (binder.Type == typeof(JValue))
+        {
+          result = instance;
+          return true;
+        }
+
+        object value = instance.Value;
+
+        if (value == null)
+        {
+          result = null;
+          return ReflectionUtils.IsNullable(binder.Type);
+        }
+
+        result = ConvertUtils.Convert(instance.Value, CultureInfo.InvariantCulture, binder.Type);
+        return true;
+      }
+
+      public override bool TryBinaryOperation(JValue instance, BinaryOperationBinder binder, object arg, out object result)
+      {
+        object compareValue = (arg is JValue) ? ((JValue) arg).Value : arg;
+
+        switch (binder.Operation)
+        {
+          case ExpressionType.Equal:
+            result = (Compare(instance.Type, instance.Value, compareValue) == 0);
+            return true;
+          case ExpressionType.NotEqual:
+            result = (Compare(instance.Type, instance.Value, compareValue) != 0);
+            return true;
+          case ExpressionType.GreaterThan:
+            result = (Compare(instance.Type, instance.Value, compareValue) > 0);
+            return true;
+          case ExpressionType.GreaterThanOrEqual:
+            result = (Compare(instance.Type, instance.Value, compareValue) >= 0);
+            return true;
+          case ExpressionType.LessThan:
+            result = (Compare(instance.Type, instance.Value, compareValue) < 0);
+            return true;
+          case ExpressionType.LessThanOrEqual:
+            result = (Compare(instance.Type, instance.Value, compareValue) <= 0);
+            return true;
+          case ExpressionType.Add:
+          case ExpressionType.AddAssign:
+          case ExpressionType.Subtract:
+          case ExpressionType.SubtractAssign:
+          case ExpressionType.Multiply:
+          case ExpressionType.MultiplyAssign:
+          case ExpressionType.Divide:
+          case ExpressionType.DivideAssign:
+            if (Operation(binder.Operation, instance.Value, compareValue, out result))
+            {
+              result = new JValue(result);
+              return true;
+            }
+            break;
+        }
+
+        result = null;
+        return false;
+      }
+    }
+#endif
+
+    int IComparable.CompareTo(object obj)
+    {
+      if (obj == null)
+        return 1;
+
+      object otherValue = (obj is JValue) ? ((JValue) obj).Value : obj;
+
+      return Compare(_valueType, _value, otherValue);
+    }
+
+    /// <summary>
+    /// Compares the current instance with another object of the same type and returns an integer that indicates whether the current instance precedes, follows, or occurs in the same position in the sort order as the other object.
+    /// </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 objects being compared. The return value has these meanings:
+    /// Value
+    /// Meaning
+    /// Less than zero
+    /// This instance is less than <paramref name="obj"/>.
+    /// Zero
+    /// This instance is equal to <paramref name="obj"/>.
+    /// Greater than zero
+    /// This instance is greater than <paramref name="obj"/>.
+    /// </returns>
+    /// <exception cref="T:System.ArgumentException">
+    /// 	<paramref name="obj"/> is not the same type as this instance.
+    /// </exception>
+    public int CompareTo(JValue obj)
+    {
+      if (obj == null)
+        return 1;
+
+      return Compare(_valueType, _value, obj._value);
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/MemberSerialization.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/MemberSerialization.cs
index 606ae81..909407f 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/MemberSerialization.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/MemberSerialization.cs
@@ -1,47 +1,54 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Newtonsoft.Json
-{
-  /// <summary>
-  /// Specifies the member serialization options for the <see cref="JsonSerializer"/>.
-  /// </summary>
-  public enum MemberSerialization
-  {
-    /// <summary>
-    /// All members are serialized by default. Members can be excluded using the <see cref="JsonIgnoreAttribute"/>.
-    /// </summary>
-    OptOut,
-    /// <summary>
-    /// Only members must be marked with the <see cref="JsonPropertyAttribute"/> are serialized.
-    /// </summary>
-    OptIn
-  }
-}
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Runtime.Serialization;
+using Newtonsoft.Json.Serialization;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Specifies the member serialization options for the <see cref="JsonSerializer"/>.
+  /// </summary>
+  public enum MemberSerialization
+  {
+    /// <summary>
+    /// All public members are serialized by default. Members can be excluded using <see cref="JsonIgnoreAttribute"/> or <see cref="NonSerializedAttribute"/>.
+    /// This is the default member serialization mode.
+    /// </summary>
+    OptOut,
+    /// <summary>
+    /// Only members must be marked with <see cref="JsonPropertyAttribute"/> or <see cref="DataMemberAttribute"/> are serialized.
+    /// This member serialization mode can also be set by marking the class with <see cref="DataContractAttribute"/>.
+    /// </summary>
+    OptIn,
+    /// <summary>
+    /// All public and private fields are serialized. Members can be excluded using <see cref="JsonIgnoreAttribute"/> or <see cref="NonSerializedAttribute"/>.
+    /// This member serialization mode can also be set by marking the class with <see cref="SerializableAttribute"/>
+    /// and setting IgnoreSerializableAttribute on <see cref="DefaultContractResolver"/> to false.
+    /// </summary>
+    Fields
+  }
+}
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/MissingMemberHandling.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/MissingMemberHandling.cs
index c7bd21d..d61e1e6 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/MissingMemberHandling.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/MissingMemberHandling.cs
@@ -1,46 +1,46 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace Newtonsoft.Json
-{
-  /// <summary>
-  /// Specifies missing member handling options for the <see cref="JsonSerializer"/>.
-  /// </summary>
-  public enum MissingMemberHandling
-  {
-    /// <summary>
-    /// Ignore a missing member and do not attempt to deserialize it.
-    /// </summary>
-    Ignore = 0,
-    /// <summary>
-    /// Throw a <see cref="JsonSerializationException"/> when a missing member is encountered during deserialization.
-    /// </summary>
-    Error = 1
-  }
-}
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Specifies missing member handling options for the <see cref="JsonSerializer"/>.
+  /// </summary>
+  public enum MissingMemberHandling
+  {
+    /// <summary>
+    /// Ignore a missing member and do not attempt to deserialize it.
+    /// </summary>
+    Ignore = 0,
+    /// <summary>
+    /// Throw a <see cref="JsonSerializationException"/> when a missing member is encountered during deserialization.
+    /// </summary>
+    Error = 1
+  }
+}
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Newtonsoft.Json.csproj b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Newtonsoft.Json.csproj
index 3b9feba..1e782b1 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Newtonsoft.Json.csproj
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Newtonsoft.Json.csproj
@@ -1,246 +1,277 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>9.0.30729</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Newtonsoft.Json</RootNamespace>
-    <AssemblyName>Newtonsoft.Json</AssemblyName>
-    <SignAssembly>false</SignAssembly>
-    <SccProjectName>
-    </SccProjectName>
-    <SccLocalPath>
-    </SccLocalPath>
-    <SccAuxPath>
-    </SccAuxPath>
-    <SccProvider>
-    </SccProvider>
-    <FileUpgradeFlags>
-    </FileUpgradeFlags>
-    <OldToolsVersion>2.0</OldToolsVersion>
-    <UpgradeBackupLocation>
-    </UpgradeBackupLocation>
-    <PublishUrl>publish\</PublishUrl>
-    <Install>true</Install>
-    <InstallFrom>Disk</InstallFrom>
-    <UpdateEnabled>false</UpdateEnabled>
-    <UpdateMode>Foreground</UpdateMode>
-    <UpdateInterval>7</UpdateInterval>
-    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
-    <UpdatePeriodically>false</UpdatePeriodically>
-    <UpdateRequired>false</UpdateRequired>
-    <MapFileExtensions>true</MapFileExtensions>
-    <ApplicationRevision>0</ApplicationRevision>
-    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
-    <IsWebBootstrapper>false</IsWebBootstrapper>
-    <UseApplicationTrust>false</UseApplicationTrust>
-    <BootstrapperEnabled>true</BootstrapperEnabled>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug\DotNet\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <DocumentationFile>bin\Debug\DotNet\Newtonsoft.Json.xml</DocumentationFile>
-    <RunCodeAnalysis>true</RunCodeAnalysis>
-    <CodeAnalysisRules>-Microsoft.Design#CA1012;-Microsoft.Design#CA2210;-Microsoft.Design#CA1040;-Microsoft.Design#CA1005;-Microsoft.Design#CA1020;-Microsoft.Design#CA1021;-Microsoft.Design#CA1010;-Microsoft.Design#CA1011;-Microsoft.Design#CA1009;-Microsoft.Design#CA1050;-Microsoft.Design#CA1026;-Microsoft.Design#CA1019;-Microsoft.Design#CA1031;-Microsoft.Design#CA1047;-Microsoft.Design#CA1000;-Microsoft.Design#CA1048;-Microsoft.Design#CA1051;-Microsoft.Design#CA1002;-Microsoft.Design#CA1061;-Microsoft.Design#CA1006;-Microsoft.Design#CA1046;-Microsoft.Design#CA1045;-Microsoft.Design#CA1065;-Microsoft.Design#CA1038;-Microsoft.Design#CA1008;-Microsoft.Design#CA1028;-Microsoft.Design#CA1064;-Microsoft.Design#CA1004;-Microsoft.Design#CA1035;-Microsoft.Design#CA1063;-Microsoft.Design#CA1032;-Microsoft.Design#CA1023;-Microsoft.Design#CA1033;-Microsoft.Design#CA1039;-Microsoft.Design#CA1016;-Microsoft.Design#CA1014;-Microsoft.Design#CA1017;-Microsoft.Design#CA1018;-Microsoft.Design#CA1027;-Microsoft.Design#CA1059;-Microsoft.Design#CA1060;-Microsoft.Design#CA1034;-Microsoft.Design#CA1013;-Microsoft.Design#CA1036;-Microsoft.Design#CA1044;-Microsoft.Design#CA1041;-Microsoft.Design#CA1025;-Microsoft.Design#CA1052;-Microsoft.Design#CA1053;-Microsoft.Design#CA1057;-Microsoft.Design#CA1058;-Microsoft.Design#CA1001;-Microsoft.Design#CA1049;-Microsoft.Design#CA1054;-Microsoft.Design#CA1056;-Microsoft.Design#CA1055;-Microsoft.Design#CA1030;-Microsoft.Design#CA1003;-Microsoft.Design#CA1007;-Microsoft.Design#CA1043;-Microsoft.Design#CA1024;-Microsoft.Globalization#CA1301;-Microsoft.Globalization#CA1302;-Microsoft.Globalization#CA1308;-Microsoft.Globalization#CA1306;-Microsoft.Globalization#CA2101;-Microsoft.Globalization#CA1300;-Microsoft.Globalization#CA1307;-Microsoft.Globalization#CA1309;-Microsoft.Interoperability#CA1403;-Microsoft.Interoperability#CA1406;-Microsoft.Interoperability#CA1413;-Microsoft.Interoperability#CA1402;-Microsoft.Interoperability#CA1407;-Microsoft.Interoperability#CA1404;-Microsoft.Interoperability#CA1410;-Microsoft.Interoperability#CA1411;-Microsoft.Interoperability#CA1405;-Microsoft.Interoperability#CA1409;-Microsoft.Interoperability#CA1415;-Microsoft.Interoperability#CA1408;-Microsoft.Interoperability#CA1414;-Microsoft.Interoperability#CA1412;-Microsoft.Interoperability#CA1400;-Microsoft.Interoperability#CA1401;-Microsoft.Maintainability#CA1506;-Microsoft.Maintainability#CA1502;-Microsoft.Maintainability#CA1501;-Microsoft.Maintainability#CA1505;-Microsoft.Maintainability#CA1504;-Microsoft.Maintainability#CA1500;-Microsoft.Mobility#CA1600;-Microsoft.Mobility#CA1601;-Microsoft.Naming#CA1702;-Microsoft.Naming#CA1700;-Microsoft.Naming#CA1712;-Microsoft.Naming#CA1713;-Microsoft.Naming#CA1714;-Microsoft.Naming#CA1709;-Microsoft.Naming#CA1704;-Microsoft.Naming#CA1708;-Microsoft.Naming#CA1715;-Microsoft.Naming#CA1710;-Microsoft.Naming#CA1720;-Microsoft.Naming#CA1707;-Microsoft.Naming#CA1722;-Microsoft.Naming#CA1711;-Microsoft.Naming#CA1716;-Microsoft.Naming#CA1717;-Microsoft.Naming#CA1725;-Microsoft.Naming#CA1719;-Microsoft.Naming#CA1721;-Microsoft.Naming#CA1701;-Microsoft.Naming#CA1703;-Microsoft.Naming#CA1724;-Microsoft.Naming#CA1726;-Microsoft.Performance#CA1809;-Microsoft.Performance#CA1811;-Microsoft.Performance#CA1812;-Microsoft.Performance#CA1813;-Microsoft.Performance#CA1823;-Microsoft.Performance#CA1800;-Microsoft.Performance#CA1805;-Microsoft.Performance#CA1810;-Microsoft.Performance#CA1824;-Microsoft.Performance#CA1822;-Microsoft.Performance#CA1815;-Microsoft.Performance#CA1814;-Microsoft.Performance#CA1819;-Microsoft.Performance#CA1821;-Microsoft.Performance#CA1804;-Microsoft.Performance#CA1820;-Microsoft.Performance#CA1802;-Microsoft.Portability#CA1901;-Microsoft.Portability#CA1900;-Microsoft.Reliability#CA2001;-Microsoft.Reliability#CA2002;-Microsoft.Reliability#CA2003;-Microsoft.Reliability#CA2004;-Microsoft.Reliability#CA2006;-Microsoft.Security#CA2116;-Microsoft.Security#CA2117;-Microsoft.Security#CA2105;-Microsoft.Security#CA2115;-Microsoft.Security#CA2102;-Microsoft.Security#CA2104;-Microsoft.Security#CA2122;-Microsoft.Security#CA2114;-Microsoft.Security#CA2123;-Microsoft.Security#CA2111;-Microsoft.Security#CA2108;-Microsoft.Security#CA2107;-Microsoft.Security#CA2103;-Microsoft.Security#CA2118;-Microsoft.Security#CA2109;-Microsoft.Security#CA2119;-Microsoft.Security#CA2106;-Microsoft.Security#CA2112;-Microsoft.Security#CA2120;-Microsoft.Security#CA2121;-Microsoft.Security#CA2126;-Microsoft.Security#CA2124;-Microsoft.Security#CA2127;-Microsoft.Security#CA2128;-Microsoft.Security#CA2129;-Microsoft.Usage#CA2243;-Microsoft.Usage#CA2236;-Microsoft.Usage#CA1816;-Microsoft.Usage#CA2227;-Microsoft.Usage#CA2213;-Microsoft.Usage#CA2216;-Microsoft.Usage#CA2214;-Microsoft.Usage#CA2222;-Microsoft.Usage#CA1806;-Microsoft.Usage#CA2217;-Microsoft.Usage#CA2212;-Microsoft.Usage#CA2219;-Microsoft.Usage#CA2201;-Microsoft.Usage#CA2228;-Microsoft.Usage#CA2221;-Microsoft.Usage#CA2220;-Microsoft.Usage#CA2240;-Microsoft.Usage#CA2229;-Microsoft.Usage#CA2238;-Microsoft.Usage#CA2207;-Microsoft.Usage#CA2208;-Microsoft.Usage#CA2235;-Microsoft.Usage#CA2237;-Microsoft.Usage#CA2232;-Microsoft.Usage#CA2223;-Microsoft.Usage#CA2211;-Microsoft.Usage#CA2233;-Microsoft.Usage#CA2225;-Microsoft.Usage#CA2226;-Microsoft.Usage#CA2231;-Microsoft.Usage#CA2224;-Microsoft.Usage#CA2218;-Microsoft.Usage#CA2234;-Microsoft.Usage#CA2239;-Microsoft.Usage#CA2200;-Microsoft.Usage#CA1801;-Microsoft.Usage#CA2242;-Microsoft.Usage#CA2205;-Microsoft.Usage#CA2230</CodeAnalysisRules>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release\DotNet\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <DocumentationFile>bin\Release\DotNet\Newtonsoft.Json.xml</DocumentationFile>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="System.Core">
-      <RequiredTargetFramework>3.5</RequiredTargetFramework>
-    </Reference>
-    <Reference Include="System.Data" />
-    <Reference Include="System.Runtime.Serialization">
-      <RequiredTargetFramework>3.0</RequiredTargetFramework>
-    </Reference>
-    <Reference Include="System.Web" />
-    <Reference Include="System.Xml" />
-    <Reference Include="System.Xml.Linq">
-      <RequiredTargetFramework>3.5</RequiredTargetFramework>
-    </Reference>
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="Bson\BsonBinaryType.cs" />
-    <Compile Include="Bson\BsonBinaryWriter.cs" />
-    <Compile Include="Bson\BsonReader.cs" />
-    <Compile Include="Bson\BsonToken.cs" />
-    <Compile Include="Bson\BsonType.cs" />
-    <Compile Include="Bson\BsonWriter.cs" />
-    <Compile Include="Bson\BsonObjectId.cs" />
-    <Compile Include="Converters\BinaryConverter.cs" />
-    <Compile Include="Converters\DataSetConverter.cs" />
-    <Compile Include="Converters\DataTableConverter.cs" />
-    <Compile Include="Converters\CustomCreationConverter.cs" />
-    <Compile Include="Converters\DateTimeConverterBase.cs" />
-    <Compile Include="Converters\EntityKeyMemberConverter.cs" />
-    <Compile Include="Converters\KeyValuePairConverter.cs" />
-    <Compile Include="Converters\BsonObjectIdConverter.cs" />
-    <Compile Include="Converters\RegexConverter.cs" />
-    <Compile Include="Converters\StringEnumConverter.cs" />
-    <Compile Include="ConstructorHandling.cs" />
-    <Compile Include="Linq\JPath.cs" />
-    <Compile Include="Linq\JRaw.cs" />
-    <Compile Include="Required.cs" />
-    <Compile Include="Serialization\JsonFormatterConverter.cs" />
-    <Compile Include="Serialization\JsonISerializableContract.cs" />
-    <Compile Include="Serialization\JsonLinqContract.cs" />
-    <Compile Include="Serialization\JsonPrimitiveContract.cs" />
-    <Compile Include="Serialization\DynamicValueProvider.cs" />
-    <Compile Include="Serialization\ErrorEventArgs.cs" />
-    <Compile Include="Linq\ComponentModel\JPropertyDescriptor.cs" />
-    <Compile Include="Linq\ComponentModel\JTypeDescriptionProvider.cs" />
-    <Compile Include="Linq\ComponentModel\JTypeDescriptor.cs" />
-    <Compile Include="Serialization\DefaultReferenceResolver.cs" />
-    <Compile Include="PreserveReferencesHandling.cs" />
-    <Compile Include="IJsonLineInfo.cs" />
-    <Compile Include="JsonArrayAttribute.cs" />
-    <Compile Include="JsonContainerAttribute.cs" />
-    <Compile Include="DefaultValueHandling.cs" />
-    <Compile Include="JsonConverterAttribute.cs" />
-    <Compile Include="JsonObjectAttribute.cs" />
-    <Compile Include="JsonSerializerSettings.cs" />
-    <Compile Include="JsonValidatingReader.cs" />
-    <Compile Include="Linq\IJEnumerable.cs" />
-    <Compile Include="Linq\JTokenEqualityComparer.cs" />
-    <Compile Include="MemberSerialization.cs" />
-    <Compile Include="ObjectCreationHandling.cs" />
-    <Compile Include="Converters\IsoDateTimeConverter.cs" />
-    <Compile Include="Converters\JavaScriptDateTimeConverter.cs" />
-    <Compile Include="Converters\JsonDateTimeSerializationMode.cs" />
-    <Compile Include="Converters\XmlNodeConverter.cs" />
-    <Compile Include="JsonTextReader.cs" />
-    <Compile Include="JsonPropertyAttribute.cs" />
-    <Compile Include="JsonIgnoreAttribute.cs" />
-    <Compile Include="JsonTextWriter.cs" />
-    <Compile Include="JsonWriterException.cs" />
-    <Compile Include="JsonReaderException.cs" />
-    <Compile Include="JsonConverter.cs" />
-    <Compile Include="JsonConverterCollection.cs" />
-    <Compile Include="JsonReader.cs" />
-    <Compile Include="JsonConvert.cs" />
-    <Compile Include="JsonSerializationException.cs" />
-    <Compile Include="JsonSerializer.cs" />
-    <Compile Include="Linq\Extensions.cs" />
-    <Compile Include="Linq\JConstructor.cs" />
-    <Compile Include="Linq\JContainer.cs" />
-    <Compile Include="Linq\JEnumerable.cs" />
-    <Compile Include="Linq\JObject.cs" />
-    <Compile Include="Linq\JArray.cs" />
-    <Compile Include="Linq\JTokenReader.cs" />
-    <Compile Include="Linq\JTokenWriter.cs" />
-    <Compile Include="Linq\JToken.cs" />
-    <Compile Include="Linq\JProperty.cs" />
-    <Compile Include="Linq\JTokenType.cs" />
-    <Compile Include="Linq\JValue.cs" />
-    <Compile Include="Schema\Extensions.cs" />
-    <Compile Include="Schema\JsonSchemaException.cs" />
-    <Compile Include="Schema\JsonSchemaModel.cs" />
-    <Compile Include="Schema\JsonSchemaModelBuilder.cs" />
-    <Compile Include="Schema\JsonSchemaNodeCollection.cs" />
-    <Compile Include="Schema\JsonSchemaNode.cs" />
-    <Compile Include="Schema\JsonSchemaResolver.cs" />
-    <Compile Include="Schema\JsonSchemaWriter.cs" />
-    <Compile Include="Schema\UndefinedSchemaIdHandling.cs" />
-    <Compile Include="Schema\ValidationEventArgs.cs" />
-    <Compile Include="Schema\ValidationEventHandler.cs" />
-    <Compile Include="Serialization\CamelCasePropertyNamesContractResolver.cs" />
-    <Compile Include="Serialization\DefaultContractResolver.cs" />
-    <Compile Include="Serialization\DefaultSerializationBinder.cs" />
-    <Compile Include="Serialization\ErrorContext.cs" />
-    <Compile Include="Serialization\IContractResolver.cs" />
-    <Compile Include="Serialization\IValueProvider.cs" />
-    <Compile Include="Serialization\JsonArrayContract.cs" />
-    <Compile Include="Serialization\JsonContract.cs" />
-    <Compile Include="Serialization\JsonDictionaryContract.cs" />
-    <Compile Include="Serialization\JsonProperty.cs" />
-    <Compile Include="Serialization\JsonPropertyCollection.cs" />
-    <Compile Include="MissingMemberHandling.cs" />
-    <Compile Include="NullValueHandling.cs" />
-    <Compile Include="ReferenceLoopHandling.cs" />
-    <Compile Include="Schema\JsonSchema.cs" />
-    <Compile Include="Schema\JsonSchemaBuilder.cs" />
-    <Compile Include="Schema\JsonSchemaConstants.cs" />
-    <Compile Include="Schema\JsonSchemaGenerator.cs" />
-    <Compile Include="Serialization\IReferenceResolver.cs" />
-    <Compile Include="Schema\JsonSchemaType.cs" />
-    <Compile Include="Serialization\JsonObjectContract.cs" />
-    <Compile Include="Serialization\JsonSerializerInternalBase.cs" />
-    <Compile Include="Serialization\JsonSerializerInternalReader.cs" />
-    <Compile Include="Serialization\JsonSerializerInternalWriter.cs" />
-    <Compile Include="Serialization\JsonSerializerProxy.cs" />
-    <Compile Include="Serialization\JsonStringContract.cs" />
-    <Compile Include="Serialization\JsonTypeReflector.cs" />
-    <Compile Include="Serialization\CachedAttributeGetter.cs" />
-    <Compile Include="Serialization\LateBoundMetadataTypeAttribute.cs" />
-    <Compile Include="Serialization\ReflectionValueProvider.cs" />
-    <Compile Include="Serialization\OnErrorAttribute.cs" />
-    <Compile Include="Utilities\Base64Encoder.cs" />
-    <Compile Include="Utilities\DynamicWrapper.cs" />
-    <Compile Include="Utilities\DynamicReflectionDelegateFactory.cs" />
-    <Compile Include="Serialization\ObjectConstructor.cs" />
-    <Compile Include="Utilities\ILGeneratorExtensions.cs" />
-    <Compile Include="Utilities\ReflectionDelegateFactory.cs" />
-    <Compile Include="Utilities\LateBoundReflectionDelegateFactory.cs" />
-    <Compile Include="Utilities\MethodCall.cs" />
-    <Compile Include="Utilities\ThreadSafeStore.cs" />
-    <Compile Include="TypeNameHandling.cs" />
-    <Compile Include="Utilities\BidirectionalDictionary.cs" />
-    <Compile Include="Utilities\ConvertUtils.cs" />
-    <Compile Include="Utilities\CollectionWrapper.cs" />
-    <Compile Include="Utilities\DateTimeUtils.cs" />
-    <Compile Include="Utilities\DictionaryWrapper.cs" />
-    <Compile Include="Utilities\EnumUtils.cs" />
-    <Compile Include="Utilities\EnumValue.cs" />
-    <Compile Include="Utilities\EnumValues.cs" />
-    <Compile Include="Utilities\JavaScriptUtils.cs" />
-    <Compile Include="JsonToken.cs" />
-    <Compile Include="JsonWriter.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="Utilities\StringBuffer.cs" />
-    <Compile Include="Utilities\CollectionUtils.cs" />
-    <Compile Include="Utilities\ListWrapper.cs" />
-    <Compile Include="Utilities\MathUtils.cs" />
-    <Compile Include="Utilities\MiscellaneousUtils.cs" />
-    <Compile Include="Utilities\ReflectionUtils.cs" />
-    <Compile Include="Utilities\StringUtils.cs" />
-    <Compile Include="Utilities\ValidationUtils.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
-      <Visible>False</Visible>
-      <ProductName>.NET Framework 2.0 %28x86%29</ProductName>
-      <Install>true</Install>
-    </BootstrapperPackage>
-    <BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
-      <Visible>False</Visible>
-      <ProductName>.NET Framework 3.0 %28x86%29</ProductName>
-      <Install>false</Install>
-    </BootstrapperPackage>
-    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
-      <Visible>False</Visible>
-      <ProductName>.NET Framework 3.5</ProductName>
-      <Install>false</Install>
-    </BootstrapperPackage>
-  </ItemGroup>
-  <ItemGroup>
-    <EmbeddedResource Include="Dynamic.snk" />
-  </ItemGroup>
-  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Newtonsoft.Json</RootNamespace>
+    <AssemblyName>Newtonsoft.Json</AssemblyName>
+    <SignAssembly>false</SignAssembly>
+    <AssemblyOriginatorKeyFile>
+    </AssemblyOriginatorKeyFile>
+    <SccProjectName>
+    </SccProjectName>
+    <SccLocalPath>
+    </SccLocalPath>
+    <SccAuxPath>
+    </SccAuxPath>
+    <SccProvider>
+    </SccProvider>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\Net40\</OutputPath>
+    <DefineConstants>DEBUG;TRACE;NET35</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>bin\Debug\Net40\Newtonsoft.Json.xml</DocumentationFile>
+    <RunCodeAnalysis>true</RunCodeAnalysis>
+    <CodeAnalysisRules>
+    </CodeAnalysisRules>
+    <CodeAnalysisRuleSet>Newtonsoft.Json.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\Net40\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>bin\Release\Net40\Newtonsoft.Json.xml</DocumentationFile>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Runtime.Serialization">
+      <RequiredTargetFramework>3.0</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Xml" />
+    <Reference Include="System.Xml.Linq">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Bson\BsonBinaryType.cs" />
+    <Compile Include="Bson\BsonBinaryWriter.cs" />
+    <Compile Include="Bson\BsonReader.cs" />
+    <Compile Include="Bson\BsonToken.cs" />
+    <Compile Include="Bson\BsonType.cs" />
+    <Compile Include="Bson\BsonWriter.cs" />
+    <Compile Include="Bson\BsonObjectId.cs" />
+    <Compile Include="Converters\BinaryConverter.cs" />
+    <Compile Include="Converters\DataSetConverter.cs" />
+    <Compile Include="Converters\DataTableConverter.cs" />
+    <Compile Include="Converters\CustomCreationConverter.cs" />
+    <Compile Include="Converters\DateTimeConverterBase.cs" />
+    <Compile Include="Converters\EntityKeyMemberConverter.cs" />
+    <Compile Include="Converters\ExpandoObjectConverter.cs" />
+    <Compile Include="Converters\KeyValuePairConverter.cs" />
+    <Compile Include="Converters\BsonObjectIdConverter.cs" />
+    <Compile Include="Converters\RegexConverter.cs" />
+    <Compile Include="Converters\StringEnumConverter.cs" />
+    <Compile Include="ConstructorHandling.cs" />
+    <Compile Include="Converters\VersionConverter.cs" />
+    <Compile Include="JsonDictionaryAttribute.cs" />
+    <Compile Include="JsonException.cs" />
+    <Compile Include="DateFormatHandling.cs" />
+    <Compile Include="DateParseHandling.cs" />
+    <Compile Include="DateTimeZoneHandling.cs" />
+    <Compile Include="Formatting.cs" />
+    <Compile Include="JsonConstructorAttribute.cs" />
+    <Compile Include="JsonPosition.cs" />
+    <Compile Include="Linq\JPropertyKeyedCollection.cs" />
+    <Compile Include="Serialization\JsonContainerContract.cs" />
+    <Compile Include="Utilities\DynamicProxy.cs" />
+    <Compile Include="Linq\JPath.cs" />
+    <Compile Include="Linq\JRaw.cs" />
+    <Compile Include="Required.cs" />
+    <Compile Include="Serialization\JsonDynamicContract.cs" />
+    <Compile Include="Serialization\JsonFormatterConverter.cs" />
+    <Compile Include="Serialization\JsonISerializableContract.cs" />
+    <Compile Include="Serialization\JsonLinqContract.cs" />
+    <Compile Include="Serialization\JsonPrimitiveContract.cs" />
+    <Compile Include="Serialization\DynamicValueProvider.cs" />
+    <Compile Include="Serialization\ErrorEventArgs.cs" />
+    <Compile Include="Linq\JPropertyDescriptor.cs" />
+    <Compile Include="Serialization\DefaultReferenceResolver.cs" />
+    <Compile Include="PreserveReferencesHandling.cs" />
+    <Compile Include="IJsonLineInfo.cs" />
+    <Compile Include="JsonArrayAttribute.cs" />
+    <Compile Include="JsonContainerAttribute.cs" />
+    <Compile Include="DefaultValueHandling.cs" />
+    <Compile Include="JsonConverterAttribute.cs" />
+    <Compile Include="JsonObjectAttribute.cs" />
+    <Compile Include="JsonSerializerSettings.cs" />
+    <Compile Include="JsonValidatingReader.cs" />
+    <Compile Include="Linq\IJEnumerable.cs" />
+    <Compile Include="Linq\JTokenEqualityComparer.cs" />
+    <Compile Include="MemberSerialization.cs" />
+    <Compile Include="ObjectCreationHandling.cs" />
+    <Compile Include="Converters\IsoDateTimeConverter.cs" />
+    <Compile Include="Converters\JavaScriptDateTimeConverter.cs" />
+    <Compile Include="Converters\XmlNodeConverter.cs" />
+    <Compile Include="JsonTextReader.cs" />
+    <Compile Include="JsonPropertyAttribute.cs" />
+    <Compile Include="JsonIgnoreAttribute.cs" />
+    <Compile Include="JsonTextWriter.cs" />
+    <Compile Include="JsonWriterException.cs" />
+    <Compile Include="JsonReaderException.cs" />
+    <Compile Include="JsonConverter.cs" />
+    <Compile Include="JsonConverterCollection.cs" />
+    <Compile Include="JsonReader.cs" />
+    <Compile Include="JsonConvert.cs" />
+    <Compile Include="JsonSerializationException.cs" />
+    <Compile Include="JsonSerializer.cs" />
+    <Compile Include="Linq\Extensions.cs" />
+    <Compile Include="Linq\JConstructor.cs" />
+    <Compile Include="Linq\JContainer.cs" />
+    <Compile Include="Linq\JEnumerable.cs" />
+    <Compile Include="Linq\JObject.cs" />
+    <Compile Include="Linq\JArray.cs" />
+    <Compile Include="Linq\JTokenReader.cs" />
+    <Compile Include="Linq\JTokenWriter.cs" />
+    <Compile Include="Linq\JToken.cs" />
+    <Compile Include="Linq\JProperty.cs" />
+    <Compile Include="Linq\JTokenType.cs" />
+    <Compile Include="Linq\JValue.cs" />
+    <Compile Include="Schema\Extensions.cs" />
+    <Compile Include="Schema\JsonSchemaException.cs" />
+    <Compile Include="Schema\JsonSchemaModel.cs" />
+    <Compile Include="Schema\JsonSchemaModelBuilder.cs" />
+    <Compile Include="Schema\JsonSchemaNodeCollection.cs" />
+    <Compile Include="Schema\JsonSchemaNode.cs" />
+    <Compile Include="Schema\JsonSchemaResolver.cs" />
+    <Compile Include="Schema\JsonSchemaWriter.cs" />
+    <Compile Include="Schema\UndefinedSchemaIdHandling.cs" />
+    <Compile Include="Schema\ValidationEventArgs.cs" />
+    <Compile Include="Schema\ValidationEventHandler.cs" />
+    <Compile Include="Serialization\CamelCasePropertyNamesContractResolver.cs" />
+    <Compile Include="Serialization\DefaultContractResolver.cs" />
+    <Compile Include="Serialization\DefaultSerializationBinder.cs" />
+    <Compile Include="Serialization\ErrorContext.cs" />
+    <Compile Include="Serialization\IContractResolver.cs" />
+    <Compile Include="Serialization\IValueProvider.cs" />
+    <Compile Include="Serialization\JsonArrayContract.cs" />
+    <Compile Include="Serialization\JsonContract.cs" />
+    <Compile Include="Serialization\JsonDictionaryContract.cs" />
+    <Compile Include="Serialization\JsonProperty.cs" />
+    <Compile Include="Serialization\JsonPropertyCollection.cs" />
+    <Compile Include="MissingMemberHandling.cs" />
+    <Compile Include="NullValueHandling.cs" />
+    <Compile Include="ReferenceLoopHandling.cs" />
+    <Compile Include="Schema\JsonSchema.cs" />
+    <Compile Include="Schema\JsonSchemaBuilder.cs" />
+    <Compile Include="Schema\JsonSchemaConstants.cs" />
+    <Compile Include="Schema\JsonSchemaGenerator.cs" />
+    <Compile Include="Serialization\IReferenceResolver.cs" />
+    <Compile Include="Schema\JsonSchemaType.cs" />
+    <Compile Include="Serialization\JsonObjectContract.cs" />
+    <Compile Include="Serialization\JsonSerializerInternalBase.cs" />
+    <Compile Include="Serialization\JsonSerializerInternalReader.cs" />
+    <Compile Include="Serialization\JsonSerializerInternalWriter.cs" />
+    <Compile Include="Serialization\JsonSerializerProxy.cs" />
+    <Compile Include="Serialization\JsonStringContract.cs" />
+    <Compile Include="Serialization\JsonTypeReflector.cs" />
+    <Compile Include="Serialization\CachedAttributeGetter.cs" />
+    <Compile Include="Serialization\LateBoundMetadataTypeAttribute.cs" />
+    <Compile Include="Serialization\ReflectionValueProvider.cs" />
+    <Compile Include="Serialization\OnErrorAttribute.cs" />
+    <Compile Include="Utilities\Base64Encoder.cs" />
+    <Compile Include="Utilities\DynamicProxyMetaObject.cs" />
+    <Compile Include="Utilities\DynamicUtils.cs" />
+    <Compile Include="Utilities\DynamicWrapper.cs" />
+    <Compile Include="Utilities\DynamicReflectionDelegateFactory.cs" />
+    <Compile Include="Serialization\ObjectConstructor.cs" />
+    <Compile Include="Utilities\ILGeneratorExtensions.cs" />
+    <Compile Include="Utilities\ReflectionDelegateFactory.cs" />
+    <Compile Include="Utilities\LateBoundReflectionDelegateFactory.cs" />
+    <Compile Include="Utilities\MethodCall.cs" />
+    <Compile Include="Utilities\StringReference.cs" />
+    <Compile Include="Utilities\ThreadSafeStore.cs" />
+    <Compile Include="TypeNameHandling.cs" />
+    <Compile Include="Utilities\BidirectionalDictionary.cs" />
+    <Compile Include="Utilities\ConvertUtils.cs" />
+    <Compile Include="Utilities\CollectionWrapper.cs" />
+    <Compile Include="Utilities\DateTimeUtils.cs" />
+    <Compile Include="Utilities\DictionaryWrapper.cs" />
+    <Compile Include="Utilities\EnumUtils.cs" />
+    <Compile Include="Utilities\EnumValue.cs" />
+    <Compile Include="Utilities\EnumValues.cs" />
+    <Compile Include="Utilities\JavaScriptUtils.cs" />
+    <Compile Include="JsonToken.cs" />
+    <Compile Include="JsonWriter.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Utilities\StringBuffer.cs" />
+    <Compile Include="Utilities\CollectionUtils.cs" />
+    <Compile Include="Utilities\ListWrapper.cs" />
+    <Compile Include="Utilities\MathUtils.cs" />
+    <Compile Include="Utilities\MiscellaneousUtils.cs" />
+    <Compile Include="Utilities\ReflectionUtils.cs" />
+    <Compile Include="Utilities\StringUtils.cs" />
+    <Compile Include="Utilities\TypeExtensions.cs" />
+    <Compile Include="Utilities\ValidationUtils.cs" />
+    <Compile Include="WriteState.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 2.0 %28x86%29</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.0 %28x86%29</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="Dynamic.snk" />
+  </ItemGroup>
+  <ItemGroup />
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
 </Project>
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/NullValueHandling.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/NullValueHandling.cs
index 8a5d966..08c4f83 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/NullValueHandling.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/NullValueHandling.cs
@@ -1,47 +1,46 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Newtonsoft.Json
-{
-  /// <summary>
-  /// Specifies null value handling options for the <see cref="JsonSerializer"/>.
-  /// </summary>
-  public enum NullValueHandling
-  {
-    /// <summary>
-    /// Include null values when serializing and deserializing objects.
-    /// </summary>
-    Include = 0,
-    /// <summary>
-    /// Ignore null values when serializing and deserializing objects.
-    /// </summary>
-    Ignore = 1
-  }
+#region License
+// 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.
+#endregion
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Specifies null value handling options for the <see cref="JsonSerializer"/>.
+  /// </summary>
+  /// <example>
+  ///   <code lang="cs" source="..\Src\Newtonsoft.Json.Tests\Documentation\SerializationTests.cs" region="ReducingSerializedJsonSizeNullValueHandlingObject" title="NullValueHandling Class" />
+  ///   <code lang="cs" source="..\Src\Newtonsoft.Json.Tests\Documentation\SerializationTests.cs" region="ReducingSerializedJsonSizeNullValueHandlingExample" title="NullValueHandling Ignore Example" />
+  /// </example>
+  public enum NullValueHandling
+  {
+    /// <summary>
+    /// Include null values when serializing and deserializing objects.
+    /// </summary>
+    Include = 0,
+    /// <summary>
+    /// Ignore null values when serializing and deserializing objects.
+    /// </summary>
+    Ignore = 1
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/ObjectCreationHandling.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/ObjectCreationHandling.cs
index c2e9d6e..a3be502 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/ObjectCreationHandling.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/ObjectCreationHandling.cs
@@ -1,51 +1,46 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Newtonsoft.Json
-{
-  /// <summary>
-  /// Specifies how object creation is handled by the <see cref="JsonSerializer"/>.
-  /// </summary>
-  public enum ObjectCreationHandling
-  {
-    /// <summary>
-    /// Reuse existing objects, create new objects when needed.
-    /// </summary>
-    Auto = 0,
-    /// <summary>
-    /// Only reuse existing objects.
-    /// </summary>
-    Reuse = 1,
-    /// <summary>
-    /// Always create new objects.
-    /// </summary>
-    Replace = 2
-  }
+#region License
+// 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.
+#endregion
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Specifies how object creation is handled by the <see cref="JsonSerializer"/>.
+  /// </summary>
+  public enum ObjectCreationHandling
+  {
+    /// <summary>
+    /// Reuse existing objects, create new objects when needed.
+    /// </summary>
+    Auto = 0,
+    /// <summary>
+    /// Only reuse existing objects.
+    /// </summary>
+    Reuse = 1,
+    /// <summary>
+    /// Always create new objects.
+    /// </summary>
+    Replace = 2
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/PreserveReferencesHandling.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/PreserveReferencesHandling.cs
index e374107..cb9f5be 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/PreserveReferencesHandling.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/PreserveReferencesHandling.cs
@@ -1,55 +1,58 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace Newtonsoft.Json
-{
-  /// <summary>
-  /// Specifies reference handling options for the <see cref="JsonSerializer"/>.
-  /// </summary>
-  [Flags]
-  public enum PreserveReferencesHandling
-  {
-    /// <summary>
-    /// Do not preserve references when serializing types.
-    /// </summary>
-    None = 0,
-    /// <summary>
-    /// Preserve references when serializing into a JSON object structure.
-    /// </summary>
-    Objects = 1,
-    /// <summary>
-    /// Preserve references when serializing into a JSON array structure.
-    /// </summary>
-    Arrays = 2,
-    /// <summary>
-    /// Preserve references when serializing.
-    /// </summary>
-    All = Objects | Arrays
-  }
-}
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Specifies reference handling options for the <see cref="JsonSerializer"/>.
+  /// </summary>
+  /// <example>
+  ///   <code lang="cs" source="..\Src\Newtonsoft.Json.Tests\Documentation\SerializationTests.cs" region="PreservingObjectReferencesOn" title="Preserve Object References" />       
+  /// </example>
+  [Flags]
+  public enum PreserveReferencesHandling
+  {
+    /// <summary>
+    /// Do not preserve references when serializing types.
+    /// </summary>
+    None = 0,
+    /// <summary>
+    /// Preserve references when serializing into a JSON object structure.
+    /// </summary>
+    Objects = 1,
+    /// <summary>
+    /// Preserve references when serializing into a JSON array structure.
+    /// </summary>
+    Arrays = 2,
+    /// <summary>
+    /// Preserve references when serializing.
+    /// </summary>
+    All = Objects | Arrays
+  }
+}
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs
index ee62b13..bcfabf8 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs
@@ -1,103 +1,97 @@
-#region License
-// Copyright 2006 James Newton-King
-// http://www.newtonsoft.com
-//
-// This work is licensed under the Creative Commons Attribution 2.5 License
-// http://creativecommons.org/licenses/by/2.5/
-//
-// You are free:
-//    * to copy, distribute, display, and perform the work
-//    * to make derivative works
-//    * to make commercial use of the work
-//
-// Under the following conditions:
-//    * You must attribute the work in the manner specified by the author or licensor:
-//          - If you find this component useful a link to http://www.newtonsoft.com would be appreciated.
-//    * For any reuse or distribution, you must make clear to others the license terms of this work.
-//    * Any of these conditions can be waived if you get permission from the copyright holder.
-#endregion
-
-using System;
-using System.Reflection;
-using System.Runtime.CompilerServices;
-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.
-#if SILVERLIGHT
-[assembly: AssemblyTitle("Newtonsoft Json.NET Silverlight")]
-#elif PocketPC
-[assembly: AssemblyTitle("Newtonsoft Json.NET Compact")]
-#elif NET20
-[assembly: AssemblyTitle("Newtonsoft Json.NET .NET 2.0")]
-[assembly: AllowPartiallyTrustedCallers]
-#else
-[assembly: AssemblyTitle("Newtonsoft Json.NET")]
-[assembly: AllowPartiallyTrustedCallers]
-#endif
-
-#if !SIGNED
-
-#if SILVERLIGHT
-[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests.Silverlight")]
-#elif PocketPC
-[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests.Compact")]
-#elif NET20
-[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests.Net20")]
-#else
-[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests")]
-#endif
-
-#else
-
-#if SILVERLIGHT
-[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests.Silverlight, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")]
-#elif PocketPC
-[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests.Compact, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")]
-#elif NET20
-[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests.Net20, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")]
-#else
-[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")]
-#endif
-
-#endif
-
-
-[assembly: InternalsVisibleTo("Newtonsoft.Json.Dynamic, PublicKey=0024000004800000940000000602000000240000525341310004000001000100cbd8d53b9d7de30f1f1278f636ec462cf9c254991291e66ebb157a885638a517887633b898ccbcf0d5c5ff7be85a6abe9e765d0ac7cd33c68dac67e7e64530e8222101109f154ab14a941c490ac155cd1d4fcba0fabb49016b4ef28593b015cab5937da31172f03f67d09edda404b88a60023f062ae71d0b2e4438b74cc11dc9")]
-
-
-
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("Newtonsoft")]
-[assembly: AssemblyProduct("Newtonsoft Json.NET")]
-[assembly: AssemblyCopyright("Copyright © Newtonsoft 2008")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-
-// Setting ComVisible to false makes the types in this assembly not visible 
-// to COM componenets.  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("9ca358aa-317b-4925-8ada-4a29e943a363")]
-
-// 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("3.5.0.0")]
-#if !PocketPC
-[assembly: AssemblyFileVersion("3.5.0.0")]
-#endif
-
-[assembly: CLSCompliant(true)]
\ No newline at end of file
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+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.
+#if WINDOWS_PHONE
+[assembly: AssemblyTitle("Json.NET Windows Phone")]
+#elif SILVERLIGHT
+[assembly: AssemblyTitle("Json.NET Silverlight")]
+#elif PocketPC
+[assembly: AssemblyTitle("Json.NET Compact")]
+#elif PORTABLE
+[assembly: AssemblyTitle("Json.NET Portable")]
+#elif NETFX_CORE
+[assembly: AssemblyTitle("Json.NET Metro")]
+[assembly: SecurityTransparent]
+#elif NET20
+[assembly: AssemblyTitle("Json.NET .NET 2.0")]
+[assembly: AllowPartiallyTrustedCallers]
+#elif NET35
+[assembly: AssemblyTitle("Json.NET .NET 3.5")]
+[assembly: AllowPartiallyTrustedCallers]
+#else
+[assembly: AssemblyTitle("Json.NET")]
+[assembly: AllowPartiallyTrustedCallers]
+#endif
+
+#if !SIGNED
+[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests")]
+#else
+[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")]
+#endif
+
+[assembly: InternalsVisibleTo("Newtonsoft.Json.Dynamic, PublicKey=0024000004800000940000000602000000240000525341310004000001000100cbd8d53b9d7de30f1f1278f636ec462cf9c254991291e66ebb157a885638a517887633b898ccbcf0d5c5ff7be85a6abe9e765d0ac7cd33c68dac67e7e64530e8222101109f154ab14a941c490ac155cd1d4fcba0fabb49016b4ef28593b015cab5937da31172f03f67d09edda404b88a60023f062ae71d0b2e4438b74cc11dc9")]
+
+[assembly: AssemblyDescription("Json.NET is a popular high-performance JSON framework for .NET")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Newtonsoft")]
+[assembly: AssemblyProduct("Json.NET")]
+[assembly: AssemblyCopyright("Copyright © James Newton-King 2008")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+#if !PORTABLE
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM componenets.  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("9ca358aa-317b-4925-8ada-4a29e943a363")]
+#endif
+
+// 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("4.5.0.0")]
+#if !PocketPC
+[assembly: AssemblyFileVersion("4.5.8.15205")]
+#endif
+
+[assembly: CLSCompliant(true)]
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/ReferenceLoopHandling.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/ReferenceLoopHandling.cs
index 4953b95..01d03b1 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/ReferenceLoopHandling.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/ReferenceLoopHandling.cs
@@ -1,50 +1,50 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace Newtonsoft.Json
-{
-  /// <summary>
-  /// Specifies reference loop handling options for the <see cref="JsonSerializer"/>.
-  /// </summary>
-  public enum ReferenceLoopHandling
-  {
-    /// <summary>
-    /// Throw a <see cref="JsonSerializationException"/> when a loop is encountered.
-    /// </summary>
-    Error = 0,
-    /// <summary>
-    /// Ignore loop references and do not serialize.
-    /// </summary>
-    Ignore = 1,
-    /// <summary>
-    /// Serialize loop references.
-    /// </summary>
-    Serialize = 2
-  }
-}
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Specifies reference loop handling options for the <see cref="JsonSerializer"/>.
+  /// </summary>
+  public enum ReferenceLoopHandling
+  {
+    /// <summary>
+    /// Throw a <see cref="JsonSerializationException"/> when a loop is encountered.
+    /// </summary>
+    Error = 0,
+    /// <summary>
+    /// Ignore loop references and do not serialize.
+    /// </summary>
+    Ignore = 1,
+    /// <summary>
+    /// Serialize loop references.
+    /// </summary>
+    Serialize = 2
+  }
+}
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Required.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Required.cs
index b48ba41..22c86d5 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Required.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Required.cs
@@ -1,21 +1,46 @@
-namespace Newtonsoft.Json
-{
-  /// <summary>
-  /// Indicating whether a property is required.
-  /// </summary>
-  public enum Required
-  {
-    /// <summary>
-    /// The property is not required. The default state.
-    /// </summary>
-    Default,
-    /// <summary>
-    /// The property must be defined in JSON but can be a null value.
-    /// </summary>
-    AllowNull,
-    /// <summary>
-    /// The property must be defined in JSON and cannot be a null value.
-    /// </summary>
-    Always
-  }
+#region License
+// 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.
+#endregion
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Indicating whether a property is required.
+  /// </summary>
+  public enum Required
+  {
+    /// <summary>
+    /// The property is not required. The default state.
+    /// </summary>
+    Default,
+    /// <summary>
+    /// The property must be defined in JSON but can be a null value.
+    /// </summary>
+    AllowNull,
+    /// <summary>
+    /// The property must be defined in JSON and cannot be a null value.
+    /// </summary>
+    Always
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/Extensions.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/Extensions.cs
index 054d42d..04bac5a 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/Extensions.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/Extensions.cs
@@ -1,88 +1,104 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Newtonsoft.Json.Linq;
-using Newtonsoft.Json.Utilities;
-
-namespace Newtonsoft.Json.Schema
-{
-  /// <summary>
-  /// Contains the JSON schema extension methods.
-  /// </summary>
-  public static class Extensions
-  {
-    /// <summary>
-    /// Determines whether the <see cref="JToken"/> is valid.
-    /// </summary>
-    /// <param name="source">The source <see cref="JToken"/> to test.</param>
-    /// <param name="schema">The schema to test with.</param>
-    /// <returns>
-    /// 	<c>true</c> if the specified <see cref="JToken"/> is valid; otherwise, <c>false</c>.
-    /// </returns>
-    public static bool IsValid(this JToken source, JsonSchema schema)
-    {
-      bool valid = true;
-      source.Validate(schema, (sender, args) => { valid = false; });
-      return valid;
-    }
-
-    /// <summary>
-    /// Validates the specified <see cref="JToken"/>.
-    /// </summary>
-    /// <param name="source">The source <see cref="JToken"/> to test.</param>
-    /// <param name="schema">The schema to test with.</param>
-    public static void Validate(this JToken source, JsonSchema schema)
-    {
-      source.Validate(schema, null);
-    }
-
-    /// <summary>
-    /// Validates the specified <see cref="JToken"/>.
-    /// </summary>
-    /// <param name="source">The source <see cref="JToken"/> to test.</param>
-    /// <param name="schema">The schema to test with.</param>
-    /// <param name="validationEventHandler">The validation event handler.</param>
-    public static void Validate(this JToken source, JsonSchema schema, ValidationEventHandler validationEventHandler)
-    {
-      ValidationUtils.ArgumentNotNull(source, "source");
-      ValidationUtils.ArgumentNotNull(schema, "schema");
-
-      using (JsonValidatingReader reader = new JsonValidatingReader(source.CreateReader()))
-      {
-        reader.Schema = schema;
-        if (validationEventHandler != null)
-          reader.ValidationEventHandler += validationEventHandler;
-
-        while (reader.Read())
-        {
-        }
-      }
-    }
-  }
-}
+#region License
+// 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.
+#endregion
+
+using System.Collections.Generic;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Schema
+{
+  /// <summary>
+  /// Contains the JSON schema extension methods.
+  /// </summary>
+  public static class Extensions
+  {
+    /// <summary>
+    /// Determines whether the <see cref="JToken"/> is valid.
+    /// </summary>
+    /// <param name="source">The source <see cref="JToken"/> to test.</param>
+    /// <param name="schema">The schema to test with.</param>
+    /// <returns>
+    /// 	<c>true</c> if the specified <see cref="JToken"/> is valid; otherwise, <c>false</c>.
+    /// </returns>
+    public static bool IsValid(this JToken source, JsonSchema schema)
+    {
+      bool valid = true;
+      source.Validate(schema, (sender, args) => { valid = false; });
+      return valid;
+    }
+
+    /// <summary>
+    /// Determines whether the <see cref="JToken"/> is valid.
+    /// </summary>
+    /// <param name="source">The source <see cref="JToken"/> to test.</param>
+    /// <param name="schema">The schema to test with.</param>
+    /// <param name="errorMessages">When this method returns, contains any error messages generated while validating. </param>
+    /// <returns>
+    /// 	<c>true</c> if the specified <see cref="JToken"/> is valid; otherwise, <c>false</c>.
+    /// </returns>
+    public static bool IsValid(this JToken source, JsonSchema schema, out IList<string> errorMessages)
+    {
+      IList<string> errors = new List<string>();
+
+      source.Validate(schema, (sender, args) => errors.Add(args.Message));
+
+      errorMessages = errors;
+      return (errorMessages.Count == 0);
+    }
+
+    /// <summary>
+    /// Validates the specified <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="source">The source <see cref="JToken"/> to test.</param>
+    /// <param name="schema">The schema to test with.</param>
+    public static void Validate(this JToken source, JsonSchema schema)
+    {
+      source.Validate(schema, null);
+    }
+
+    /// <summary>
+    /// Validates the specified <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="source">The source <see cref="JToken"/> to test.</param>
+    /// <param name="schema">The schema to test with.</param>
+    /// <param name="validationEventHandler">The validation event handler.</param>
+    public static void Validate(this JToken source, JsonSchema schema, ValidationEventHandler validationEventHandler)
+    {
+      ValidationUtils.ArgumentNotNull(source, "source");
+      ValidationUtils.ArgumentNotNull(schema, "schema");
+
+      using (JsonValidatingReader reader = new JsonValidatingReader(source.CreateReader()))
+      {
+        reader.Schema = schema;
+        if (validationEventHandler != null)
+          reader.ValidationEventHandler += validationEventHandler;
+
+        while (reader.Read())
+        {
+        }
+      }
+    }
+  }
+}
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchema.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchema.cs
index eef40c2..d8de6a8 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchema.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchema.cs
@@ -1,284 +1,296 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.IO;
-using Newtonsoft.Json.Linq;
-using Newtonsoft.Json.Utilities;
-using System.Globalization;
-
-namespace Newtonsoft.Json.Schema
-{
-  /// <summary>
-  /// An in-memory representation of a JSON Schema.
-  /// </summary>
-  public class JsonSchema
-  {
-    /// <summary>
-    /// Gets or sets the id.
-    /// </summary>
-    public string Id { get; set; }
-    /// <summary>
-    /// Gets or sets the title.
-    /// </summary>
-    public string Title { get; set; }
-    /// <summary>
-    /// Gets or sets whether the object is optional.
-    /// </summary>
-    public bool? Optional { get; set; }
-    /// <summary>
-    /// Gets or sets whether the object is read only.
-    /// </summary>
-    public bool? ReadOnly { get; set; }
-    /// <summary>
-    /// Gets or sets whether the object is visible to users.
-    /// </summary>
-    public bool? Hidden { get; set; }
-    /// <summary>
-    /// Gets or sets whether the object is transient.
-    /// </summary>
-    public bool? Transient { get; set; }
-    /// <summary>
-    /// Gets or sets the description of the object.
-    /// </summary>
-    public string Description { get; set; }
-    /// <summary>
-    /// Gets or sets the types of values allowed by the object.
-    /// </summary>
-    /// <value>The type.</value>
-    public JsonSchemaType? Type { get; set; }
-    /// <summary>
-    /// Gets or sets the pattern.
-    /// </summary>
-    /// <value>The pattern.</value>
-    public string Pattern { get; set; }
-    /// <summary>
-    /// Gets or sets the minimum length.
-    /// </summary>
-    /// <value>The minimum length.</value>
-    public int? MinimumLength { get; set; }
-    /// <summary>
-    /// Gets or sets the maximum length.
-    /// </summary>
-    /// <value>The maximum length.</value>
-    public int? MaximumLength { get; set; }
-    /// <summary>
-    /// Gets or sets the maximum decimals.
-    /// </summary>
-    /// <value>The maximum decimals.</value>
-    public int? MaximumDecimals { get; set; }
-    /// <summary>
-    /// Gets or sets the minimum.
-    /// </summary>
-    /// <value>The minimum.</value>
-    public double? Minimum { get; set; }
-    /// <summary>
-    /// Gets or sets the maximum.
-    /// </summary>
-    /// <value>The maximum.</value>
-    public double? Maximum { get; set; }
-    /// <summary>
-    /// Gets or sets the minimum number of items.
-    /// </summary>
-    /// <value>The minimum number of items.</value>
-    public int? MinimumItems { get; set; }
-    /// <summary>
-    /// Gets or sets the maximum number of items.
-    /// </summary>
-    /// <value>The maximum number of items.</value>
-    public int? MaximumItems { get; set; }
-    /// <summary>
-    /// Gets or sets the <see cref="JsonSchema"/> of items.
-    /// </summary>
-    /// <value>The <see cref="JsonSchema"/> of items.</value>
-    public IList<JsonSchema> Items { get; set; }
-    /// <summary>
-    /// Gets or sets the <see cref="JsonSchema"/> of properties.
-    /// </summary>
-    /// <value>The <see cref="JsonSchema"/> of properties.</value>
-    public IDictionary<string, JsonSchema> Properties { get; set; }
-    /// <summary>
-    /// Gets or sets the <see cref="JsonSchema"/> of additional properties.
-    /// </summary>
-    /// <value>The <see cref="JsonSchema"/> of additional properties.</value>
-    public JsonSchema AdditionalProperties { get; set; }
-    /// <summary>
-    /// Gets or sets a value indicating whether additional properties are allowed.
-    /// </summary>
-    /// <value>
-    /// 	<c>true</c> if additional properties are allowed; otherwise, <c>false</c>.
-    /// </value>
-    public bool AllowAdditionalProperties { get; set; }
-    /// <summary>
-    /// Gets or sets the required property if this property is present.
-    /// </summary>
-    /// <value>The required property if this property is present.</value>
-    public string Requires { get; set; }
-    /// <summary>
-    /// Gets or sets the identity.
-    /// </summary>
-    /// <value>The identity.</value>
-    public IList<string> Identity { get; set; }
-    /// <summary>
-    /// Gets or sets the a collection of valid enum values allowed.
-    /// </summary>
-    /// <value>A collection of valid enum values allowed.</value>
-    public IList<JToken> Enum { get; set; }
-    /// <summary>
-    /// Gets or sets a collection of options.
-    /// </summary>
-    /// <value>A collection of options.</value>
-    public IDictionary<JToken, string> Options { get; set; }
-    /// <summary>
-    /// Gets or sets disallowed types.
-    /// </summary>
-    /// <value>The disallow types.</value>
-    public JsonSchemaType? Disallow { get; set; }
-    /// <summary>
-    /// Gets or sets the default value.
-    /// </summary>
-    /// <value>The default value.</value>
-    public JToken Default { get; set; }
-    /// <summary>
-    /// Gets or sets the extend <see cref="JsonSchema"/>.
-    /// </summary>
-    /// <value>The extended <see cref="JsonSchema"/>.</value>
-    public JsonSchema Extends { get; set; }
-    /// <summary>
-    /// Gets or sets the format.
-    /// </summary>
-    /// <value>The format.</value>
-    public string Format { get; set; }
-
-    private readonly string _internalId = Guid.NewGuid().ToString("N");
-
-    internal string InternalId
-    {
-      get { return _internalId; }
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonSchema"/> class.
-    /// </summary>
-    public JsonSchema()
-    {
-      AllowAdditionalProperties = true;
-    }
-
-    /// <summary>
-    /// Reads a <see cref="JsonSchema"/> from the specified <see cref="JsonReader"/>.
-    /// </summary>
-    /// <param name="reader">The <see cref="JsonReader"/> containing the JSON Schema to read.</param>
-    /// <returns>The <see cref="JsonSchema"/> object representing the JSON Schema.</returns>
-    public static JsonSchema Read(JsonReader reader)
-    {
-      return Read(reader, new JsonSchemaResolver());
-    }
-
-    /// <summary>
-    /// Reads a <see cref="JsonSchema"/> from the specified <see cref="JsonReader"/>.
-    /// </summary>
-    /// <param name="reader">The <see cref="JsonReader"/> containing the JSON Schema to read.</param>
-    /// <param name="resolver">The <see cref="JsonSchemaResolver"/> to use when resolving schema references.</param>
-    /// <returns>The <see cref="JsonSchema"/> object representing the JSON Schema.</returns>
-    public static JsonSchema Read(JsonReader reader, JsonSchemaResolver resolver)
-    {
-      ValidationUtils.ArgumentNotNull(reader, "reader");
-      ValidationUtils.ArgumentNotNull(resolver, "resolver");
-
-      JsonSchemaBuilder builder = new JsonSchemaBuilder(resolver);
-      return builder.Parse(reader);
-    }
-
-    /// <summary>
-    /// Load a <see cref="JsonSchema"/> from a string that contains schema JSON.
-    /// </summary>
-    /// <param name="json">A <see cref="String"/> that contains JSON.</param>
-    /// <returns>A <see cref="JsonSchema"/> populated from the string that contains JSON.</returns>
-    public static JsonSchema Parse(string json)
-    {
-      return Parse(json, new JsonSchemaResolver());
-    }
-
-    /// <summary>
-    /// Parses the specified json.
-    /// </summary>
-    /// <param name="json">The json.</param>
-    /// <param name="resolver">The resolver.</param>
-    /// <returns>A <see cref="JsonSchema"/> populated from the string that contains JSON.</returns>
-    public static JsonSchema Parse(string json, JsonSchemaResolver resolver)
-    {
-      ValidationUtils.ArgumentNotNull(json, "json");
-
-      JsonReader reader = new JsonTextReader(new StringReader(json));
-
-      return Read(reader, resolver);
-    }
-
-    /// <summary>
-    /// Writes this schema to a <see cref="JsonWriter"/>.
-    /// </summary>
-    /// <param name="writer">A <see cref="JsonWriter"/> into which this method will write.</param>
-    public void WriteTo(JsonWriter writer)
-    {
-      WriteTo(writer, new JsonSchemaResolver());
-    }
-
-    /// <summary>
-    /// Writes this schema to a <see cref="JsonWriter"/> using the specified <see cref="JsonSchemaResolver"/>.
-    /// </summary>
-    /// <param name="writer">A <see cref="JsonWriter"/> into which this method will write.</param>
-    /// <param name="resolver">The resolver used.</param>
-    public void WriteTo(JsonWriter writer, JsonSchemaResolver resolver)
-    {
-      ValidationUtils.ArgumentNotNull(writer, "writer");
-      ValidationUtils.ArgumentNotNull(resolver, "resolver");
-
-      JsonSchemaWriter schemaWriter = new JsonSchemaWriter(writer, resolver);
-      schemaWriter.WriteSchema(this);
-    }
-
-    /// <summary>
-    /// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
-    /// </summary>
-    /// <returns>
-    /// A <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
-    /// </returns>
-    public override string ToString()
-    {
-      StringWriter writer = new StringWriter(CultureInfo.InvariantCulture);
-      JsonTextWriter jsonWriter = new JsonTextWriter(writer);
-      jsonWriter.Formatting = Formatting.Indented;
-
-      WriteTo(jsonWriter);
-
-      return writer.ToString();
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Utilities;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Schema
+{
+  /// <summary>
+  /// An in-memory representation of a JSON Schema.
+  /// </summary>
+  public class JsonSchema
+  {
+    /// <summary>
+    /// Gets or sets the id.
+    /// </summary>
+    public string Id { get; set; }
+    /// <summary>
+    /// Gets or sets the title.
+    /// </summary>
+    public string Title { get; set; }
+    /// <summary>
+    /// Gets or sets whether the object is required.
+    /// </summary>
+    public bool? Required { get; set; }
+    /// <summary>
+    /// Gets or sets whether the object is read only.
+    /// </summary>
+    public bool? ReadOnly { get; set; }
+    /// <summary>
+    /// Gets or sets whether the object is visible to users.
+    /// </summary>
+    public bool? Hidden { get; set; }
+    /// <summary>
+    /// Gets or sets whether the object is transient.
+    /// </summary>
+    public bool? Transient { get; set; }
+    /// <summary>
+    /// Gets or sets the description of the object.
+    /// </summary>
+    public string Description { get; set; }
+    /// <summary>
+    /// Gets or sets the types of values allowed by the object.
+    /// </summary>
+    /// <value>The type.</value>
+    public JsonSchemaType? Type { get; set; }
+    /// <summary>
+    /// Gets or sets the pattern.
+    /// </summary>
+    /// <value>The pattern.</value>
+    public string Pattern { get; set; }
+    /// <summary>
+    /// Gets or sets the minimum length.
+    /// </summary>
+    /// <value>The minimum length.</value>
+    public int? MinimumLength { get; set; }
+    /// <summary>
+    /// Gets or sets the maximum length.
+    /// </summary>
+    /// <value>The maximum length.</value>
+    public int? MaximumLength { get; set; }
+    /// <summary>
+    /// Gets or sets a number that the value should be divisble by.
+    /// </summary>
+    /// <value>A number that the value should be divisble by.</value>
+    public double? DivisibleBy { get; set; }
+    /// <summary>
+    /// Gets or sets the minimum.
+    /// </summary>
+    /// <value>The minimum.</value>
+    public double? Minimum { get; set; }
+    /// <summary>
+    /// Gets or sets the maximum.
+    /// </summary>
+    /// <value>The maximum.</value>
+    public double? Maximum { get; set; }
+    /// <summary>
+    /// Gets or sets a flag indicating whether the value can not equal the number defined by the "minimum" attribute.
+    /// </summary>
+    /// <value>A flag indicating whether the value can not equal the number defined by the "minimum" attribute.</value>
+    public bool? ExclusiveMinimum { get; set; }
+    /// <summary>
+    /// Gets or sets a flag indicating whether the value can not equal the number defined by the "maximum" attribute.
+    /// </summary>
+    /// <value>A flag indicating whether the value can not equal the number defined by the "maximum" attribute.</value>
+    public bool? ExclusiveMaximum { get; set; }
+    /// <summary>
+    /// Gets or sets the minimum number of items.
+    /// </summary>
+    /// <value>The minimum number of items.</value>
+    public int? MinimumItems { get; set; }
+    /// <summary>
+    /// Gets or sets the maximum number of items.
+    /// </summary>
+    /// <value>The maximum number of items.</value>
+    public int? MaximumItems { get; set; }
+    /// <summary>
+    /// Gets or sets the <see cref="JsonSchema"/> of items.
+    /// </summary>
+    /// <value>The <see cref="JsonSchema"/> of items.</value>
+    public IList<JsonSchema> Items { get; set; }
+    /// <summary>
+    /// Gets or sets the <see cref="JsonSchema"/> of properties.
+    /// </summary>
+    /// <value>The <see cref="JsonSchema"/> of properties.</value>
+    public IDictionary<string, JsonSchema> Properties { get; set; }
+    /// <summary>
+    /// Gets or sets the <see cref="JsonSchema"/> of additional properties.
+    /// </summary>
+    /// <value>The <see cref="JsonSchema"/> of additional properties.</value>
+    public JsonSchema AdditionalProperties { get; set; }
+    /// <summary>
+    /// Gets or sets the pattern properties.
+    /// </summary>
+    /// <value>The pattern properties.</value>
+    public IDictionary<string, JsonSchema> PatternProperties { get; set; }
+    /// <summary>
+    /// Gets or sets a value indicating whether additional properties are allowed.
+    /// </summary>
+    /// <value>
+    /// 	<c>true</c> if additional properties are allowed; otherwise, <c>false</c>.
+    /// </value>
+    public bool AllowAdditionalProperties { get; set; }
+    /// <summary>
+    /// Gets or sets the required property if this property is present.
+    /// </summary>
+    /// <value>The required property if this property is present.</value>
+    public string Requires { get; set; }
+    /// <summary>
+    /// Gets or sets the identity.
+    /// </summary>
+    /// <value>The identity.</value>
+    public IList<string> Identity { get; set; }
+    /// <summary>
+    /// Gets or sets the a collection of valid enum values allowed.
+    /// </summary>
+    /// <value>A collection of valid enum values allowed.</value>
+    public IList<JToken> Enum { get; set; }
+    /// <summary>
+    /// Gets or sets a collection of options.
+    /// </summary>
+    /// <value>A collection of options.</value>
+    public IDictionary<JToken, string> Options { get; set; }
+    /// <summary>
+    /// Gets or sets disallowed types.
+    /// </summary>
+    /// <value>The disallow types.</value>
+    public JsonSchemaType? Disallow { get; set; }
+    /// <summary>
+    /// Gets or sets the default value.
+    /// </summary>
+    /// <value>The default value.</value>
+    public JToken Default { get; set; }
+    /// <summary>
+    /// Gets or sets the extend <see cref="JsonSchema"/>.
+    /// </summary>
+    /// <value>The extended <see cref="JsonSchema"/>.</value>
+    public JsonSchema Extends { get; set; }
+    /// <summary>
+    /// Gets or sets the format.
+    /// </summary>
+    /// <value>The format.</value>
+    public string Format { get; set; }
+
+    private readonly string _internalId = Guid.NewGuid().ToString("N");
+
+    internal string InternalId
+    {
+      get { return _internalId; }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonSchema"/> class.
+    /// </summary>
+    public JsonSchema()
+    {
+      AllowAdditionalProperties = true;
+    }
+
+    /// <summary>
+    /// Reads a <see cref="JsonSchema"/> from the specified <see cref="JsonReader"/>.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> containing the JSON Schema to read.</param>
+    /// <returns>The <see cref="JsonSchema"/> object representing the JSON Schema.</returns>
+    public static JsonSchema Read(JsonReader reader)
+    {
+      return Read(reader, new JsonSchemaResolver());
+    }
+
+    /// <summary>
+    /// Reads a <see cref="JsonSchema"/> from the specified <see cref="JsonReader"/>.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> containing the JSON Schema to read.</param>
+    /// <param name="resolver">The <see cref="JsonSchemaResolver"/> to use when resolving schema references.</param>
+    /// <returns>The <see cref="JsonSchema"/> object representing the JSON Schema.</returns>
+    public static JsonSchema Read(JsonReader reader, JsonSchemaResolver resolver)
+    {
+      ValidationUtils.ArgumentNotNull(reader, "reader");
+      ValidationUtils.ArgumentNotNull(resolver, "resolver");
+
+      JsonSchemaBuilder builder = new JsonSchemaBuilder(resolver);
+      return builder.Parse(reader);
+    }
+
+    /// <summary>
+    /// Load a <see cref="JsonSchema"/> from a string that contains schema JSON.
+    /// </summary>
+    /// <param name="json">A <see cref="String"/> that contains JSON.</param>
+    /// <returns>A <see cref="JsonSchema"/> populated from the string that contains JSON.</returns>
+    public static JsonSchema Parse(string json)
+    {
+      return Parse(json, new JsonSchemaResolver());
+    }
+
+    /// <summary>
+    /// Parses the specified json.
+    /// </summary>
+    /// <param name="json">The json.</param>
+    /// <param name="resolver">The resolver.</param>
+    /// <returns>A <see cref="JsonSchema"/> populated from the string that contains JSON.</returns>
+    public static JsonSchema Parse(string json, JsonSchemaResolver resolver)
+    {
+      ValidationUtils.ArgumentNotNull(json, "json");
+
+      JsonReader reader = new JsonTextReader(new StringReader(json));
+
+      return Read(reader, resolver);
+    }
+
+    /// <summary>
+    /// Writes this schema to a <see cref="JsonWriter"/>.
+    /// </summary>
+    /// <param name="writer">A <see cref="JsonWriter"/> into which this method will write.</param>
+    public void WriteTo(JsonWriter writer)
+    {
+      WriteTo(writer, new JsonSchemaResolver());
+    }
+
+    /// <summary>
+    /// Writes this schema to a <see cref="JsonWriter"/> using the specified <see cref="JsonSchemaResolver"/>.
+    /// </summary>
+    /// <param name="writer">A <see cref="JsonWriter"/> into which this method will write.</param>
+    /// <param name="resolver">The resolver used.</param>
+    public void WriteTo(JsonWriter writer, JsonSchemaResolver resolver)
+    {
+      ValidationUtils.ArgumentNotNull(writer, "writer");
+      ValidationUtils.ArgumentNotNull(resolver, "resolver");
+
+      JsonSchemaWriter schemaWriter = new JsonSchemaWriter(writer, resolver);
+      schemaWriter.WriteSchema(this);
+    }
+
+    /// <summary>
+    /// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
+    /// </summary>
+    /// <returns>
+    /// A <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
+    /// </returns>
+    public override string ToString()
+    {
+      StringWriter writer = new StringWriter(CultureInfo.InvariantCulture);
+      JsonTextWriter jsonWriter = new JsonTextWriter(writer);
+      jsonWriter.Formatting = Formatting.Indented;
+
+      WriteTo(jsonWriter);
+
+      return writer.ToString();
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaBuilder.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaBuilder.cs
index 399ff4c..1229a1f 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaBuilder.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaBuilder.cs
@@ -1,393 +1,433 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Globalization;
-using Newtonsoft.Json.Utilities;
-using Newtonsoft.Json.Linq;
-
-namespace Newtonsoft.Json.Schema
-{
-  internal class JsonSchemaBuilder
-  {
-    private JsonReader _reader;
-    private readonly IList<JsonSchema> _stack;
-    private readonly JsonSchemaResolver _resolver;
-    private JsonSchema _currentSchema;
-
-    private void Push(JsonSchema value)
-    {
-      _currentSchema = value;
-      _stack.Add(value);
-      _resolver.LoadedSchemas.Add(value);
-    }
-
-    private JsonSchema Pop()
-    {
-      JsonSchema poppedSchema = _currentSchema;
-      _stack.RemoveAt(_stack.Count - 1);
-      _currentSchema = _stack.LastOrDefault();
-
-      return poppedSchema;
-    }
-
-    private JsonSchema CurrentSchema
-    {
-      get { return _currentSchema; }
-    }
-
-    public JsonSchemaBuilder(JsonSchemaResolver resolver)
-    {
-      _stack = new List<JsonSchema>();
-      _resolver = resolver;
-    }
-
-    internal JsonSchema Parse(JsonReader reader)
-    {
-      _reader = reader;
-
-      if (reader.TokenType == JsonToken.None)
-        _reader.Read();
-
-      return BuildSchema();
-    }
-
-    private JsonSchema BuildSchema()
-    {
-      if (_reader.TokenType != JsonToken.StartObject)
-        throw new Exception("Expected StartObject while parsing schema object, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType));
-
-      _reader.Read();
-      // empty schema object
-      if (_reader.TokenType == JsonToken.EndObject)
-      {
-        Push(new JsonSchema());
-        return Pop();
-      }
-
-      string propertyName = Convert.ToString(_reader.Value, CultureInfo.InvariantCulture);
-      _reader.Read();
-      
-      // schema reference
-      if (propertyName == JsonSchemaConstants.ReferencePropertyName)
-      {
-        string id = (string)_reader.Value;
-        _reader.Read();
-        JsonSchema referencedSchema = _resolver.GetSchema(id);
-        if (referencedSchema == null)
-          throw new Exception("Could not resolve schema reference for Id '{0}'.".FormatWith(CultureInfo.InvariantCulture, id));
-
-        return referencedSchema;
-      }
-
-      // regular ol' schema object
-      Push(new JsonSchema());
-
-      ProcessSchemaProperty(propertyName);
-
-      while (_reader.Read() && _reader.TokenType != JsonToken.EndObject)
-      {
-        propertyName = Convert.ToString(_reader.Value, CultureInfo.InvariantCulture);
-        _reader.Read();
-
-        ProcessSchemaProperty(propertyName);
-      }
-
-      return Pop();
-    }
-
-    private void ProcessSchemaProperty(string propertyName)
-    {
-      switch (propertyName)
-      {
-        case JsonSchemaConstants.TypePropertyName:
-          CurrentSchema.Type = ProcessType();
-          break;
-        case JsonSchemaConstants.IdPropertyName:
-          CurrentSchema.Id = (string) _reader.Value;
-          break;
-        case JsonSchemaConstants.TitlePropertyName:
-          CurrentSchema.Title = (string) _reader.Value;
-          break;
-        case JsonSchemaConstants.DescriptionPropertyName:
-          CurrentSchema.Description = (string)_reader.Value;
-          break;
-        case JsonSchemaConstants.PropertiesPropertyName:
-          ProcessProperties();
-          break;
-        case JsonSchemaConstants.ItemsPropertyName:
-          ProcessItems();
-          break;
-        case JsonSchemaConstants.AdditionalPropertiesPropertyName:
-          ProcessAdditionalProperties();
-          break;
-        case JsonSchemaConstants.OptionalPropertyName:
-          CurrentSchema.Optional = (bool)_reader.Value;
-          break;
-        case JsonSchemaConstants.RequiresPropertyName:
-          CurrentSchema.Requires = (string) _reader.Value;
-          break;
-        case JsonSchemaConstants.IdentityPropertyName:
-          ProcessIdentity();
-          break;
-        case JsonSchemaConstants.MinimumPropertyName:
-          CurrentSchema.Minimum = Convert.ToDouble(_reader.Value, CultureInfo.InvariantCulture);
-          break;
-        case JsonSchemaConstants.MaximumPropertyName:
-          CurrentSchema.Maximum = Convert.ToDouble(_reader.Value, CultureInfo.InvariantCulture);
-          break;
-        case JsonSchemaConstants.MaximumLengthPropertyName:
-          CurrentSchema.MaximumLength = Convert.ToInt32(_reader.Value, CultureInfo.InvariantCulture);
-          break;
-        case JsonSchemaConstants.MinimumLengthPropertyName:
-          CurrentSchema.MinimumLength = Convert.ToInt32(_reader.Value, CultureInfo.InvariantCulture);
-          break;
-        case JsonSchemaConstants.MaximumItemsPropertyName:
-          CurrentSchema.MaximumItems = Convert.ToInt32(_reader.Value, CultureInfo.InvariantCulture);
-          break;
-        case JsonSchemaConstants.MinimumItemsPropertyName:
-          CurrentSchema.MinimumItems = Convert.ToInt32(_reader.Value, CultureInfo.InvariantCulture);
-          break;
-        case JsonSchemaConstants.MaximumDecimalsPropertyName:
-          CurrentSchema.MaximumDecimals = Convert.ToInt32(_reader.Value, CultureInfo.InvariantCulture);
-          break;
-        case JsonSchemaConstants.DisallowPropertyName:
-          CurrentSchema.Disallow = ProcessType();
-          break;
-        case JsonSchemaConstants.DefaultPropertyName:
-          ProcessDefault();
-          break;
-        case JsonSchemaConstants.HiddenPropertyName:
-          CurrentSchema.Hidden = (bool) _reader.Value;
-          break;
-        case JsonSchemaConstants.ReadOnlyPropertyName:
-          CurrentSchema.ReadOnly = (bool) _reader.Value;
-          break;
-        case JsonSchemaConstants.FormatPropertyName:
-          CurrentSchema.Format = (string) _reader.Value;
-          break;
-        case JsonSchemaConstants.PatternPropertyName:
-          CurrentSchema.Pattern = (string) _reader.Value;
-          break;
-        case JsonSchemaConstants.OptionsPropertyName:
-          ProcessOptions();
-          break;
-        case JsonSchemaConstants.EnumPropertyName:
-          ProcessEnum();
-          break;
-        case JsonSchemaConstants.ExtendsPropertyName:
-          ProcessExtends();
-          break;
-        default:
-          _reader.Skip();
-          break;
-      }
-    }
-
-    private void ProcessExtends()
-    {
-      CurrentSchema.Extends = BuildSchema();
-    }
-
-    private void ProcessEnum()
-    {
-      if (_reader.TokenType != JsonToken.StartArray)
-        throw new Exception("Expected StartArray token while parsing enum values, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType));
-
-      CurrentSchema.Enum = new List<JToken>();
-
-      while (_reader.Read() && _reader.TokenType != JsonToken.EndArray)
-      {
-        JToken value = JToken.ReadFrom(_reader);
-        CurrentSchema.Enum.Add(value);
-      }
-    }
-
-    private void ProcessOptions()
-    {
-      CurrentSchema.Options = new Dictionary<JToken, string>(new JTokenEqualityComparer());
-
-      switch (_reader.TokenType)
-      {
-        case JsonToken.StartArray:
-          while (_reader.Read() && _reader.TokenType != JsonToken.EndArray)
-          {
-            if (_reader.TokenType != JsonToken.StartObject)
-              throw new Exception("Expect object token, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType));
-
-            string label = null;
-            JToken value = null;
-
-            while (_reader.Read() && _reader.TokenType != JsonToken.EndObject)
-            {
-              string propertyName = Convert.ToString(_reader.Value, CultureInfo.InvariantCulture);
-              _reader.Read();
-
-              switch (propertyName)
-              {
-                case JsonSchemaConstants.OptionValuePropertyName:
-                  value = JToken.ReadFrom(_reader);
-                  break;
-                case JsonSchemaConstants.OptionLabelPropertyName:
-                  label = (string) _reader.Value;
-                  break;
-                default:
-                  throw new Exception("Unexpected property in JSON schema option: {0}.".FormatWith(CultureInfo.InvariantCulture, propertyName));
-              }
-            }
-
-            if (value == null)
-              throw new Exception("No value specified for JSON schema option.");
-
-            if (CurrentSchema.Options.ContainsKey(value))
-              throw new Exception("Duplicate value in JSON schema option collection: {0}".FormatWith(CultureInfo.InvariantCulture, value));
-
-            CurrentSchema.Options.Add(value, label);
-          }
-          break;
-        default:
-          throw new Exception("Expected array token, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType));
-      }
-    }
-
-    private void ProcessDefault()
-    {
-      CurrentSchema.Default = JToken.ReadFrom(_reader);
-    }
-
-    private void ProcessIdentity()
-    {
-      CurrentSchema.Identity = new List<string>();
-
-      switch (_reader.TokenType)
-      {
-        case JsonToken.String:
-          CurrentSchema.Identity.Add(_reader.Value.ToString());
-          break;
-        case JsonToken.StartArray:
-          while (_reader.Read() && _reader.TokenType != JsonToken.EndArray)
-          {
-            if (_reader.TokenType != JsonToken.String)
-              throw new Exception("Exception JSON property name string token, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType));
-
-            CurrentSchema.Identity.Add(_reader.Value.ToString());
-          }
-          break;
-        default:
-          throw new Exception("Expected array or JSON property name string token, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType));
-      }
-    }
-
-    private void ProcessAdditionalProperties()
-    {
-      if (_reader.TokenType == JsonToken.Boolean)
-        CurrentSchema.AllowAdditionalProperties = (bool)_reader.Value;
-      else
-        CurrentSchema.AdditionalProperties = BuildSchema();
-    }
-
-    private void ProcessItems()
-    {
-      CurrentSchema.Items = new List<JsonSchema>();
-
-      switch (_reader.TokenType)
-      {
-        case JsonToken.StartObject:
-          CurrentSchema.Items.Add(BuildSchema());
-          break;
-        case JsonToken.StartArray:
-          while (_reader.Read() && _reader.TokenType != JsonToken.EndArray)
-          {
-            CurrentSchema.Items.Add(BuildSchema());
-          }
-          break;
-        default:
-          throw new Exception("Expected array or JSON schema object token, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType));
-      }
-    }
-
-    private void ProcessProperties()
-    {
-      IDictionary<string, JsonSchema> properties = new Dictionary<string, JsonSchema>();
-
-      if (_reader.TokenType != JsonToken.StartObject)
-        throw new Exception("Expected StartObject token while parsing schema properties, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType));
-
-      while (_reader.Read() && _reader.TokenType != JsonToken.EndObject)
-      {
-        string propertyName = Convert.ToString(_reader.Value, CultureInfo.InvariantCulture);
-        _reader.Read();
-
-        if (properties.ContainsKey(propertyName))
-          throw new Exception("Property {0} has already been defined in schema.".FormatWith(CultureInfo.InvariantCulture, propertyName));
-
-        properties.Add(propertyName, BuildSchema());
-      }
-
-      CurrentSchema.Properties = properties;
-    }
-
-    private JsonSchemaType? ProcessType()
-    {
-      switch (_reader.TokenType)
-      {
-        case JsonToken.String:
-          return MapType(_reader.Value.ToString());
-        case JsonToken.StartArray:
-          // ensure type is in blank state before ORing values
-          JsonSchemaType? type = JsonSchemaType.None;
-
-          while (_reader.Read() && _reader.TokenType != JsonToken.EndArray)
-          {
-            if (_reader.TokenType != JsonToken.String)
-              throw new Exception("Exception JSON schema type string token, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType));
-
-            type = type | MapType(_reader.Value.ToString());
-          }
-
-          return type;
-        default:
-          throw new Exception("Expected array or JSON schema type string token, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType));
-      }
-    }
-
-    internal static JsonSchemaType MapType(string type)
-    {
-      JsonSchemaType mappedType;
-      if (!JsonSchemaConstants.JsonSchemaTypeMapping.TryGetValue(type, out mappedType))
-        throw new Exception("Invalid JSON schema type: {0}".FormatWith(CultureInfo.InvariantCulture, type));
-
-      return mappedType;
-    }
-
-    internal static string MapType(JsonSchemaType type)
-    {
-      return JsonSchemaConstants.JsonSchemaTypeMapping.Single(kv => kv.Value == type).Key;
-    }
-  }
-}
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#else
+using System.Linq;
+#endif
+using System.Globalization;
+using Newtonsoft.Json.Utilities;
+using Newtonsoft.Json.Linq;
+
+namespace Newtonsoft.Json.Schema
+{
+  internal class JsonSchemaBuilder
+  {
+    private JsonReader _reader;
+    private readonly IList<JsonSchema> _stack;
+    private readonly JsonSchemaResolver _resolver;
+    private JsonSchema _currentSchema;
+
+    private void Push(JsonSchema value)
+    {
+      _currentSchema = value;
+      _stack.Add(value);
+      _resolver.LoadedSchemas.Add(value);
+    }
+
+    private JsonSchema Pop()
+    {
+      JsonSchema poppedSchema = _currentSchema;
+      _stack.RemoveAt(_stack.Count - 1);
+      _currentSchema = _stack.LastOrDefault();
+
+      return poppedSchema;
+    }
+
+    private JsonSchema CurrentSchema
+    {
+      get { return _currentSchema; }
+    }
+
+    public JsonSchemaBuilder(JsonSchemaResolver resolver)
+    {
+      _stack = new List<JsonSchema>();
+      _resolver = resolver;
+    }
+
+    internal JsonSchema Parse(JsonReader reader)
+    {
+      _reader = reader;
+
+      if (reader.TokenType == JsonToken.None)
+        _reader.Read();
+
+      return BuildSchema();
+    }
+
+    private JsonSchema BuildSchema()
+    {
+      if (_reader.TokenType != JsonToken.StartObject)
+        throw JsonReaderException.Create(_reader, "Expected StartObject while parsing schema object, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType));
+
+      _reader.Read();
+      // empty schema object
+      if (_reader.TokenType == JsonToken.EndObject)
+      {
+        Push(new JsonSchema());
+        return Pop();
+      }
+
+      string propertyName = Convert.ToString(_reader.Value, CultureInfo.InvariantCulture);
+      _reader.Read();
+      
+      // schema reference
+      if (propertyName == JsonSchemaConstants.ReferencePropertyName)
+      {
+        string id = (string)_reader.Value;
+
+        // skip to the end of the current object
+        while (_reader.Read() && _reader.TokenType != JsonToken.EndObject)
+        {
+            if (_reader.TokenType == JsonToken.StartObject)
+              throw JsonReaderException.Create(_reader, "Found StartObject within the schema reference with the Id '{0}'".FormatWith(CultureInfo.InvariantCulture, id));
+        }
+
+        JsonSchema referencedSchema = _resolver.GetSchema(id);
+        if (referencedSchema == null)
+          throw new JsonException("Could not resolve schema reference for Id '{0}'.".FormatWith(CultureInfo.InvariantCulture, id));
+
+        return referencedSchema;
+      }
+
+      // regular ol' schema object
+      Push(new JsonSchema());
+
+      ProcessSchemaProperty(propertyName);
+
+      while (_reader.Read() && _reader.TokenType != JsonToken.EndObject)
+      {
+        propertyName = Convert.ToString(_reader.Value, CultureInfo.InvariantCulture);
+        _reader.Read();
+
+        ProcessSchemaProperty(propertyName);
+      }
+
+      return Pop();
+    }
+
+    private void ProcessSchemaProperty(string propertyName)
+    {
+      switch (propertyName)
+      {
+        case JsonSchemaConstants.TypePropertyName:
+          CurrentSchema.Type = ProcessType();
+          break;
+        case JsonSchemaConstants.IdPropertyName:
+          CurrentSchema.Id = (string) _reader.Value;
+          break;
+        case JsonSchemaConstants.TitlePropertyName:
+          CurrentSchema.Title = (string) _reader.Value;
+          break;
+        case JsonSchemaConstants.DescriptionPropertyName:
+          CurrentSchema.Description = (string)_reader.Value;
+          break;
+        case JsonSchemaConstants.PropertiesPropertyName:
+          ProcessProperties();
+          break;
+        case JsonSchemaConstants.ItemsPropertyName:
+          ProcessItems();
+          break;
+        case JsonSchemaConstants.AdditionalPropertiesPropertyName:
+          ProcessAdditionalProperties();
+          break;
+        case JsonSchemaConstants.PatternPropertiesPropertyName:
+          ProcessPatternProperties();
+          break;
+        case JsonSchemaConstants.RequiredPropertyName:
+          CurrentSchema.Required = (bool)_reader.Value;
+          break;
+        case JsonSchemaConstants.RequiresPropertyName:
+          CurrentSchema.Requires = (string) _reader.Value;
+          break;
+        case JsonSchemaConstants.IdentityPropertyName:
+          ProcessIdentity();
+          break;
+        case JsonSchemaConstants.MinimumPropertyName:
+          CurrentSchema.Minimum = Convert.ToDouble(_reader.Value, CultureInfo.InvariantCulture);
+          break;
+        case JsonSchemaConstants.MaximumPropertyName:
+          CurrentSchema.Maximum = Convert.ToDouble(_reader.Value, CultureInfo.InvariantCulture);
+          break;
+        case JsonSchemaConstants.ExclusiveMinimumPropertyName:
+          CurrentSchema.ExclusiveMinimum = (bool)_reader.Value;
+          break;
+        case JsonSchemaConstants.ExclusiveMaximumPropertyName:
+          CurrentSchema.ExclusiveMaximum = (bool)_reader.Value;
+          break;
+        case JsonSchemaConstants.MaximumLengthPropertyName:
+          CurrentSchema.MaximumLength = Convert.ToInt32(_reader.Value, CultureInfo.InvariantCulture);
+          break;
+        case JsonSchemaConstants.MinimumLengthPropertyName:
+          CurrentSchema.MinimumLength = Convert.ToInt32(_reader.Value, CultureInfo.InvariantCulture);
+          break;
+        case JsonSchemaConstants.MaximumItemsPropertyName:
+          CurrentSchema.MaximumItems = Convert.ToInt32(_reader.Value, CultureInfo.InvariantCulture);
+          break;
+        case JsonSchemaConstants.MinimumItemsPropertyName:
+          CurrentSchema.MinimumItems = Convert.ToInt32(_reader.Value, CultureInfo.InvariantCulture);
+          break;
+        case JsonSchemaConstants.DivisibleByPropertyName:
+          CurrentSchema.DivisibleBy = Convert.ToDouble(_reader.Value, CultureInfo.InvariantCulture);
+          break;
+        case JsonSchemaConstants.DisallowPropertyName:
+          CurrentSchema.Disallow = ProcessType();
+          break;
+        case JsonSchemaConstants.DefaultPropertyName:
+          ProcessDefault();
+          break;
+        case JsonSchemaConstants.HiddenPropertyName:
+          CurrentSchema.Hidden = (bool) _reader.Value;
+          break;
+        case JsonSchemaConstants.ReadOnlyPropertyName:
+          CurrentSchema.ReadOnly = (bool) _reader.Value;
+          break;
+        case JsonSchemaConstants.FormatPropertyName:
+          CurrentSchema.Format = (string) _reader.Value;
+          break;
+        case JsonSchemaConstants.PatternPropertyName:
+          CurrentSchema.Pattern = (string) _reader.Value;
+          break;
+        case JsonSchemaConstants.OptionsPropertyName:
+          ProcessOptions();
+          break;
+        case JsonSchemaConstants.EnumPropertyName:
+          ProcessEnum();
+          break;
+        case JsonSchemaConstants.ExtendsPropertyName:
+          ProcessExtends();
+          break;
+        default:
+          _reader.Skip();
+          break;
+      }
+    }
+
+    private void ProcessExtends()
+    {
+      CurrentSchema.Extends = BuildSchema();
+    }
+
+    private void ProcessEnum()
+    {
+      if (_reader.TokenType != JsonToken.StartArray)
+        throw JsonReaderException.Create(_reader, "Expected StartArray token while parsing enum values, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType));
+
+      CurrentSchema.Enum = new List<JToken>();
+
+      while (_reader.Read() && _reader.TokenType != JsonToken.EndArray)
+      {
+        JToken value = JToken.ReadFrom(_reader);
+        CurrentSchema.Enum.Add(value);
+      }
+    }
+
+    private void ProcessOptions()
+    {
+      CurrentSchema.Options = new Dictionary<JToken, string>(new JTokenEqualityComparer());
+
+      switch (_reader.TokenType)
+      {
+        case JsonToken.StartArray:
+          while (_reader.Read() && _reader.TokenType != JsonToken.EndArray)
+          {
+            if (_reader.TokenType != JsonToken.StartObject)
+              throw JsonReaderException.Create(_reader, "Expect object token, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType));
+
+            string label = null;
+            JToken value = null;
+
+            while (_reader.Read() && _reader.TokenType != JsonToken.EndObject)
+            {
+              string propertyName = Convert.ToString(_reader.Value, CultureInfo.InvariantCulture);
+              _reader.Read();
+
+              switch (propertyName)
+              {
+                case JsonSchemaConstants.OptionValuePropertyName:
+                  value = JToken.ReadFrom(_reader);
+                  break;
+                case JsonSchemaConstants.OptionLabelPropertyName:
+                  label = (string) _reader.Value;
+                  break;
+                default:
+                  throw JsonReaderException.Create(_reader, "Unexpected property in JSON schema option: {0}.".FormatWith(CultureInfo.InvariantCulture, propertyName));
+              }
+            }
+
+            if (value == null)
+              throw new JsonException("No value specified for JSON schema option.");
+
+            if (CurrentSchema.Options.ContainsKey(value))
+              throw new JsonException("Duplicate value in JSON schema option collection: {0}".FormatWith(CultureInfo.InvariantCulture, value));
+
+            CurrentSchema.Options.Add(value, label);
+          }
+          break;
+        default:
+          throw JsonReaderException.Create(_reader, "Expected array token, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType));
+      }
+    }
+
+    private void ProcessDefault()
+    {
+      CurrentSchema.Default = JToken.ReadFrom(_reader);
+    }
+
+    private void ProcessIdentity()
+    {
+      CurrentSchema.Identity = new List<string>();
+
+      switch (_reader.TokenType)
+      {
+        case JsonToken.String:
+          CurrentSchema.Identity.Add(_reader.Value.ToString());
+          break;
+        case JsonToken.StartArray:
+          while (_reader.Read() && _reader.TokenType != JsonToken.EndArray)
+          {
+            if (_reader.TokenType != JsonToken.String)
+              throw JsonReaderException.Create(_reader, "Exception JSON property name string token, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType));
+
+            CurrentSchema.Identity.Add(_reader.Value.ToString());
+          }
+          break;
+        default:
+          throw JsonReaderException.Create(_reader, "Expected array or JSON property name string token, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType));
+      }
+    }
+
+    private void ProcessAdditionalProperties()
+    {
+      if (_reader.TokenType == JsonToken.Boolean)
+        CurrentSchema.AllowAdditionalProperties = (bool)_reader.Value;
+      else
+        CurrentSchema.AdditionalProperties = BuildSchema();
+    }
+
+    private void ProcessPatternProperties()
+    {
+      Dictionary<string, JsonSchema> patternProperties = new Dictionary<string, JsonSchema>();
+
+      if (_reader.TokenType != JsonToken.StartObject)
+        throw JsonReaderException.Create(_reader, "Expected StartObject token.");
+
+      while (_reader.Read() && _reader.TokenType != JsonToken.EndObject)
+      {
+        string propertyName = Convert.ToString(_reader.Value, CultureInfo.InvariantCulture);
+        _reader.Read();
+
+        if (patternProperties.ContainsKey(propertyName))
+          throw new JsonException("Property {0} has already been defined in schema.".FormatWith(CultureInfo.InvariantCulture, propertyName));
+
+        patternProperties.Add(propertyName, BuildSchema());
+      }
+
+      CurrentSchema.PatternProperties = patternProperties;
+    }
+
+    private void ProcessItems()
+    {
+      CurrentSchema.Items = new List<JsonSchema>();
+
+      switch (_reader.TokenType)
+      {
+        case JsonToken.StartObject:
+          CurrentSchema.Items.Add(BuildSchema());
+          break;
+        case JsonToken.StartArray:
+          while (_reader.Read() && _reader.TokenType != JsonToken.EndArray)
+          {
+            CurrentSchema.Items.Add(BuildSchema());
+          }
+          break;
+        default:
+          throw JsonReaderException.Create(_reader, "Expected array or JSON schema object token, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType));
+      }
+    }
+
+    private void ProcessProperties()
+    {
+      IDictionary<string, JsonSchema> properties = new Dictionary<string, JsonSchema>();
+
+      if (_reader.TokenType != JsonToken.StartObject)
+        throw JsonReaderException.Create(_reader, "Expected StartObject token while parsing schema properties, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType));
+
+      while (_reader.Read() && _reader.TokenType != JsonToken.EndObject)
+      {
+        string propertyName = Convert.ToString(_reader.Value, CultureInfo.InvariantCulture);
+        _reader.Read();
+
+        if (properties.ContainsKey(propertyName))
+          throw new JsonException("Property {0} has already been defined in schema.".FormatWith(CultureInfo.InvariantCulture, propertyName));
+
+        properties.Add(propertyName, BuildSchema());
+      }
+
+      CurrentSchema.Properties = properties;
+    }
+
+    private JsonSchemaType? ProcessType()
+    {
+      switch (_reader.TokenType)
+      {
+        case JsonToken.String:
+          return MapType(_reader.Value.ToString());
+        case JsonToken.StartArray:
+          // ensure type is in blank state before ORing values
+          JsonSchemaType? type = JsonSchemaType.None;
+
+          while (_reader.Read() && _reader.TokenType != JsonToken.EndArray)
+          {
+            if (_reader.TokenType != JsonToken.String)
+              throw JsonReaderException.Create(_reader, "Exception JSON schema type string token, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType));
+
+            type = type | MapType(_reader.Value.ToString());
+          }
+
+          return type;
+        default:
+          throw JsonReaderException.Create(_reader, "Expected array or JSON schema type string token, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType));
+      }
+    }
+
+    internal static JsonSchemaType MapType(string type)
+    {
+      JsonSchemaType mappedType;
+      if (!JsonSchemaConstants.JsonSchemaTypeMapping.TryGetValue(type, out mappedType))
+        throw new JsonException("Invalid JSON schema type: {0}".FormatWith(CultureInfo.InvariantCulture, type));
+
+      return mappedType;
+    }
+
+    internal static string MapType(JsonSchemaType type)
+    {
+      return JsonSchemaConstants.JsonSchemaTypeMapping.Single(kv => kv.Value == type).Key;
+    }
+  }
+}
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaConstants.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaConstants.cs
index 2b31fba..3b5e737 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaConstants.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaConstants.cs
@@ -1,80 +1,80 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Newtonsoft.Json.Schema
-{
-  internal static class JsonSchemaConstants
-  {
-    public const string TypePropertyName = "type";
-    public const string PropertiesPropertyName = "properties";
-    public const string ItemsPropertyName = "items";
-    public const string OptionalPropertyName = "optional";
-    public const string AdditionalPropertiesPropertyName = "additionalProperties";
-    public const string RequiresPropertyName = "requires";
-    public const string IdentityPropertyName = "identity";
-    public const string MinimumPropertyName = "minimum";
-    public const string MaximumPropertyName = "maximum";
-    public const string MinimumItemsPropertyName = "minItems";
-    public const string MaximumItemsPropertyName = "maxItems";
-    public const string PatternPropertyName = "pattern";
-    public const string MaximumLengthPropertyName = "maxLength";
-    public const string MinimumLengthPropertyName = "minLength";
-    public const string EnumPropertyName = "enum";
-    public const string OptionsPropertyName = "options";
-    public const string ReadOnlyPropertyName = "readonly";
-    public const string TitlePropertyName = "title";
-    public const string DescriptionPropertyName = "description";
-    public const string FormatPropertyName = "format";
-    public const string DefaultPropertyName = "default";
-    public const string TransientPropertyName = "transient";
-    public const string MaximumDecimalsPropertyName = "maxDecimal";
-    public const string HiddenPropertyName = "hidden";
-    public const string DisallowPropertyName = "disallow";
-    public const string ExtendsPropertyName = "extends";
-    public const string IdPropertyName = "id";
-
-    public const string OptionValuePropertyName = "value";
-    public const string OptionLabelPropertyName = "label";
-
-    public const string ReferencePropertyName = "$ref";
-
-    public static readonly IDictionary<string, JsonSchemaType> JsonSchemaTypeMapping = new Dictionary<string, JsonSchemaType>()
-    {
-      {"string", JsonSchemaType.String},
-      {"object", JsonSchemaType.Object},
-      {"integer", JsonSchemaType.Integer},
-      {"number", JsonSchemaType.Float},
-      {"null", JsonSchemaType.Null},
-      {"boolean", JsonSchemaType.Boolean},
-      {"array", JsonSchemaType.Array},
-      {"any", JsonSchemaType.Any}
-    };
-  }
-}
+#region License
+// 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.
+#endregion
+
+using System.Collections.Generic;
+
+namespace Newtonsoft.Json.Schema
+{
+  internal static class JsonSchemaConstants
+  {
+    public const string TypePropertyName = "type";
+    public const string PropertiesPropertyName = "properties";
+    public const string ItemsPropertyName = "items";
+    public const string RequiredPropertyName = "required";
+    public const string PatternPropertiesPropertyName = "patternProperties";
+    public const string AdditionalPropertiesPropertyName = "additionalProperties";
+    public const string RequiresPropertyName = "requires";
+    public const string IdentityPropertyName = "identity";
+    public const string MinimumPropertyName = "minimum";
+    public const string MaximumPropertyName = "maximum";
+    public const string ExclusiveMinimumPropertyName = "exclusiveMinimum";
+    public const string ExclusiveMaximumPropertyName = "exclusiveMaximum";
+    public const string MinimumItemsPropertyName = "minItems";
+    public const string MaximumItemsPropertyName = "maxItems";
+    public const string PatternPropertyName = "pattern";
+    public const string MaximumLengthPropertyName = "maxLength";
+    public const string MinimumLengthPropertyName = "minLength";
+    public const string EnumPropertyName = "enum";
+    public const string OptionsPropertyName = "options";
+    public const string ReadOnlyPropertyName = "readonly";
+    public const string TitlePropertyName = "title";
+    public const string DescriptionPropertyName = "description";
+    public const string FormatPropertyName = "format";
+    public const string DefaultPropertyName = "default";
+    public const string TransientPropertyName = "transient";
+    public const string DivisibleByPropertyName = "divisibleBy";
+    public const string HiddenPropertyName = "hidden";
+    public const string DisallowPropertyName = "disallow";
+    public const string ExtendsPropertyName = "extends";
+    public const string IdPropertyName = "id";
+
+    public const string OptionValuePropertyName = "value";
+    public const string OptionLabelPropertyName = "label";
+
+    public const string ReferencePropertyName = "$ref";
+
+    public static readonly IDictionary<string, JsonSchemaType> JsonSchemaTypeMapping = new Dictionary<string, JsonSchemaType>
+    {
+      {"string", JsonSchemaType.String},
+      {"object", JsonSchemaType.Object},
+      {"integer", JsonSchemaType.Integer},
+      {"number", JsonSchemaType.Float},
+      {"null", JsonSchemaType.Null},
+      {"boolean", JsonSchemaType.Boolean},
+      {"array", JsonSchemaType.Array},
+      {"any", JsonSchemaType.Any}
+    };
+  }
+}
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaException.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaException.cs
index a0b65e0..3fc70a5 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaException.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaException.cs
@@ -1,83 +1,108 @@
-#region License
-// 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.
-#endregion
-
-using System;
-
-namespace Newtonsoft.Json.Schema
-{
-  /// <summary>
-  /// Returns detailed information about the schema exception.
-  /// </summary>
-  public class JsonSchemaException : Exception
-  {
-    /// <summary>
-    /// Gets the line number indicating where the error occurred.
-    /// </summary>
-    /// <value>The line number indicating where the error occurred.</value>
-    public int LineNumber { get; private set; }
-
-
-    /// <summary>
-    /// Gets the line position indicating where the error occurred.
-    /// </summary>
-    /// <value>The line position indicating where the error occurred.</value>
-    public int LinePosition { get; private set; }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonSchemaException"/> class.
-    /// </summary>
-    public JsonSchemaException()
-    {
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonSchemaException"/> class
-    /// with a specified error message.
-    /// </summary>
-    /// <param name="message">The error message that explains the reason for the exception.</param>
-    public JsonSchemaException(string message)
-      : base(message)
-    {
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonSchemaException"/> class
-    /// with a specified error message and a reference to the inner exception that is the cause of this exception.
-    /// </summary>
-    /// <param name="message">The error message that explains the reason for the exception.</param>
-    /// <param name="innerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
-    public JsonSchemaException(string message, Exception innerException)
-      : base(message, innerException)
-    {
-    }
-
-    internal JsonSchemaException(string message, Exception innerException, int lineNumber, int linePosition)
-      : base(message, innerException)
-    {
-      LineNumber = lineNumber;
-      LinePosition = linePosition;
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Runtime.Serialization;
+
+namespace Newtonsoft.Json.Schema
+{
+  /// <summary>
+  /// Returns detailed information about the schema exception.
+  /// </summary>
+#if !(SILVERLIGHT || WINDOWS_PHONE || NETFX_CORE || PORTABLE)
+  [Serializable]
+#endif
+  public class JsonSchemaException : JsonException
+  {
+    /// <summary>
+    /// Gets the line number indicating where the error occurred.
+    /// </summary>
+    /// <value>The line number indicating where the error occurred.</value>
+    public int LineNumber { get; private set; }
+
+
+    /// <summary>
+    /// Gets the line position indicating where the error occurred.
+    /// </summary>
+    /// <value>The line position indicating where the error occurred.</value>
+    public int LinePosition { get; private set; }
+
+    /// <summary>
+    /// Gets the path to the JSON where the error occurred.
+    /// </summary>
+    /// <value>The path to the JSON where the error occurred.</value>
+    public string Path { get; private set; }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonSchemaException"/> class.
+    /// </summary>
+    public JsonSchemaException()
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonSchemaException"/> class
+    /// with a specified error message.
+    /// </summary>
+    /// <param name="message">The error message that explains the reason for the exception.</param>
+    public JsonSchemaException(string message)
+      : base(message)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonSchemaException"/> class
+    /// with a specified error message and a reference to the inner exception that is the cause of this exception.
+    /// </summary>
+    /// <param name="message">The error message that explains the reason for the exception.</param>
+    /// <param name="innerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
+    public JsonSchemaException(string message, Exception innerException)
+      : base(message, innerException)
+    {
+    }
+
+ #if !(WINDOWS_PHONE || SILVERLIGHT || NETFX_CORE || PORTABLE)
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonSchemaException"/> class.
+    /// </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 null. </exception>
+    /// <exception cref="T:System.Runtime.Serialization.SerializationException">The class name is null or <see cref="P:System.Exception.HResult"/> is zero (0). </exception>
+    public JsonSchemaException(SerializationInfo info, StreamingContext context)
+      : base(info, context)
+    {
+    }
+#endif
+
+    internal JsonSchemaException(string message, Exception innerException, string path, int lineNumber, int linePosition)
+      : base(message, innerException)
+    {
+      Path = path;
+      LineNumber = lineNumber;
+      LinePosition = linePosition;
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaGenerator.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaGenerator.cs
index 1e6b60b..306b637 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaGenerator.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaGenerator.cs
@@ -1,441 +1,464 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Linq;
-using System.Globalization;
-using System.ComponentModel;
-using System.Collections.Generic;
-using Newtonsoft.Json.Linq;
-using Newtonsoft.Json.Utilities;
-using Newtonsoft.Json.Serialization;
-
-namespace Newtonsoft.Json.Schema
-{
-  /// <summary>
-  /// Generates a <see cref="JsonSchema"/> from a specified <see cref="Type"/>.
-  /// </summary>
-  public class JsonSchemaGenerator
-  {
-    /// <summary>
-    /// Gets or sets how undefined schemas are handled by the serializer.
-    /// </summary>
-    public UndefinedSchemaIdHandling UndefinedSchemaIdHandling { get; set; }
-
-    private IContractResolver _contractResolver;
-    /// <summary>
-    /// Gets or sets the contract resolver.
-    /// </summary>
-    /// <value>The contract resolver.</value>
-    public IContractResolver ContractResolver
-    {
-      get
-      {
-        if (_contractResolver == null)
-          return DefaultContractResolver.Instance;
-
-        return _contractResolver;
-      }
-      set { _contractResolver = value; }
-    }
-
-    private class TypeSchema
-    {
-      public Type Type { get; private set; }
-      public JsonSchema Schema { get; private set;}
-
-      public TypeSchema(Type type, JsonSchema schema)
-      {
-        ValidationUtils.ArgumentNotNull(type, "type");
-        ValidationUtils.ArgumentNotNull(schema, "schema");
-
-        Type = type;
-        Schema = schema;
-      }
-    }
-
-    private JsonSchemaResolver _resolver;
-    private IList<TypeSchema> _stack = new List<TypeSchema>();
-    private JsonSchema _currentSchema;
-
-    private JsonSchema CurrentSchema
-    {
-      get { return _currentSchema; }
-    }
-
-    private void Push(TypeSchema typeSchema)
-    {
-      _currentSchema = typeSchema.Schema;
-      _stack.Add(typeSchema);
-      _resolver.LoadedSchemas.Add(typeSchema.Schema);
-    }
-
-    private TypeSchema Pop()
-    {
-      TypeSchema popped = _stack[_stack.Count - 1];
-      _stack.RemoveAt(_stack.Count - 1);
-      TypeSchema newValue = _stack.LastOrDefault();
-      if (newValue != null)
-      {
-        _currentSchema = newValue.Schema;
-      }
-      else
-      {
-        _currentSchema = null;
-      }
-
-      return popped;
-    }
-
-    /// <summary>
-    /// Generate a <see cref="JsonSchema"/> from the specified type.
-    /// </summary>
-    /// <param name="type">The type to generate a <see cref="JsonSchema"/> from.</param>
-    /// <returns>A <see cref="JsonSchema"/> generated from the specified type.</returns>
-    public JsonSchema Generate(Type type)
-    {
-      return Generate(type, new JsonSchemaResolver(), false);
-    }
-
-    /// <summary>
-    /// Generate a <see cref="JsonSchema"/> from the specified type.
-    /// </summary>
-    /// <param name="type">The type to generate a <see cref="JsonSchema"/> from.</param>
-    /// <param name="resolver">The <see cref="JsonSchemaResolver"/> used to resolve schema references.</param>
-    /// <returns>A <see cref="JsonSchema"/> generated from the specified type.</returns>
-    public JsonSchema Generate(Type type, JsonSchemaResolver resolver)
-    {
-      return Generate(type, resolver, false);
-    }
-
-    /// <summary>
-    /// Generate a <see cref="JsonSchema"/> from the specified type.
-    /// </summary>
-    /// <param name="type">The type to generate a <see cref="JsonSchema"/> from.</param>
-    /// <param name="rootSchemaNullable">Specify whether the generated root <see cref="JsonSchema"/> will be nullable.</param>
-    /// <returns>A <see cref="JsonSchema"/> generated from the specified type.</returns>
-    public JsonSchema Generate(Type type, bool rootSchemaNullable)
-    {
-      return Generate(type, new JsonSchemaResolver(), rootSchemaNullable);
-    }
-
-    /// <summary>
-    /// Generate a <see cref="JsonSchema"/> from the specified type.
-    /// </summary>
-    /// <param name="type">The type to generate a <see cref="JsonSchema"/> from.</param>
-    /// <param name="resolver">The <see cref="JsonSchemaResolver"/> used to resolve schema references.</param>
-    /// <param name="rootSchemaNullable">Specify whether the generated root <see cref="JsonSchema"/> will be nullable.</param>
-    /// <returns>A <see cref="JsonSchema"/> generated from the specified type.</returns>
-    public JsonSchema Generate(Type type, JsonSchemaResolver resolver, bool rootSchemaNullable)
-    {
-      ValidationUtils.ArgumentNotNull(type, "type");
-      ValidationUtils.ArgumentNotNull(resolver, "resolver");
-
-      _resolver = resolver;
-
-      return GenerateInternal(type, (!rootSchemaNullable) ? Required.Always : Required.Default, false);
-    }
-
-    private string GetTitle(Type type)
-    {
-      JsonContainerAttribute containerAttribute = JsonTypeReflector.GetJsonContainerAttribute(type);
-
-      if (containerAttribute != null && !string.IsNullOrEmpty(containerAttribute.Title))
-        return containerAttribute.Title;
-
-      return null;
-    }
-
-    private string GetDescription(Type type)
-    {
-      JsonContainerAttribute containerAttribute = JsonTypeReflector.GetJsonContainerAttribute(type);
-
-      if (containerAttribute != null && !string.IsNullOrEmpty(containerAttribute.Description))
-        return containerAttribute.Description;
-
-#if !PocketPC
-      DescriptionAttribute descriptionAttribute = ReflectionUtils.GetAttribute<DescriptionAttribute>(type);
-      if (descriptionAttribute != null)
-        return descriptionAttribute.Description;
-#endif
-
-      return null;
-    }
-
-    private string GetTypeId(Type type, bool explicitOnly)
-    {
-      JsonContainerAttribute containerAttribute = JsonTypeReflector.GetJsonContainerAttribute(type);
-
-      if (containerAttribute != null && !string.IsNullOrEmpty(containerAttribute.Id))
-        return containerAttribute.Id;
-
-      if (explicitOnly)
-        return null;
-
-      switch (UndefinedSchemaIdHandling)
-      {
-        case UndefinedSchemaIdHandling.UseTypeName:
-          return type.FullName;
-        case UndefinedSchemaIdHandling.UseAssemblyQualifiedName:
-          return type.AssemblyQualifiedName;
-        default:
-          return null;
-      }
-    }
-
-    private JsonSchema GenerateInternal(Type type, Required valueRequired, bool optional)
-    {
-      ValidationUtils.ArgumentNotNull(type, "type");
-
-      string resolvedId = GetTypeId(type, false);
-      string explicitId = GetTypeId(type, true);
-
-      if (!string.IsNullOrEmpty(resolvedId))
-      {
-        JsonSchema resolvedSchema = _resolver.GetSchema(resolvedId);
-        if (resolvedSchema != null)
-        {
-          // resolved schema is not null but referencing member allows nulls
-          // change resolved schema to allow nulls. hacky but what are ya gonna do?
-          if (valueRequired != Required.Always && !HasFlag(resolvedSchema.Type, JsonSchemaType.Null))
-            resolvedSchema.Type |= JsonSchemaType.Null;
-          if (optional && resolvedSchema.Optional != true)
-            resolvedSchema.Optional = true;
-
-          return resolvedSchema;
-        }
-      }
-
-      // test for unresolved circular reference
-      if (_stack.Any(tc => tc.Type == type))
-      {
-        throw new Exception("Unresolved circular reference for type '{0}'. Explicitly define an Id for the type using a JsonObject/JsonArray attribute or automatically generate a type Id using the UndefinedSchemaIdHandling property.".FormatWith(CultureInfo.InvariantCulture, type));
-      }
-
-      JsonContract contract = ContractResolver.ResolveContract(type);
-      JsonConverter converter;
-      if ((converter = contract.Converter) != null || (converter = contract.InternalConverter) != null)
-      {
-        JsonSchema converterSchema = converter.GetSchema();
-        if (converterSchema != null)
-          return converterSchema;
-      }
-
-      Push(new TypeSchema(type, new JsonSchema()));
-
-      if (explicitId != null)
-        CurrentSchema.Id = explicitId;
-
-      if (optional)
-        CurrentSchema.Optional = true;
-      CurrentSchema.Title = GetTitle(type);
-      CurrentSchema.Description = GetDescription(type);
-
-      if (converter != null)
-      {
-        // todo: Add GetSchema to JsonConverter and use here?
-        CurrentSchema.Type = JsonSchemaType.Any;
-      }
-      else if (contract is JsonDictionaryContract)
-      {
-        CurrentSchema.Type = AddNullType(JsonSchemaType.Object, valueRequired);
-
-        Type keyType;
-        Type valueType;
-        ReflectionUtils.GetDictionaryKeyValueTypes(type, out keyType, out valueType);
-
-        if (keyType != null)
-        {
-          // can be converted to a string
-          if (typeof (IConvertible).IsAssignableFrom(keyType))
-          {
-            CurrentSchema.AdditionalProperties = GenerateInternal(valueType, Required.Default, false);
-          }
-        }
-      }
-      else if (contract is JsonArrayContract)
-      {
-        CurrentSchema.Type = AddNullType(JsonSchemaType.Array, valueRequired);
-
-        CurrentSchema.Id = GetTypeId(type, false);
-
-        JsonArrayAttribute arrayAttribute = JsonTypeReflector.GetJsonContainerAttribute(type) as JsonArrayAttribute;
-        bool allowNullItem = (arrayAttribute != null) ? arrayAttribute.AllowNullItems : true;
-
-        Type collectionItemType = ReflectionUtils.GetCollectionItemType(type);
-        if (collectionItemType != null)
-        {
-          CurrentSchema.Items = new List<JsonSchema>();
-          CurrentSchema.Items.Add(GenerateInternal(collectionItemType, (!allowNullItem) ? Required.Always : Required.Default, false));
-        }
-      }
-      else if (contract is JsonPrimitiveContract)
-      {
-        CurrentSchema.Type = GetJsonSchemaType(type, valueRequired);
-
-        if (CurrentSchema.Type == JsonSchemaType.Integer && type.IsEnum && !type.IsDefined(typeof(FlagsAttribute), true))
-        {
-          CurrentSchema.Enum = new List<JToken>();
-          CurrentSchema.Options = new Dictionary<JToken, string>();
-
-          EnumValues<long> enumValues = EnumUtils.GetNamesAndValues<long>(type);
-          foreach (EnumValue<long> enumValue in enumValues)
-          {
-            JToken value = JToken.FromObject(enumValue.Value);
-
-            CurrentSchema.Enum.Add(value);
-            CurrentSchema.Options.Add(value, enumValue.Name);
-          }
-        }
-      }
-      else if (contract is JsonObjectContract)
-      {
-        CurrentSchema.Type = AddNullType(JsonSchemaType.Object, valueRequired);
-        CurrentSchema.Id = GetTypeId(type, false);
-        GenerateObjectSchema(type, (JsonObjectContract)contract);
-      }
-#if !SILVERLIGHT && !PocketPC
-      else if (contract is JsonISerializableContract)
-      {
-        CurrentSchema.Type = AddNullType(JsonSchemaType.Object, valueRequired);
-        CurrentSchema.Id = GetTypeId(type, false);
-        GenerateISerializableContract(type, (JsonISerializableContract) contract);
-      }
-#endif
-      else if (contract is JsonStringContract)
-      {
-        JsonSchemaType schemaType = (!ReflectionUtils.IsNullable(contract.UnderlyingType))
-                                      ? JsonSchemaType.String
-                                      : AddNullType(JsonSchemaType.String, valueRequired);
-
-        CurrentSchema.Type = schemaType;
-      }
-      else if (contract is JsonLinqContract)
-      {
-        CurrentSchema.Type = JsonSchemaType.Any;
-      }
-      else
-      {
-        throw new Exception("Unexpected contract type: {0}".FormatWith(CultureInfo.InvariantCulture, contract));
-      }
-
-      return Pop().Schema;
-    }
-
-    private JsonSchemaType AddNullType(JsonSchemaType type, Required valueRequired)
-    {
-      if (valueRequired != Required.Always)
-        return type | JsonSchemaType.Null;
-
-      return type;
-    }
-
-    private void GenerateObjectSchema(Type type, JsonObjectContract contract)
-    {
-      CurrentSchema.Properties = new Dictionary<string, JsonSchema>();
-      foreach (JsonProperty property in contract.Properties)
-      {
-        if (!property.Ignored)
-        {
-          bool optional = property.NullValueHandling == NullValueHandling.Ignore ||
-                          property.DefaultValueHandling == DefaultValueHandling.Ignore ||
-                          property.ShouldSerialize != null;
-
-          JsonSchema propertySchema = GenerateInternal(property.PropertyType, property.Required, optional);
-
-          if (property.DefaultValue != null)
-            propertySchema.Default = JToken.FromObject(property.DefaultValue);
-
-          CurrentSchema.Properties.Add(property.PropertyName, propertySchema);
-        }
-      }
-
-      if (type.IsSealed)
-        CurrentSchema.AllowAdditionalProperties = false;
-    }
-
-#if !SILVERLIGHT && !PocketPC
-    private void GenerateISerializableContract(Type type, JsonISerializableContract contract)
-    {
-      CurrentSchema.AllowAdditionalProperties = true;
-    }
-#endif
-
-    internal static bool HasFlag(JsonSchemaType? value, JsonSchemaType flag)
-    {
-      // default value is Any
-      if (value == null)
-        return true;
-
-      return ((value & flag) == flag);
-    }
-
-    private JsonSchemaType GetJsonSchemaType(Type type, Required valueRequired)
-    {
-      JsonSchemaType schemaType = JsonSchemaType.None;
-      if (valueRequired != Required.Always && ReflectionUtils.IsNullable(type))
-      {
-        schemaType = JsonSchemaType.Null;
-        if (ReflectionUtils.IsNullableType(type))
-          type = Nullable.GetUnderlyingType(type);
-      }
-
-      TypeCode typeCode = Type.GetTypeCode(type);
-
-      switch (typeCode)
-      {
-        case TypeCode.Empty:
-        case TypeCode.Object:
-          return schemaType | JsonSchemaType.String;
-        case TypeCode.DBNull:
-          return schemaType | JsonSchemaType.Null;
-        case TypeCode.Boolean:
-          return schemaType | JsonSchemaType.Boolean;
-        case TypeCode.Char:
-          return schemaType | JsonSchemaType.String;
-        case TypeCode.SByte:
-        case TypeCode.Byte:
-        case TypeCode.Int16:
-        case TypeCode.UInt16:
-        case TypeCode.Int32:
-        case TypeCode.UInt32:
-        case TypeCode.Int64:
-        case TypeCode.UInt64:
-          return schemaType | JsonSchemaType.Integer;
-        case TypeCode.Single:
-        case TypeCode.Double:
-        case TypeCode.Decimal:
-          return schemaType | JsonSchemaType.Float;
-        // convert to string?
-        case TypeCode.DateTime:
-          return schemaType | JsonSchemaType.String;
-        case TypeCode.String:
-          return schemaType | JsonSchemaType.String;
-        default:
-          throw new Exception("Unexpected type code '{0}' for type '{1}'.".FormatWith(CultureInfo.InvariantCulture, typeCode, type));
-      }
-    }
-  }
-}
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Globalization;
+using System.ComponentModel;
+using System.Collections.Generic;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Utilities;
+using Newtonsoft.Json.Serialization;
+#if NETFX_CORE
+using IConvertible = Newtonsoft.Json.Utilities.Convertible;
+#endif
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#else
+using System.Linq;
+#endif
+
+namespace Newtonsoft.Json.Schema
+{
+  /// <summary>
+  /// Generates a <see cref="JsonSchema"/> from a specified <see cref="Type"/>.
+  /// </summary>
+  public class JsonSchemaGenerator
+  {
+    /// <summary>
+    /// Gets or sets how undefined schemas are handled by the serializer.
+    /// </summary>
+    public UndefinedSchemaIdHandling UndefinedSchemaIdHandling { get; set; }
+
+    private IContractResolver _contractResolver;
+    /// <summary>
+    /// Gets or sets the contract resolver.
+    /// </summary>
+    /// <value>The contract resolver.</value>
+    public IContractResolver ContractResolver
+    {
+      get
+      {
+        if (_contractResolver == null)
+          return DefaultContractResolver.Instance;
+
+        return _contractResolver;
+      }
+      set { _contractResolver = value; }
+    }
+
+    private class TypeSchema
+    {
+      public Type Type { get; private set; }
+      public JsonSchema Schema { get; private set;}
+
+      public TypeSchema(Type type, JsonSchema schema)
+      {
+        ValidationUtils.ArgumentNotNull(type, "type");
+        ValidationUtils.ArgumentNotNull(schema, "schema");
+
+        Type = type;
+        Schema = schema;
+      }
+    }
+
+    private JsonSchemaResolver _resolver;
+    private readonly IList<TypeSchema> _stack = new List<TypeSchema>();
+    private JsonSchema _currentSchema;
+
+    private JsonSchema CurrentSchema
+    {
+      get { return _currentSchema; }
+    }
+
+    private void Push(TypeSchema typeSchema)
+    {
+      _currentSchema = typeSchema.Schema;
+      _stack.Add(typeSchema);
+      _resolver.LoadedSchemas.Add(typeSchema.Schema);
+    }
+
+    private TypeSchema Pop()
+    {
+      TypeSchema popped = _stack[_stack.Count - 1];
+      _stack.RemoveAt(_stack.Count - 1);
+      TypeSchema newValue = _stack.LastOrDefault();
+      if (newValue != null)
+      {
+        _currentSchema = newValue.Schema;
+      }
+      else
+      {
+        _currentSchema = null;
+      }
+
+      return popped;
+    }
+
+    /// <summary>
+    /// Generate a <see cref="JsonSchema"/> from the specified type.
+    /// </summary>
+    /// <param name="type">The type to generate a <see cref="JsonSchema"/> from.</param>
+    /// <returns>A <see cref="JsonSchema"/> generated from the specified type.</returns>
+    public JsonSchema Generate(Type type)
+    {
+      return Generate(type, new JsonSchemaResolver(), false);
+    }
+
+    /// <summary>
+    /// Generate a <see cref="JsonSchema"/> from the specified type.
+    /// </summary>
+    /// <param name="type">The type to generate a <see cref="JsonSchema"/> from.</param>
+    /// <param name="resolver">The <see cref="JsonSchemaResolver"/> used to resolve schema references.</param>
+    /// <returns>A <see cref="JsonSchema"/> generated from the specified type.</returns>
+    public JsonSchema Generate(Type type, JsonSchemaResolver resolver)
+    {
+      return Generate(type, resolver, false);
+    }
+
+    /// <summary>
+    /// Generate a <see cref="JsonSchema"/> from the specified type.
+    /// </summary>
+    /// <param name="type">The type to generate a <see cref="JsonSchema"/> from.</param>
+    /// <param name="rootSchemaNullable">Specify whether the generated root <see cref="JsonSchema"/> will be nullable.</param>
+    /// <returns>A <see cref="JsonSchema"/> generated from the specified type.</returns>
+    public JsonSchema Generate(Type type, bool rootSchemaNullable)
+    {
+      return Generate(type, new JsonSchemaResolver(), rootSchemaNullable);
+    }
+
+    /// <summary>
+    /// Generate a <see cref="JsonSchema"/> from the specified type.
+    /// </summary>
+    /// <param name="type">The type to generate a <see cref="JsonSchema"/> from.</param>
+    /// <param name="resolver">The <see cref="JsonSchemaResolver"/> used to resolve schema references.</param>
+    /// <param name="rootSchemaNullable">Specify whether the generated root <see cref="JsonSchema"/> will be nullable.</param>
+    /// <returns>A <see cref="JsonSchema"/> generated from the specified type.</returns>
+    public JsonSchema Generate(Type type, JsonSchemaResolver resolver, bool rootSchemaNullable)
+    {
+      ValidationUtils.ArgumentNotNull(type, "type");
+      ValidationUtils.ArgumentNotNull(resolver, "resolver");
+
+      _resolver = resolver;
+
+      return GenerateInternal(type, (!rootSchemaNullable) ? Required.Always : Required.Default, false);
+    }
+
+    private string GetTitle(Type type)
+    {
+      JsonContainerAttribute containerAttribute = JsonTypeReflector.GetJsonContainerAttribute(type);
+
+      if (containerAttribute != null && !string.IsNullOrEmpty(containerAttribute.Title))
+        return containerAttribute.Title;
+
+      return null;
+    }
+
+    private string GetDescription(Type type)
+    {
+      JsonContainerAttribute containerAttribute = JsonTypeReflector.GetJsonContainerAttribute(type);
+
+      if (containerAttribute != null && !string.IsNullOrEmpty(containerAttribute.Description))
+        return containerAttribute.Description;
+
+#if !(NETFX_CORE || PORTABLE)
+      DescriptionAttribute descriptionAttribute = ReflectionUtils.GetAttribute<DescriptionAttribute>(type);
+      if (descriptionAttribute != null)
+        return descriptionAttribute.Description;
+#endif
+
+      return null;
+    }
+
+    private string GetTypeId(Type type, bool explicitOnly)
+    {
+      JsonContainerAttribute containerAttribute = JsonTypeReflector.GetJsonContainerAttribute(type);
+
+      if (containerAttribute != null && !string.IsNullOrEmpty(containerAttribute.Id))
+        return containerAttribute.Id;
+
+      if (explicitOnly)
+        return null;
+
+      switch (UndefinedSchemaIdHandling)
+      {
+        case UndefinedSchemaIdHandling.UseTypeName:
+          return type.FullName;
+        case UndefinedSchemaIdHandling.UseAssemblyQualifiedName:
+          return type.AssemblyQualifiedName;
+        default:
+          return null;
+      }
+    }
+
+    private JsonSchema GenerateInternal(Type type, Required valueRequired, bool required)
+    {
+      ValidationUtils.ArgumentNotNull(type, "type");
+
+      string resolvedId = GetTypeId(type, false);
+      string explicitId = GetTypeId(type, true);
+
+      if (!string.IsNullOrEmpty(resolvedId))
+      {
+        JsonSchema resolvedSchema = _resolver.GetSchema(resolvedId);
+        if (resolvedSchema != null)
+        {
+          // resolved schema is not null but referencing member allows nulls
+          // change resolved schema to allow nulls. hacky but what are ya gonna do?
+          if (valueRequired != Required.Always && !HasFlag(resolvedSchema.Type, JsonSchemaType.Null))
+            resolvedSchema.Type |= JsonSchemaType.Null;
+          if (required && resolvedSchema.Required != true)
+            resolvedSchema.Required = true;
+
+          return resolvedSchema;
+        }
+      }
+
+      // test for unresolved circular reference
+      if (_stack.Any(tc => tc.Type == type))
+      {
+        throw new JsonException("Unresolved circular reference for type '{0}'. Explicitly define an Id for the type using a JsonObject/JsonArray attribute or automatically generate a type Id using the UndefinedSchemaIdHandling property.".FormatWith(CultureInfo.InvariantCulture, type));
+      }
+
+      JsonContract contract = ContractResolver.ResolveContract(type);
+      JsonConverter converter;
+      if ((converter = contract.Converter) != null || (converter = contract.InternalConverter) != null)
+      {
+        JsonSchema converterSchema = converter.GetSchema();
+        if (converterSchema != null)
+          return converterSchema;
+      }
+
+      Push(new TypeSchema(type, new JsonSchema()));
+
+      if (explicitId != null)
+        CurrentSchema.Id = explicitId;
+
+      if (required)
+        CurrentSchema.Required = true;
+      CurrentSchema.Title = GetTitle(type);
+      CurrentSchema.Description = GetDescription(type);
+
+      if (converter != null)
+      {
+        // todo: Add GetSchema to JsonConverter and use here?
+        CurrentSchema.Type = JsonSchemaType.Any;
+      }
+      else
+      {
+        switch (contract.ContractType)
+        {
+          case JsonContractType.Object:
+            CurrentSchema.Type = AddNullType(JsonSchemaType.Object, valueRequired);
+            CurrentSchema.Id = GetTypeId(type, false);
+            GenerateObjectSchema(type, (JsonObjectContract) contract);
+            break;
+          case JsonContractType.Array:
+            CurrentSchema.Type = AddNullType(JsonSchemaType.Array, valueRequired);
+
+            CurrentSchema.Id = GetTypeId(type, false);
+
+            JsonArrayAttribute arrayAttribute = JsonTypeReflector.GetJsonContainerAttribute(type) as JsonArrayAttribute;
+            bool allowNullItem = (arrayAttribute == null || arrayAttribute.AllowNullItems);
+
+            Type collectionItemType = ReflectionUtils.GetCollectionItemType(type);
+            if (collectionItemType != null)
+            {
+              CurrentSchema.Items = new List<JsonSchema>();
+              CurrentSchema.Items.Add(GenerateInternal(collectionItemType, (!allowNullItem) ? Required.Always : Required.Default, false));
+            }
+            break;
+          case JsonContractType.Primitive:
+            CurrentSchema.Type = GetJsonSchemaType(type, valueRequired);
+
+            if (CurrentSchema.Type == JsonSchemaType.Integer && type.IsEnum() && !type.IsDefined(typeof (FlagsAttribute), true))
+            {
+              CurrentSchema.Enum = new List<JToken>();
+              CurrentSchema.Options = new Dictionary<JToken, string>();
+
+              EnumValues<long> enumValues = EnumUtils.GetNamesAndValues<long>(type);
+              foreach (EnumValue<long> enumValue in enumValues)
+              {
+                JToken value = JToken.FromObject(enumValue.Value);
+
+                CurrentSchema.Enum.Add(value);
+                CurrentSchema.Options.Add(value, enumValue.Name);
+              }
+            }
+            break;
+          case JsonContractType.String:
+            JsonSchemaType schemaType = (!ReflectionUtils.IsNullable(contract.UnderlyingType))
+                                          ? JsonSchemaType.String
+                                          : AddNullType(JsonSchemaType.String, valueRequired);
+
+            CurrentSchema.Type = schemaType;
+            break;
+          case JsonContractType.Dictionary:
+            CurrentSchema.Type = AddNullType(JsonSchemaType.Object, valueRequired);
+
+            Type keyType;
+            Type valueType;
+            ReflectionUtils.GetDictionaryKeyValueTypes(type, out keyType, out valueType);
+
+            if (keyType != null)
+            {
+              // can be converted to a string
+              if (ConvertUtils.IsConvertible(keyType))
+              {
+                CurrentSchema.AdditionalProperties = GenerateInternal(valueType, Required.Default, false);
+              }
+            }
+            break;
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+          case JsonContractType.Serializable:
+            CurrentSchema.Type = AddNullType(JsonSchemaType.Object, valueRequired);
+            CurrentSchema.Id = GetTypeId(type, false);
+            GenerateISerializableContract(type, (JsonISerializableContract) contract);
+            break;
+#endif
+#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
+          case JsonContractType.Dynamic:
+#endif
+          case JsonContractType.Linq:
+            CurrentSchema.Type = JsonSchemaType.Any;
+            break;
+          default:
+            throw new JsonException("Unexpected contract type: {0}".FormatWith(CultureInfo.InvariantCulture, contract));
+        }
+      }
+
+      return Pop().Schema;
+    }
+
+    private JsonSchemaType AddNullType(JsonSchemaType type, Required valueRequired)
+    {
+      if (valueRequired != Required.Always)
+        return type | JsonSchemaType.Null;
+
+      return type;
+    }
+
+    private bool HasFlag(DefaultValueHandling value, DefaultValueHandling flag)
+    {
+      return ((value & flag) == flag);
+    }
+
+    private void GenerateObjectSchema(Type type, JsonObjectContract contract)
+    {
+      CurrentSchema.Properties = new Dictionary<string, JsonSchema>();
+      foreach (JsonProperty property in contract.Properties)
+      {
+        if (!property.Ignored)
+        {
+          bool optional = property.NullValueHandling == NullValueHandling.Ignore ||
+                          HasFlag(property.DefaultValueHandling.GetValueOrDefault(), DefaultValueHandling.Ignore) ||
+                          property.ShouldSerialize != null ||
+                          property.GetIsSpecified != null;
+
+          JsonSchema propertySchema = GenerateInternal(property.PropertyType, property.Required, !optional);
+
+          if (property.DefaultValue != null)
+            propertySchema.Default = JToken.FromObject(property.DefaultValue);
+
+          CurrentSchema.Properties.Add(property.PropertyName, propertySchema);
+        }
+      }
+
+      if (type.IsSealed())
+        CurrentSchema.AllowAdditionalProperties = false;
+    }
+
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+    private void GenerateISerializableContract(Type type, JsonISerializableContract contract)
+    {
+      CurrentSchema.AllowAdditionalProperties = true;
+    }
+#endif
+
+    internal static bool HasFlag(JsonSchemaType? value, JsonSchemaType flag)
+    {
+      // default value is Any
+      if (value == null)
+        return true;
+
+      bool match = ((value & flag) == flag);
+      if (match)
+        return true;
+
+      // integer is a subset of float
+      if (value == JsonSchemaType.Float && flag == JsonSchemaType.Integer)
+        return true;
+
+      return false;
+    }
+
+    private JsonSchemaType GetJsonSchemaType(Type type, Required valueRequired)
+    {
+      JsonSchemaType schemaType = JsonSchemaType.None;
+      if (valueRequired != Required.Always && ReflectionUtils.IsNullable(type))
+      {
+        schemaType = JsonSchemaType.Null;
+        if (ReflectionUtils.IsNullableType(type))
+          type = Nullable.GetUnderlyingType(type);
+      }
+
+      TypeCode typeCode = ConvertUtils.GetTypeCode(type);
+
+      switch (typeCode)
+      {
+        case TypeCode.Empty:
+        case TypeCode.Object:
+          return schemaType | JsonSchemaType.String;
+#if !(NETFX_CORE || PORTABLE)
+        case TypeCode.DBNull:
+          return schemaType | JsonSchemaType.Null;
+#endif
+        case TypeCode.Boolean:
+          return schemaType | JsonSchemaType.Boolean;
+        case TypeCode.Char:
+          return schemaType | JsonSchemaType.String;
+        case TypeCode.SByte:
+        case TypeCode.Byte:
+        case TypeCode.Int16:
+        case TypeCode.UInt16:
+        case TypeCode.Int32:
+        case TypeCode.UInt32:
+        case TypeCode.Int64:
+        case TypeCode.UInt64:
+          return schemaType | JsonSchemaType.Integer;
+        case TypeCode.Single:
+        case TypeCode.Double:
+        case TypeCode.Decimal:
+          return schemaType | JsonSchemaType.Float;
+        // convert to string?
+        case TypeCode.DateTime:
+          return schemaType | JsonSchemaType.String;
+        case TypeCode.String:
+          return schemaType | JsonSchemaType.String;
+        default:
+          throw new JsonException("Unexpected type code '{0}' for type '{1}'.".FormatWith(CultureInfo.InvariantCulture, typeCode, type));
+      }
+    }
+  }
+}
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaModel.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaModel.cs
index 26e1ae2..1a74a8d 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaModel.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaModel.cs
@@ -1,103 +1,111 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Newtonsoft.Json.Linq;
-using Newtonsoft.Json.Utilities;
-
-namespace Newtonsoft.Json.Schema
-{
-  internal class JsonSchemaModel
-  {
-    public bool Optional { get; set; }
-    public JsonSchemaType Type { get; set; }
-    public int? MinimumLength { get; set; }
-    public int? MaximumLength { get; set; }
-    public int? MaximumDecimals { get; set; }
-    public double? Minimum { get; set; }
-    public double? Maximum { get; set; }
-    public int? MinimumItems { get; set; }
-    public int? MaximumItems { get; set; }
-    public IList<string> Patterns { get; set; }
-    public IList<JsonSchemaModel> Items { get; set; }
-    public IDictionary<string, JsonSchemaModel> Properties { get; set; }
-    public JsonSchemaModel AdditionalProperties { get; set; }
-    public bool AllowAdditionalProperties { get; set; }
-    public IList<JToken> Enum { get; set; }
-    public JsonSchemaType Disallow { get; set; }
-
-    public JsonSchemaModel()
-    {
-      Type = JsonSchemaType.Any;
-      AllowAdditionalProperties = true;
-      Optional = true;
-    }
-
-    public static JsonSchemaModel Create(IList<JsonSchema> schemata)
-    {
-      JsonSchemaModel model = new JsonSchemaModel();
-
-      foreach (JsonSchema schema in schemata)
-      {
-        Combine(model, schema);
-      }
-
-      return model;
-    }
-
-    private static void Combine(JsonSchemaModel model, JsonSchema schema)
-    {
-      model.Optional = model.Optional && (schema.Optional ?? false);
-      model.Type = model.Type & (schema.Type ?? JsonSchemaType.Any);
-
-      model.MinimumLength = MathUtils.Max(model.MinimumLength, schema.MinimumLength);
-      model.MaximumLength = MathUtils.Min(model.MaximumLength, schema.MaximumLength);
-      model.MaximumDecimals = MathUtils.Min(model.MaximumDecimals, schema.MaximumDecimals);
-      model.Minimum = MathUtils.Max(model.Minimum, schema.Minimum);
-      model.Maximum = MathUtils.Max(model.Maximum, schema.Maximum);
-      model.MinimumItems = MathUtils.Max(model.MinimumItems, schema.MinimumItems);
-      model.MaximumItems = MathUtils.Min(model.MaximumItems, schema.MaximumItems);
-      model.AllowAdditionalProperties = model.AllowAdditionalProperties && schema.AllowAdditionalProperties;
-      if (schema.Enum != null)
-      {
-        if (model.Enum == null)
-          model.Enum = new List<JToken>();
-
-        model.Enum.AddRangeDistinct(schema.Enum, new JTokenEqualityComparer());
-      }
-      model.Disallow = model.Disallow | (schema.Disallow ?? JsonSchemaType.None);
-
-      if (schema.Pattern != null)
-      {
-        if (model.Patterns == null)
-          model.Patterns = new List<string>();
-
-        model.Patterns.AddDistinct(schema.Pattern);
-      }
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System.Collections.Generic;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Schema
+{
+  internal class JsonSchemaModel
+  {
+    public bool Required { get; set; }
+    public JsonSchemaType Type { get; set; }
+    public int? MinimumLength { get; set; }
+    public int? MaximumLength { get; set; }
+    public double? DivisibleBy { get; set; }
+    public double? Minimum { get; set; }
+    public double? Maximum { get; set; }
+    public bool ExclusiveMinimum { get; set; }
+    public bool ExclusiveMaximum { get; set; }
+    public int? MinimumItems { get; set; }
+    public int? MaximumItems { get; set; }
+    public IList<string> Patterns { get; set; }
+    public IList<JsonSchemaModel> Items { get; set; }
+    public IDictionary<string, JsonSchemaModel> Properties { get; set; }
+    public IDictionary<string, JsonSchemaModel> PatternProperties { get; set; }
+    public JsonSchemaModel AdditionalProperties { get; set; }
+    public bool AllowAdditionalProperties { get; set; }
+    public IList<JToken> Enum { get; set; }
+    public JsonSchemaType Disallow { get; set; }
+
+    public JsonSchemaModel()
+    {
+      Type = JsonSchemaType.Any;
+      AllowAdditionalProperties = true;
+      Required = false;
+    }
+
+    public static JsonSchemaModel Create(IList<JsonSchema> schemata)
+    {
+      JsonSchemaModel model = new JsonSchemaModel();
+
+      foreach (JsonSchema schema in schemata)
+      {
+        Combine(model, schema);
+      }
+
+      return model;
+    }
+
+    private static void Combine(JsonSchemaModel model, JsonSchema schema)
+    {
+      // Version 3 of the Draft JSON Schema has the default value of Not Required
+      model.Required = model.Required || (schema.Required ?? false);
+      model.Type = model.Type & (schema.Type ?? JsonSchemaType.Any);
+
+      model.MinimumLength = MathUtils.Max(model.MinimumLength, schema.MinimumLength);
+      model.MaximumLength = MathUtils.Min(model.MaximumLength, schema.MaximumLength);
+
+      // not sure what is the best way to combine divisibleBy
+      model.DivisibleBy = MathUtils.Max(model.DivisibleBy, schema.DivisibleBy);
+
+      model.Minimum = MathUtils.Max(model.Minimum, schema.Minimum);
+      model.Maximum = MathUtils.Max(model.Maximum, schema.Maximum);
+      model.ExclusiveMinimum = model.ExclusiveMinimum || (schema.ExclusiveMinimum ?? false);
+      model.ExclusiveMaximum = model.ExclusiveMaximum || (schema.ExclusiveMaximum ?? false);
+
+      model.MinimumItems = MathUtils.Max(model.MinimumItems, schema.MinimumItems);
+      model.MaximumItems = MathUtils.Min(model.MaximumItems, schema.MaximumItems);
+      model.AllowAdditionalProperties = model.AllowAdditionalProperties && schema.AllowAdditionalProperties;
+      if (schema.Enum != null)
+      {
+        if (model.Enum == null)
+          model.Enum = new List<JToken>();
+
+        model.Enum.AddRangeDistinct(schema.Enum, new JTokenEqualityComparer());
+      }
+      model.Disallow = model.Disallow | (schema.Disallow ?? JsonSchemaType.None);
+
+      if (schema.Pattern != null)
+      {
+        if (model.Patterns == null)
+          model.Patterns = new List<string>();
+
+        model.Patterns.AddDistinct(schema.Pattern);
+      }
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaModelBuilder.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaModelBuilder.cs
index 5c7d3b2..3ee968f 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaModelBuilder.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaModelBuilder.cs
@@ -1,159 +1,175 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Newtonsoft.Json.Schema
-{
-  internal class JsonSchemaModelBuilder
-  {
-    private JsonSchemaNodeCollection _nodes = new JsonSchemaNodeCollection();
-    private Dictionary<JsonSchemaNode, JsonSchemaModel> _nodeModels = new Dictionary<JsonSchemaNode, JsonSchemaModel>();
-    private JsonSchemaNode _node ;
-
-    public JsonSchemaModel Build(JsonSchema schema)
-    {
-      _nodes = new JsonSchemaNodeCollection();
-      _node = AddSchema(null, schema);
-
-      _nodeModels = new Dictionary<JsonSchemaNode, JsonSchemaModel>();
-      JsonSchemaModel model = BuildNodeModel(_node);
-
-      return model;
-    }
-
-    public JsonSchemaNode AddSchema(JsonSchemaNode existingNode, JsonSchema schema)
-    {
-      string newId;
-      if (existingNode != null)
-      {
-        if (existingNode.Schemas.Contains(schema))
-          return existingNode;
-
-        newId = JsonSchemaNode.GetId(existingNode.Schemas.Union(new[] { schema }));
-      }
-      else
-      {
-        newId = JsonSchemaNode.GetId(new[] { schema });
-      }
-
-      if (_nodes.Contains(newId))
-        return _nodes[newId];
-
-      JsonSchemaNode currentNode = (existingNode != null)
-        ? existingNode.Combine(schema)
-        : new JsonSchemaNode(schema);
-
-      _nodes.Add(currentNode);
-
-      if (schema.Properties != null)
-      {
-        foreach (KeyValuePair<string, JsonSchema> property in schema.Properties)
-        {
-          AddProperty(currentNode, property.Key, property.Value);
-        }
-      }
-
-      if (schema.Items != null)
-      {
-        for (int i = 0; i < schema.Items.Count; i++)
-        {
-          AddItem(currentNode, i, schema.Items[i]);
-        }
-      }
-
-      if (schema.AdditionalProperties != null)
-        AddAdditionalProperties(currentNode, schema.AdditionalProperties);
-
-      if (schema.Extends != null)
-        currentNode = AddSchema(currentNode, schema.Extends);
-
-      return currentNode;
-    }
-
-    public void AddProperty(JsonSchemaNode parentNode, string propertyName, JsonSchema schema)
-    {
-      JsonSchemaNode propertyNode;
-      parentNode.Properties.TryGetValue(propertyName, out propertyNode);
-
-      parentNode.Properties[propertyName] = AddSchema(propertyNode, schema);
-    }
-
-    public void AddItem(JsonSchemaNode parentNode, int index, JsonSchema schema)
-    {
-      JsonSchemaNode existingItemNode = (parentNode.Items.Count > index)
-                                  ? parentNode.Items[index]
-                                  : null;
-
-      JsonSchemaNode newItemNode = AddSchema(existingItemNode, schema);
-      
-      if (!(parentNode.Items.Count > index))
-      {
-        parentNode.Items.Add(newItemNode);
-      }
-      else
-      {
-        parentNode.Items[index] = newItemNode;
-      }
-    }
-
-    public void AddAdditionalProperties(JsonSchemaNode parentNode, JsonSchema schema)
-    {
-      parentNode.AdditionalProperties = AddSchema(parentNode.AdditionalProperties, schema);
-    }
-
-    private JsonSchemaModel BuildNodeModel(JsonSchemaNode node)
-    {
-      JsonSchemaModel model;
-      if (_nodeModels.TryGetValue(node, out model))
-        return model;
-      
-      model = JsonSchemaModel.Create(node.Schemas);
-      _nodeModels[node] = model;
-
-      foreach (KeyValuePair<string, JsonSchemaNode> property in node.Properties)
-      {
-        if (model.Properties == null)
-          model.Properties = new Dictionary<string, JsonSchemaModel>();
-
-        model.Properties[property.Key] = BuildNodeModel(property.Value);
-      }
-      for (int i = 0; i < node.Items.Count; i++)
-      {
-        if (model.Items == null)
-          model.Items = new List<JsonSchemaModel>();
-
-        model.Items.Add(BuildNodeModel(node.Items[i]));
-      }
-      if (node.AdditionalProperties != null)
-        model.AdditionalProperties = BuildNodeModel(node.AdditionalProperties);
-
-      return model;
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System.Collections.Generic;
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#else
+using System.Linq;
+#endif
+
+namespace Newtonsoft.Json.Schema
+{
+  internal class JsonSchemaModelBuilder
+  {
+    private JsonSchemaNodeCollection _nodes = new JsonSchemaNodeCollection();
+    private Dictionary<JsonSchemaNode, JsonSchemaModel> _nodeModels = new Dictionary<JsonSchemaNode, JsonSchemaModel>();
+    private JsonSchemaNode _node ;
+
+    public JsonSchemaModel Build(JsonSchema schema)
+    {
+      _nodes = new JsonSchemaNodeCollection();
+      _node = AddSchema(null, schema);
+
+      _nodeModels = new Dictionary<JsonSchemaNode, JsonSchemaModel>();
+      JsonSchemaModel model = BuildNodeModel(_node);
+
+      return model;
+    }
+
+    public JsonSchemaNode AddSchema(JsonSchemaNode existingNode, JsonSchema schema)
+    {
+      string newId;
+      if (existingNode != null)
+      {
+        if (existingNode.Schemas.Contains(schema))
+          return existingNode;
+
+        newId = JsonSchemaNode.GetId(existingNode.Schemas.Union(new[] { schema }));
+      }
+      else
+      {
+        newId = JsonSchemaNode.GetId(new[] { schema });
+      }
+
+      if (_nodes.Contains(newId))
+        return _nodes[newId];
+
+      JsonSchemaNode currentNode = (existingNode != null)
+        ? existingNode.Combine(schema)
+        : new JsonSchemaNode(schema);
+
+      _nodes.Add(currentNode);
+
+      AddProperties(schema.Properties, currentNode.Properties);
+
+      AddProperties(schema.PatternProperties, currentNode.PatternProperties);
+
+      if (schema.Items != null)
+      {
+        for (int i = 0; i < schema.Items.Count; i++)
+        {
+          AddItem(currentNode, i, schema.Items[i]);
+        }
+      }
+
+      if (schema.AdditionalProperties != null)
+        AddAdditionalProperties(currentNode, schema.AdditionalProperties);
+
+      if (schema.Extends != null)
+        currentNode = AddSchema(currentNode, schema.Extends);
+
+      return currentNode;
+    }
+
+    public void AddProperties(IDictionary<string, JsonSchema> source, IDictionary<string, JsonSchemaNode> target)
+    {
+      if (source != null)
+      {
+        foreach (KeyValuePair<string, JsonSchema> property in source)
+        {
+          AddProperty(target, property.Key, property.Value);
+        }
+      }
+    }
+
+    public void AddProperty(IDictionary<string, JsonSchemaNode> target, string propertyName, JsonSchema schema)
+    {
+      JsonSchemaNode propertyNode;
+      target.TryGetValue(propertyName, out propertyNode);
+
+      target[propertyName] = AddSchema(propertyNode, schema);
+    }
+
+    public void AddItem(JsonSchemaNode parentNode, int index, JsonSchema schema)
+    {
+      JsonSchemaNode existingItemNode = (parentNode.Items.Count > index)
+                                  ? parentNode.Items[index]
+                                  : null;
+
+      JsonSchemaNode newItemNode = AddSchema(existingItemNode, schema);
+      
+      if (!(parentNode.Items.Count > index))
+      {
+        parentNode.Items.Add(newItemNode);
+      }
+      else
+      {
+        parentNode.Items[index] = newItemNode;
+      }
+    }
+
+    public void AddAdditionalProperties(JsonSchemaNode parentNode, JsonSchema schema)
+    {
+      parentNode.AdditionalProperties = AddSchema(parentNode.AdditionalProperties, schema);
+    }
+
+    private JsonSchemaModel BuildNodeModel(JsonSchemaNode node)
+    {
+      JsonSchemaModel model;
+      if (_nodeModels.TryGetValue(node, out model))
+        return model;
+      
+      model = JsonSchemaModel.Create(node.Schemas);
+      _nodeModels[node] = model;
+
+      foreach (KeyValuePair<string, JsonSchemaNode> property in node.Properties)
+      {
+        if (model.Properties == null)
+          model.Properties = new Dictionary<string, JsonSchemaModel>();
+
+        model.Properties[property.Key] = BuildNodeModel(property.Value);
+      }
+      foreach (KeyValuePair<string, JsonSchemaNode> property in node.PatternProperties)
+      {
+        if (model.PatternProperties == null)
+          model.PatternProperties = new Dictionary<string, JsonSchemaModel>();
+
+        model.PatternProperties[property.Key] = BuildNodeModel(property.Value);
+      }
+      foreach (JsonSchemaNode t in node.Items)
+      {
+        if (model.Items == null)
+          model.Items = new List<JsonSchemaModel>();
+
+        model.Items.Add(BuildNodeModel(t));
+      }
+      if (node.AdditionalProperties != null)
+        model.AdditionalProperties = BuildNodeModel(node.AdditionalProperties);
+
+      return model;
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaNode.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaNode.cs
index 33f4558..01b2c18 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaNode.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaNode.cs
@@ -1,70 +1,77 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Linq;
-
-namespace Newtonsoft.Json.Schema
-{
-  internal class JsonSchemaNode
-  {
-    public string Id { get; private set; }
-    public ReadOnlyCollection<JsonSchema> Schemas { get; private set; }
-    public Dictionary<string, JsonSchemaNode> Properties { get; private set; }
-    public List<JsonSchemaNode> Items { get; private set; }
-    public JsonSchemaNode AdditionalProperties { get; set; }
-
-    public JsonSchemaNode(JsonSchema schema)
-    {
-      Schemas = new ReadOnlyCollection<JsonSchema>(new []{ schema });
-      Properties = new Dictionary<string, JsonSchemaNode>();
-      Items = new List<JsonSchemaNode>();
-
-      Id = GetId(Schemas);
-    }
-
-    private JsonSchemaNode(JsonSchemaNode source, JsonSchema schema)
-    {
-      Schemas = new ReadOnlyCollection<JsonSchema>(source.Schemas.Union(new[] { schema }).ToList());
-      Properties = new Dictionary<string, JsonSchemaNode>(source.Properties);
-      Items = new List<JsonSchemaNode>(source.Items);
-      AdditionalProperties = source.AdditionalProperties;
-
-      Id = GetId(Schemas);
-    }
-
-    public JsonSchemaNode Combine(JsonSchema schema)
-    {
-      return new JsonSchemaNode(this, schema);
-    }
-
-    public static string GetId(IEnumerable<JsonSchema> schemata)
-    {
-      return string.Join("-", schemata.Select(s => s.InternalId).OrderBy(id => id, StringComparer.Ordinal).ToArray());
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#else
+using System.Linq;
+#endif
+
+namespace Newtonsoft.Json.Schema
+{
+  internal class JsonSchemaNode
+  {
+    public string Id { get; private set; }
+    public ReadOnlyCollection<JsonSchema> Schemas { get; private set; }
+    public Dictionary<string, JsonSchemaNode> Properties { get; private set; }
+    public Dictionary<string, JsonSchemaNode> PatternProperties { get; private set; }
+    public List<JsonSchemaNode> Items { get; private set; }
+    public JsonSchemaNode AdditionalProperties { get; set; }
+
+    public JsonSchemaNode(JsonSchema schema)
+    {
+      Schemas = new ReadOnlyCollection<JsonSchema>(new []{ schema });
+      Properties = new Dictionary<string, JsonSchemaNode>();
+      PatternProperties = new Dictionary<string, JsonSchemaNode>();
+      Items = new List<JsonSchemaNode>();
+
+      Id = GetId(Schemas);
+    }
+
+    private JsonSchemaNode(JsonSchemaNode source, JsonSchema schema)
+    {
+      Schemas = new ReadOnlyCollection<JsonSchema>(source.Schemas.Union(new[] { schema }).ToList());
+      Properties = new Dictionary<string, JsonSchemaNode>(source.Properties);
+      PatternProperties = new Dictionary<string, JsonSchemaNode>(source.PatternProperties);
+      Items = new List<JsonSchemaNode>(source.Items);
+      AdditionalProperties = source.AdditionalProperties;
+
+      Id = GetId(Schemas);
+    }
+
+    public JsonSchemaNode Combine(JsonSchema schema)
+    {
+      return new JsonSchemaNode(this, schema);
+    }
+
+    public static string GetId(IEnumerable<JsonSchema> schemata)
+    {
+      return string.Join("-", schemata.Select(s => s.InternalId).OrderBy(id => id, StringComparer.Ordinal).ToArray());
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaNodeCollection.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaNodeCollection.cs
index 69fd541..5f2ef01 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaNodeCollection.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaNodeCollection.cs
@@ -1,37 +1,37 @@
-#region License
-// 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.
-#endregion
-
-using System.Collections.ObjectModel;
-
-namespace Newtonsoft.Json.Schema
-{
-  internal class JsonSchemaNodeCollection : KeyedCollection<string, JsonSchemaNode>
-  {
-    protected override string GetKeyForItem(JsonSchemaNode item)
-    {
-      return item.Id;
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System.Collections.ObjectModel;
+
+namespace Newtonsoft.Json.Schema
+{
+  internal class JsonSchemaNodeCollection : KeyedCollection<string, JsonSchemaNode>
+  {
+    protected override string GetKeyForItem(JsonSchemaNode item)
+    {
+      return item.Id;
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaResolver.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaResolver.cs
index d7c514f..e228acd 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaResolver.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaResolver.cs
@@ -1,66 +1,65 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Text;
-using System.Globalization;
-using Newtonsoft.Json.Utilities;
-
-namespace Newtonsoft.Json.Schema
-{
-  /// <summary>
-  /// Resolves <see cref="JsonSchema"/> from an id.
-  /// </summary>
-  public class JsonSchemaResolver
-  {
-    /// <summary>
-    /// Gets or sets the loaded schemas.
-    /// </summary>
-    /// <value>The loaded schemas.</value>
-    public IList<JsonSchema> LoadedSchemas { get; protected set; }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonSchemaResolver"/> class.
-    /// </summary>
-    public JsonSchemaResolver()
-    {
-      LoadedSchemas = new List<JsonSchema>();
-    }
-
-    /// <summary>
-    /// Gets a <see cref="JsonSchema"/> for the specified id.
-    /// </summary>
-    /// <param name="id">The id.</param>
-    /// <returns>A <see cref="JsonSchema"/> for the specified id.</returns>
-    public virtual JsonSchema GetSchema(string id)
-    {
-      JsonSchema schema = LoadedSchemas.SingleOrDefault(s => s.Id == id);
-      return schema;
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System.Collections.Generic;
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#else
+using System.Linq;
+#endif
+
+namespace Newtonsoft.Json.Schema
+{
+  /// <summary>
+  /// Resolves <see cref="JsonSchema"/> from an id.
+  /// </summary>
+  public class JsonSchemaResolver
+  {
+    /// <summary>
+    /// Gets or sets the loaded schemas.
+    /// </summary>
+    /// <value>The loaded schemas.</value>
+    public IList<JsonSchema> LoadedSchemas { get; protected set; }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonSchemaResolver"/> class.
+    /// </summary>
+    public JsonSchemaResolver()
+    {
+      LoadedSchemas = new List<JsonSchema>();
+    }
+
+    /// <summary>
+    /// Gets a <see cref="JsonSchema"/> for the specified id.
+    /// </summary>
+    /// <param name="id">The id.</param>
+    /// <returns>A <see cref="JsonSchema"/> for the specified id.</returns>
+    public virtual JsonSchema GetSchema(string id)
+    {
+      JsonSchema schema = LoadedSchemas.SingleOrDefault(s => s.Id == id);
+      return schema;
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaType.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaType.cs
index bf7c1fb..160a4fc 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaType.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaType.cs
@@ -1,76 +1,73 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Newtonsoft.Json.Schema
-{
-  /// <summary>
-  /// The value types allowed by the <see cref="JsonSchema"/>.
-  /// </summary>
-  [Flags]
-  public enum JsonSchemaType
-  {
-    /// <summary>
-    /// No type specified.
-    /// </summary>
-    None = 0,
-    /// <summary>
-    /// String type.
-    /// </summary>
-    String = 1,
-    /// <summary>
-    /// Float type.
-    /// </summary>
-    Float = 2,
-    /// <summary>
-    /// Integer type.
-    /// </summary>
-    Integer = 4,
-    /// <summary>
-    /// Boolean type.
-    /// </summary>
-    Boolean = 8,
-    /// <summary>
-    /// Object type.
-    /// </summary>
-    Object = 16,
-    /// <summary>
-    /// Array type.
-    /// </summary>
-    Array = 32,
-    /// <summary>
-    /// Null type.
-    /// </summary>
-    Null = 64,
-    /// <summary>
-    /// Any type.
-    /// </summary>
-    Any = String | Float | Integer | Boolean | Object | Array | Null
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json.Schema
+{
+  /// <summary>
+  /// The value types allowed by the <see cref="JsonSchema"/>.
+  /// </summary>
+  [Flags]
+  public enum JsonSchemaType
+  {
+    /// <summary>
+    /// No type specified.
+    /// </summary>
+    None = 0,
+    /// <summary>
+    /// String type.
+    /// </summary>
+    String = 1,
+    /// <summary>
+    /// Float type.
+    /// </summary>
+    Float = 2,
+    /// <summary>
+    /// Integer type.
+    /// </summary>
+    Integer = 4,
+    /// <summary>
+    /// Boolean type.
+    /// </summary>
+    Boolean = 8,
+    /// <summary>
+    /// Object type.
+    /// </summary>
+    Object = 16,
+    /// <summary>
+    /// Array type.
+    /// </summary>
+    Array = 32,
+    /// <summary>
+    /// Null type.
+    /// </summary>
+    Null = 64,
+    /// <summary>
+    /// Any type.
+    /// </summary>
+    Any = String | Float | Integer | Boolean | Object | Array | Null
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaWriter.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaWriter.cs
index 2d5d2a6..0745995 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaWriter.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaWriter.cs
@@ -1,213 +1,223 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Newtonsoft.Json.Linq;
-using Newtonsoft.Json.Utilities;
-
-namespace Newtonsoft.Json.Schema
-{
-  internal class JsonSchemaWriter
-  {
-    private readonly JsonWriter _writer;
-    private readonly JsonSchemaResolver _resolver;
-
-    public JsonSchemaWriter(JsonWriter writer, JsonSchemaResolver resolver)
-    {
-      ValidationUtils.ArgumentNotNull(writer, "writer");
-      _writer = writer;
-      _resolver = resolver;
-    }
-
-    private void ReferenceOrWriteSchema(JsonSchema schema)
-    {
-      if (schema.Id != null && _resolver.GetSchema(schema.Id) != null)
-      {
-        _writer.WriteStartObject();
-        _writer.WritePropertyName(JsonSchemaConstants.ReferencePropertyName);
-        _writer.WriteValue(schema.Id);
-        _writer.WriteEndObject();
-      }
-      else
-      {
-        WriteSchema(schema);
-      }
-    }
-
-    public void WriteSchema(JsonSchema schema)
-    {
-      ValidationUtils.ArgumentNotNull(schema, "schema");
-
-      if (!_resolver.LoadedSchemas.Contains(schema))
-        _resolver.LoadedSchemas.Add(schema);
-
-      _writer.WriteStartObject();
-      WritePropertyIfNotNull(_writer, JsonSchemaConstants.IdPropertyName, schema.Id);
-      WritePropertyIfNotNull(_writer, JsonSchemaConstants.TitlePropertyName, schema.Title);
-      WritePropertyIfNotNull(_writer, JsonSchemaConstants.DescriptionPropertyName, schema.Description);
-      WritePropertyIfNotNull(_writer, JsonSchemaConstants.OptionalPropertyName, schema.Optional);
-      WritePropertyIfNotNull(_writer, JsonSchemaConstants.ReadOnlyPropertyName, schema.ReadOnly);
-      WritePropertyIfNotNull(_writer, JsonSchemaConstants.HiddenPropertyName, schema.Hidden);
-      WritePropertyIfNotNull(_writer, JsonSchemaConstants.TransientPropertyName, schema.Transient);
-      if (schema.Type != null)
-        WriteType(JsonSchemaConstants.TypePropertyName, _writer, schema.Type.Value);
-      if (!schema.AllowAdditionalProperties)
-      {
-        _writer.WritePropertyName(JsonSchemaConstants.AdditionalPropertiesPropertyName);
-        _writer.WriteValue(schema.AllowAdditionalProperties);
-      }
-      else
-      {
-        if (schema.AdditionalProperties != null)
-        {
-          _writer.WritePropertyName(JsonSchemaConstants.AdditionalPropertiesPropertyName);
-          ReferenceOrWriteSchema(schema.AdditionalProperties);
-        }
-      }
-      if (schema.Properties != null)
-      {
-        _writer.WritePropertyName(JsonSchemaConstants.PropertiesPropertyName);
-        _writer.WriteStartObject();
-        foreach (KeyValuePair<string, JsonSchema> property in schema.Properties)
-        {
-          _writer.WritePropertyName(property.Key);
-          ReferenceOrWriteSchema(property.Value);
-        }
-        _writer.WriteEndObject();
-      }
-      WriteItems(schema);
-      WritePropertyIfNotNull(_writer, JsonSchemaConstants.MinimumPropertyName, schema.Minimum);
-      WritePropertyIfNotNull(_writer, JsonSchemaConstants.MaximumPropertyName, schema.Maximum);
-      WritePropertyIfNotNull(_writer, JsonSchemaConstants.MinimumLengthPropertyName, schema.MinimumLength);
-      WritePropertyIfNotNull(_writer, JsonSchemaConstants.MaximumLengthPropertyName, schema.MaximumLength);
-      WritePropertyIfNotNull(_writer, JsonSchemaConstants.MinimumItemsPropertyName, schema.MinimumItems);
-      WritePropertyIfNotNull(_writer, JsonSchemaConstants.MaximumItemsPropertyName, schema.MaximumItems);
-      WritePropertyIfNotNull(_writer, JsonSchemaConstants.MaximumDecimalsPropertyName, schema.MaximumDecimals);
-      WritePropertyIfNotNull(_writer, JsonSchemaConstants.FormatPropertyName, schema.Format);
-      WritePropertyIfNotNull(_writer, JsonSchemaConstants.PatternPropertyName, schema.Pattern);
-      if (schema.Enum != null)
-      {
-        _writer.WritePropertyName(JsonSchemaConstants.EnumPropertyName);
-        _writer.WriteStartArray();
-        foreach (JToken token in schema.Enum)
-        {
-          token.WriteTo(_writer);
-        }
-        _writer.WriteEndArray();
-      }
-      if (schema.Default != null)
-      {
-        _writer.WritePropertyName(JsonSchemaConstants.DefaultPropertyName);
-        schema.Default.WriteTo(_writer);
-      }
-      if (schema.Options != null)
-      {
-        _writer.WritePropertyName(JsonSchemaConstants.OptionsPropertyName);
-        _writer.WriteStartArray();
-        foreach (KeyValuePair<JToken, string> option in schema.Options)
-        {
-          _writer.WriteStartObject();
-          _writer.WritePropertyName(JsonSchemaConstants.OptionValuePropertyName);
-          option.Key.WriteTo(_writer);
-          if (option.Value != null)
-          {
-            _writer.WritePropertyName(JsonSchemaConstants.OptionValuePropertyName);
-            _writer.WriteValue(option.Value);
-          }
-          _writer.WriteEndObject();
-        }
-        _writer.WriteEndArray();
-      }
-      if (schema.Disallow != null)
-        WriteType(JsonSchemaConstants.DisallowPropertyName, _writer, schema.Disallow.Value);
-      if (schema.Extends != null)
-      {
-        _writer.WritePropertyName(JsonSchemaConstants.ExtendsPropertyName);
-        ReferenceOrWriteSchema(schema.Extends);
-      }
-      _writer.WriteEndObject();
-    }
-
-    private void WriteItems(JsonSchema schema)
-    {
-      if (CollectionUtils.IsNullOrEmpty(schema.Items))
-        return;
-
-      _writer.WritePropertyName(JsonSchemaConstants.ItemsPropertyName);
-
-      if (schema.Items.Count == 1)
-      {
-        ReferenceOrWriteSchema(schema.Items[0]);
-        return;
-      }
-
-      _writer.WriteStartArray();
-      foreach (JsonSchema itemSchema in schema.Items)
-      {
-        ReferenceOrWriteSchema(itemSchema);
-      }
-      _writer.WriteEndArray();
-    }
-
-    private void WriteType(string propertyName, JsonWriter writer, JsonSchemaType type)
-    {
-      IList<JsonSchemaType> types;
-      if (System.Enum.IsDefined(typeof(JsonSchemaType), type))
-        types = new List<JsonSchemaType> { type };
-      else
-        types = EnumUtils.GetFlagsValues(type).Where(v => v != JsonSchemaType.None).ToList();
-
-      if (types.Count == 0)
-        return;
-
-      writer.WritePropertyName(propertyName);
-
-      if (types.Count == 1)
-      {
-        writer.WriteValue(JsonSchemaBuilder.MapType(types[0]));
-        return;
-      }
-
-      writer.WriteStartArray();
-      foreach (JsonSchemaType jsonSchemaType in types)
-      {
-        writer.WriteValue(JsonSchemaBuilder.MapType(jsonSchemaType));
-      }
-      writer.WriteEndArray();
-    }
-
-    private void WritePropertyIfNotNull(JsonWriter writer, string propertyName, object value)
-    {
-      if (value != null)
-      {
-        writer.WritePropertyName(propertyName);
-        writer.WriteValue(value);
-      }
-    }
-  }
-}
+#region License
+// 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.
+#endregion
+
+using System.Collections.Generic;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Utilities;
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#else
+using System.Linq;
+#endif
+
+namespace Newtonsoft.Json.Schema
+{
+  internal class JsonSchemaWriter
+  {
+    private readonly JsonWriter _writer;
+    private readonly JsonSchemaResolver _resolver;
+
+    public JsonSchemaWriter(JsonWriter writer, JsonSchemaResolver resolver)
+    {
+      ValidationUtils.ArgumentNotNull(writer, "writer");
+      _writer = writer;
+      _resolver = resolver;
+    }
+
+    private void ReferenceOrWriteSchema(JsonSchema schema)
+    {
+      if (schema.Id != null && _resolver.GetSchema(schema.Id) != null)
+      {
+        _writer.WriteStartObject();
+        _writer.WritePropertyName(JsonSchemaConstants.ReferencePropertyName);
+        _writer.WriteValue(schema.Id);
+        _writer.WriteEndObject();
+      }
+      else
+      {
+        WriteSchema(schema);
+      }
+    }
+
+    public void WriteSchema(JsonSchema schema)
+    {
+      ValidationUtils.ArgumentNotNull(schema, "schema");
+
+      if (!_resolver.LoadedSchemas.Contains(schema))
+        _resolver.LoadedSchemas.Add(schema);
+
+      _writer.WriteStartObject();
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.IdPropertyName, schema.Id);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.TitlePropertyName, schema.Title);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.DescriptionPropertyName, schema.Description);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.RequiredPropertyName, schema.Required);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.ReadOnlyPropertyName, schema.ReadOnly);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.HiddenPropertyName, schema.Hidden);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.TransientPropertyName, schema.Transient);
+      if (schema.Type != null)
+        WriteType(JsonSchemaConstants.TypePropertyName, _writer, schema.Type.Value);
+      if (!schema.AllowAdditionalProperties)
+      {
+        _writer.WritePropertyName(JsonSchemaConstants.AdditionalPropertiesPropertyName);
+        _writer.WriteValue(schema.AllowAdditionalProperties);
+      }
+      else
+      {
+        if (schema.AdditionalProperties != null)
+        {
+          _writer.WritePropertyName(JsonSchemaConstants.AdditionalPropertiesPropertyName);
+          ReferenceOrWriteSchema(schema.AdditionalProperties);
+        }
+      }
+      WriteSchemaDictionaryIfNotNull(_writer, JsonSchemaConstants.PropertiesPropertyName, schema.Properties);
+      WriteSchemaDictionaryIfNotNull(_writer, JsonSchemaConstants.PatternPropertiesPropertyName, schema.PatternProperties);
+      WriteItems(schema);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.MinimumPropertyName, schema.Minimum);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.MaximumPropertyName, schema.Maximum);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.ExclusiveMinimumPropertyName, schema.ExclusiveMinimum);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.ExclusiveMaximumPropertyName, schema.ExclusiveMaximum);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.MinimumLengthPropertyName, schema.MinimumLength);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.MaximumLengthPropertyName, schema.MaximumLength);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.MinimumItemsPropertyName, schema.MinimumItems);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.MaximumItemsPropertyName, schema.MaximumItems);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.DivisibleByPropertyName, schema.DivisibleBy);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.FormatPropertyName, schema.Format);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.PatternPropertyName, schema.Pattern);
+      if (schema.Enum != null)
+      {
+        _writer.WritePropertyName(JsonSchemaConstants.EnumPropertyName);
+        _writer.WriteStartArray();
+        foreach (JToken token in schema.Enum)
+        {
+          token.WriteTo(_writer);
+        }
+        _writer.WriteEndArray();
+      }
+      if (schema.Default != null)
+      {
+        _writer.WritePropertyName(JsonSchemaConstants.DefaultPropertyName);
+        schema.Default.WriteTo(_writer);
+      }
+      if (schema.Options != null)
+      {
+        _writer.WritePropertyName(JsonSchemaConstants.OptionsPropertyName);
+        _writer.WriteStartArray();
+        foreach (KeyValuePair<JToken, string> option in schema.Options)
+        {
+          _writer.WriteStartObject();
+          _writer.WritePropertyName(JsonSchemaConstants.OptionValuePropertyName);
+          option.Key.WriteTo(_writer);
+          if (option.Value != null)
+          {
+            _writer.WritePropertyName(JsonSchemaConstants.OptionLabelPropertyName);
+            _writer.WriteValue(option.Value);
+          }
+          _writer.WriteEndObject();
+        }
+        _writer.WriteEndArray();
+      }
+      if (schema.Disallow != null)
+        WriteType(JsonSchemaConstants.DisallowPropertyName, _writer, schema.Disallow.Value);
+      if (schema.Extends != null)
+      {
+        _writer.WritePropertyName(JsonSchemaConstants.ExtendsPropertyName);
+        ReferenceOrWriteSchema(schema.Extends);
+      }
+      _writer.WriteEndObject();
+    }
+
+    private void WriteSchemaDictionaryIfNotNull(JsonWriter writer, string propertyName, IDictionary<string, JsonSchema> properties)
+    {
+      if (properties != null)
+      {
+        writer.WritePropertyName(propertyName);
+        writer.WriteStartObject();
+        foreach (KeyValuePair<string, JsonSchema> property in properties)
+        {
+          writer.WritePropertyName(property.Key);
+          ReferenceOrWriteSchema(property.Value);
+        }
+        writer.WriteEndObject();
+      }
+    }
+
+    private void WriteItems(JsonSchema schema)
+    {
+      if (CollectionUtils.IsNullOrEmpty(schema.Items))
+        return;
+
+      _writer.WritePropertyName(JsonSchemaConstants.ItemsPropertyName);
+
+      if (schema.Items.Count == 1)
+      {
+        ReferenceOrWriteSchema(schema.Items[0]);
+        return;
+      }
+
+      _writer.WriteStartArray();
+      foreach (JsonSchema itemSchema in schema.Items)
+      {
+        ReferenceOrWriteSchema(itemSchema);
+      }
+      _writer.WriteEndArray();
+    }
+
+    private void WriteType(string propertyName, JsonWriter writer, JsonSchemaType type)
+    {
+      IList<JsonSchemaType> types;
+      if (System.Enum.IsDefined(typeof(JsonSchemaType), type))
+        types = new List<JsonSchemaType> { type };
+      else
+        types = EnumUtils.GetFlagsValues(type).Where(v => v != JsonSchemaType.None).ToList();
+
+      if (types.Count == 0)
+        return;
+
+      writer.WritePropertyName(propertyName);
+
+      if (types.Count == 1)
+      {
+        writer.WriteValue(JsonSchemaBuilder.MapType(types[0]));
+        return;
+      }
+
+      writer.WriteStartArray();
+      foreach (JsonSchemaType jsonSchemaType in types)
+      {
+        writer.WriteValue(JsonSchemaBuilder.MapType(jsonSchemaType));
+      }
+      writer.WriteEndArray();
+    }
+
+    private void WritePropertyIfNotNull(JsonWriter writer, string propertyName, object value)
+    {
+      if (value != null)
+      {
+        writer.WritePropertyName(propertyName);
+        writer.WriteValue(value);
+      }
+    }
+  }
+}
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/UndefinedSchemaIdHandling.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/UndefinedSchemaIdHandling.cs
index c38225d..34bbbee 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/UndefinedSchemaIdHandling.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/UndefinedSchemaIdHandling.cs
@@ -1,46 +1,46 @@
-#region License
-// 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.
-#endregion
-
-namespace Newtonsoft.Json.Schema
-{
-  /// <summary>
-  /// Specifies undefined schema Id handling options for the <see cref="JsonSchemaGenerator"/>.
-  /// </summary>
-  public enum UndefinedSchemaIdHandling
-  {
-    /// <summary>
-    /// Do not infer a schema Id.
-    /// </summary>
-    None = 0,
-    /// <summary>
-    /// Use the .NET type name as the schema Id.
-    /// </summary>
-    UseTypeName = 1,
-    /// <summary>
-    /// Use the assembly qualified .NET type name as the schema Id.
-    /// </summary>
-    UseAssemblyQualifiedName = 2,
-  }
+#region License
+// 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.
+#endregion
+
+namespace Newtonsoft.Json.Schema
+{
+  /// <summary>
+  /// Specifies undefined schema Id handling options for the <see cref="JsonSchemaGenerator"/>.
+  /// </summary>
+  public enum UndefinedSchemaIdHandling
+  {
+    /// <summary>
+    /// Do not infer a schema Id.
+    /// </summary>
+    None = 0,
+    /// <summary>
+    /// Use the .NET type name as the schema Id.
+    /// </summary>
+    UseTypeName = 1,
+    /// <summary>
+    /// Use the assembly qualified .NET type name as the schema Id.
+    /// </summary>
+    UseAssemblyQualifiedName = 2,
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/ValidationEventArgs.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/ValidationEventArgs.cs
index 3b2b107..b6b94f2 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/ValidationEventArgs.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/ValidationEventArgs.cs
@@ -1,62 +1,71 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using Newtonsoft.Json.Utilities;
-
-namespace Newtonsoft.Json.Schema
-{
-  /// <summary>
-  /// Returns detailed information related to the <see cref="ValidationEventHandler"/>.
-  /// </summary>
-  public class ValidationEventArgs : EventArgs
-  {
-    private readonly JsonSchemaException _ex;
-
-    internal ValidationEventArgs(JsonSchemaException ex)
-    {
-      ValidationUtils.ArgumentNotNull(ex, "ex");
-      _ex = ex;
-    }
-
-    /// <summary>
-    /// Gets the <see cref="JsonSchemaException"/> associated with the validation event.
-    /// </summary>
-    /// <value>The JsonSchemaException associated with the validation event.</value>
-    public JsonSchemaException Exception
-    {
-      get { return _ex; }
-    }
-
-    /// <summary>
-    /// Gets the text description corresponding to the validation event.
-    /// </summary>
-    /// <value>The text description.</value>
-    public string Message
-    {
-      get { return _ex.Message; }
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Schema
+{
+  /// <summary>
+  /// Returns detailed information related to the <see cref="ValidationEventHandler"/>.
+  /// </summary>
+  public class ValidationEventArgs : EventArgs
+  {
+    private readonly JsonSchemaException _ex;
+
+    internal ValidationEventArgs(JsonSchemaException ex)
+    {
+      ValidationUtils.ArgumentNotNull(ex, "ex");
+      _ex = ex;
+    }
+
+    /// <summary>
+    /// Gets the <see cref="JsonSchemaException"/> associated with the validation error.
+    /// </summary>
+    /// <value>The JsonSchemaException associated with the validation error.</value>
+    public JsonSchemaException Exception
+    {
+      get { return _ex; }
+    }
+
+    /// <summary>
+    /// Gets the path of the JSON location where the validation error occurred.
+    /// </summary>
+    /// <value>The path of the JSON location where the validation error occurred.</value>
+    public string Path
+    {
+      get { return _ex.Path; }
+    }
+
+    /// <summary>
+    /// Gets the text description corresponding to the validation error.
+    /// </summary>
+    /// <value>The text description.</value>
+    public string Message
+    {
+      get { return _ex.Message; }
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/ValidationEventHandler.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/ValidationEventHandler.cs
index 54315fa..95d213d 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/ValidationEventHandler.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/ValidationEventHandler.cs
@@ -1,32 +1,32 @@
-#region License
-// 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.
-#endregion
-
-namespace Newtonsoft.Json.Schema
-{
-  /// <summary>
-  /// Represents the callback method that will handle JSON schema validation events and the <see cref="ValidationEventArgs"/>.
-  /// </summary>
-  public delegate void ValidationEventHandler(object sender, ValidationEventArgs e);
+#region License
+// 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.
+#endregion
+
+namespace Newtonsoft.Json.Schema
+{
+  /// <summary>
+  /// Represents the callback method that will handle JSON schema validation events and the <see cref="ValidationEventArgs"/>.
+  /// </summary>
+  public delegate void ValidationEventHandler(object sender, ValidationEventArgs e);
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/CachedAttributeGetter.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/CachedAttributeGetter.cs
index 752d75c..97ba904 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/CachedAttributeGetter.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/CachedAttributeGetter.cs
@@ -1,44 +1,44 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using System.Text;
-using Newtonsoft.Json.Utilities;
-
-namespace Newtonsoft.Json.Serialization
-{
-  internal static class CachedAttributeGetter<T> where T : Attribute
-  {
-    private static readonly ThreadSafeStore<ICustomAttributeProvider, T> TypeAttributeCache = new ThreadSafeStore<ICustomAttributeProvider, T>(JsonTypeReflector.GetAttribute<T>);
-
-    public static T GetAttribute(ICustomAttributeProvider type)
-    {
-      return TypeAttributeCache.Get(type);
-    }
-  }
-}
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Reflection;
+using Newtonsoft.Json.Utilities;
+#if NETFX_CORE || PORTABLE
+using ICustomAttributeProvider = Newtonsoft.Json.Utilities.CustomAttributeProvider;
+#endif
+
+namespace Newtonsoft.Json.Serialization
+{
+  internal static class CachedAttributeGetter<T> where T : Attribute
+  {
+    private static readonly ThreadSafeStore<ICustomAttributeProvider, T> TypeAttributeCache = new ThreadSafeStore<ICustomAttributeProvider, T>(JsonTypeReflector.GetAttribute<T>);
+
+    public static T GetAttribute(ICustomAttributeProvider type)
+    {
+      return TypeAttributeCache.Get(type);
+    }
+  }
+}
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/CamelCasePropertyNamesContractResolver.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/CamelCasePropertyNamesContractResolver.cs
index acda243..e853ec1 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/CamelCasePropertyNamesContractResolver.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/CamelCasePropertyNamesContractResolver.cs
@@ -1,64 +1,55 @@
-#region License
-// 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.
-#endregion
-
-using System.Globalization;
-
-namespace Newtonsoft.Json.Serialization
-{
-  /// <summary>
-  /// Resolves member mappings for a type, camel casing property names.
-  /// </summary>
-  public class CamelCasePropertyNamesContractResolver : DefaultContractResolver
-  {
-    /// <summary>
-    /// Initializes a new instance of the <see cref="CamelCasePropertyNamesContractResolver"/> class.
-    /// </summary>
-    public CamelCasePropertyNamesContractResolver()
-      : base(true)
-    {
-    }
-
-    /// <summary>
-    /// Resolves the name of the property.
-    /// </summary>
-    /// <param name="propertyName">Name of the property.</param>
-    /// <returns>The property name camel cased.</returns>
-    protected override string ResolvePropertyName(string propertyName)
-    {
-      // lower case the first letter of the passed in name
-      if (string.IsNullOrEmpty(propertyName))
-        return propertyName;
-
-      if (!char.IsUpper(propertyName[0]))
-        return propertyName;
-
-      string camelCaseName = char.ToLower(propertyName[0], CultureInfo.InvariantCulture).ToString(CultureInfo.InvariantCulture);
-      if (propertyName.Length > 1)
-        camelCaseName += propertyName.Substring(1);
-
-      return camelCaseName;
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System.Globalization;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Resolves member mappings for a type, camel casing property names.
+  /// </summary>
+  public class CamelCasePropertyNamesContractResolver : DefaultContractResolver
+  {
+    /// <summary>
+    /// Initializes a new instance of the <see cref="CamelCasePropertyNamesContractResolver"/> class.
+    /// </summary>
+    public CamelCasePropertyNamesContractResolver()
+      : base(true)
+    {
+    }
+
+    /// <summary>
+    /// Resolves the name of the property.
+    /// </summary>
+    /// <param name="propertyName">Name of the property.</param>
+    /// <returns>The property name camel cased.</returns>
+    protected internal override string ResolvePropertyName(string propertyName)
+    {
+      // lower case the first letter of the passed in name
+      return StringUtils.ToCamelCase(propertyName);
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs
index 6f5adf7..2e0ab29 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs
@@ -1,715 +1,1097 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Globalization;
-using System.Linq;
-using System.Reflection;
-using System.Runtime.Serialization;
-using System.Security.Permissions;
-using Newtonsoft.Json.Converters;
-using Newtonsoft.Json.Utilities;
-using Newtonsoft.Json.Linq;
-using System.Runtime.CompilerServices;
-
-namespace Newtonsoft.Json.Serialization
-{
-  internal struct ResolverContractKey : IEquatable<ResolverContractKey>
-  {
-    private readonly Type _resolverType;
-    private readonly Type _contractType;
-
-    public ResolverContractKey(Type resolverType, Type contractType)
-    {
-      _resolverType = resolverType;
-      _contractType = contractType;
-    }
-
-    public override int GetHashCode()
-    {
-      return _resolverType.GetHashCode() ^ _contractType.GetHashCode();
-    }
-
-    public override bool Equals(object obj)
-    {
-      if (!(obj is ResolverContractKey))
-        return false;
-
-      return Equals((ResolverContractKey) obj);
-    }
-
-    public bool Equals(ResolverContractKey other)
-    {
-      return (_resolverType == other._resolverType && _contractType == other._contractType);
-    }
-  }
-
-  /// <summary>
-  /// Used by <see cref="JsonSerializer"/> to resolves a <see cref="JsonContract"/> for a given <see cref="Type"/>.
-  /// </summary>
-  public class DefaultContractResolver : IContractResolver
-  {
-    internal static readonly IContractResolver Instance = new DefaultContractResolver(true);
-    private static readonly IList<JsonConverter> BuiltInConverters = new List<JsonConverter>
-      {
-#if !PocketPC && !SILVERLIGHT && !NET20
-        new EntityKeyMemberConverter(),
-#endif
-        new BinaryConverter(),
-        new KeyValuePairConverter(),
-#if !SILVERLIGHT
-        new XmlNodeConverter(),
-        new DataSetConverter(),
-        new DataTableConverter(),
-#endif
-        new BsonObjectIdConverter()
-      };
-
-    private static Dictionary<ResolverContractKey, JsonContract> _sharedContractCache;
-    private static readonly object _typeContractCacheLock = new object();
-
-    private Dictionary<ResolverContractKey, JsonContract> _instanceContractCache;
-    private readonly bool _sharedCache;
-
-    /// <summary>
-    /// Gets a value indicating whether members are being get and set using dynamic code generation.
-    /// This value is determined by the runtime permissions available.
-    /// </summary>
-    /// <value>
-    /// 	<c>true</c> if using dynamic code generation; otherwise, <c>false</c>.
-    /// </value>
-    public bool DynamicCodeGeneration
-    {
-      get { return JsonTypeReflector.DynamicCodeGeneration; }
-    }
-
-    /// <summary>
-    /// Gets or sets the default members search flags.
-    /// </summary>
-    /// <value>The default members search flags.</value>
-    public BindingFlags DefaultMembersSearchFlags { get; set; }
-
-    /// <summary>
-    /// Gets or sets a value indicating whether compiler generated members should be serialized.
-    /// </summary>
-    /// <value>
-    /// 	<c>true</c> if serialized compiler generated members; otherwise, <c>false</c>.
-    /// </value>
-    public bool SerializeCompilerGeneratedMembers { get; set; }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="DefaultContractResolver"/> class.
-    /// </summary>
-    public DefaultContractResolver()
-      : this(false)
-    {
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="DefaultContractResolver"/> class.
-    /// </summary>
-    /// <param name="shareCache">
-    /// If set to <c>true</c> the <see cref="DefaultContractResolver"/> will use a cached shared with other resolvers of the same type.
-    /// Sharing the cache will significantly performance because expensive reflection will only happen once but could cause unexpected
-    /// behavior if different instances of the resolver are suppose to produce different results. When set to false it is highly
-    /// recommended to reuse <see cref="DefaultContractResolver"/> instances with the <see cref="JsonSerializer"/>.
-    /// </param>
-    public DefaultContractResolver(bool shareCache)
-    {
-      DefaultMembersSearchFlags = BindingFlags.Public | BindingFlags.Instance;
-      _sharedCache = shareCache;
-    }
-
-    private Dictionary<ResolverContractKey, JsonContract> GetCache()
-    {
-      if (_sharedCache)
-        return _sharedContractCache;
-      else
-        return _instanceContractCache;
-    }
-
-    private void UpdateCache(Dictionary<ResolverContractKey, JsonContract> cache)
-    {
-      if (_sharedCache)
-        _sharedContractCache = cache;
-      else
-        _instanceContractCache = cache;
-    }
-
-    /// <summary>
-    /// Resolves the contract for a given type.
-    /// </summary>
-    /// <param name="type">The type to resolve a contract for.</param>
-    /// <returns>The contract for a given type.</returns>
-    public virtual JsonContract ResolveContract(Type type)
-    {
-      if (type == null)
-        throw new ArgumentNullException("type");
-
-      JsonContract contract;
-      ResolverContractKey key = new ResolverContractKey(GetType(), type);
-      Dictionary<ResolverContractKey, JsonContract> cache = GetCache();
-      if (cache == null || !cache.TryGetValue(key, out contract))
-      {
-        contract = CreateContract(type);
-
-        // avoid the possibility of modifying the cache dictionary while another thread is accessing it
-        lock (_typeContractCacheLock)
-        {
-          cache = GetCache();
-          Dictionary<ResolverContractKey, JsonContract> updatedCache =
-            (cache != null)
-              ? new Dictionary<ResolverContractKey, JsonContract>(cache)
-              : new Dictionary<ResolverContractKey, JsonContract>();
-          updatedCache[key] = contract;
-
-          UpdateCache(updatedCache);
-        }
-      }
-
-      return contract;
-    }
-
-    /// <summary>
-    /// Gets the serializable members for the type.
-    /// </summary>
-    /// <param name="objectType">The type to get serializable members for.</param>
-    /// <returns>The serializable members for the type.</returns>
-    protected virtual List<MemberInfo> GetSerializableMembers(Type objectType)
-    {
-#if !PocketPC && !NET20
-      DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(objectType);
-#endif
-
-      List<MemberInfo> defaultMembers = ReflectionUtils.GetFieldsAndProperties(objectType, DefaultMembersSearchFlags)
-        .Where(m => !ReflectionUtils.IsIndexedProperty(m)).ToList();
-      List<MemberInfo> allMembers = ReflectionUtils.GetFieldsAndProperties(objectType, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)
-        .Where(m => !ReflectionUtils.IsIndexedProperty(m)).ToList();
-
-      List<MemberInfo> serializableMembers = new List<MemberInfo>();
-      foreach (MemberInfo member in allMembers)
-      {
-        // exclude members that are compiler generated if set
-        if (SerializeCompilerGeneratedMembers || !member.IsDefined(typeof(CompilerGeneratedAttribute), true))
-        {
-          if (defaultMembers.Contains(member))
-          {
-            // add all members that are found by default member search
-            serializableMembers.Add(member);
-          }
-          else
-          {
-            // add members that are explicitly marked with JsonProperty/DataMember attribute
-            if (JsonTypeReflector.GetAttribute<JsonPropertyAttribute>(member) != null)
-              serializableMembers.Add(member);
-#if !PocketPC && !NET20
-            else if (dataContractAttribute != null && JsonTypeReflector.GetAttribute<DataMemberAttribute>(member) != null)
-              serializableMembers.Add(member);
-#endif
-          }
-        }
-      }
-
-#if !PocketPC && !SILVERLIGHT && !NET20
-      Type match;
-      // don't include EntityKey on entities objects... this is a bit hacky
-      if (objectType.AssignableToTypeName("System.Data.Objects.DataClasses.EntityObject", out match))
-        serializableMembers = serializableMembers.Where(ShouldSerializeEntityMember).ToList();
-#endif
-
-      return serializableMembers;
-    }
-
-#if !PocketPC && !SILVERLIGHT && !NET20
-    private bool ShouldSerializeEntityMember(MemberInfo memberInfo)
-    {
-      PropertyInfo propertyInfo = memberInfo as PropertyInfo;
-      if (propertyInfo != null)
-      {
-        if (propertyInfo.PropertyType.IsGenericType && propertyInfo.PropertyType.GetGenericTypeDefinition().FullName == "System.Data.Objects.DataClasses.EntityReference`1")
-          return false;
-      }
-
-      return true;
-    }
-#endif
-
-    /// <summary>
-    /// Creates a <see cref="JsonObjectContract"/> for the given type.
-    /// </summary>
-    /// <param name="objectType">Type of the object.</param>
-    /// <returns>A <see cref="JsonObjectContract"/> for the given type.</returns>
-    protected virtual JsonObjectContract CreateObjectContract(Type objectType)
-    {
-      JsonObjectContract contract = new JsonObjectContract(objectType);
-      InitializeContract(contract);
-
-      contract.MemberSerialization = JsonTypeReflector.GetObjectMemberSerialization(objectType);
-      contract.Properties.AddRange(CreateProperties(contract));
-      if (contract.DefaultCreator == null || contract.DefaultCreatorNonPublic)
-        contract.ParametrizedConstructor = GetParametrizedConstructor(objectType);
-
-      return contract;
-    }
-
-    private ConstructorInfo GetParametrizedConstructor(Type objectType)
-    {
-      ConstructorInfo[] constructors = objectType.GetConstructors(BindingFlags.Public | BindingFlags.Instance);
-
-      if (constructors.Length == 1)
-        return constructors[0];
-      else
-        return null;
-    }
-
-    /// <summary>
-    /// Resolves the default <see cref="JsonConverter" /> for the contract.
-    /// </summary>
-    /// <param name="objectType">Type of the object.</param>
-    /// <returns></returns>
-    protected virtual JsonConverter ResolveContractConverter(Type objectType)
-    {
-      return JsonTypeReflector.GetJsonConverter(objectType, objectType);
-    }
-
-    private Func<object> GetDefaultCreator(Type createdType)
-    {
-      return JsonTypeReflector.ReflectionDelegateFactory.CreateDefaultConstructor<object>(createdType);
-    }
-
-    private void InitializeContract(JsonContract contract)
-    {
-      JsonContainerAttribute containerAttribute = JsonTypeReflector.GetJsonContainerAttribute(contract.UnderlyingType);
-      if (containerAttribute != null)
-      {
-        contract.IsReference = containerAttribute._isReference;
-      }
-#if !PocketPC && !NET20
-      else
-      {
-        DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(contract.UnderlyingType);
-        // doesn't have a null value
-        if (dataContractAttribute != null && dataContractAttribute.IsReference)
-          contract.IsReference = true;
-      }
-#endif
-
-      contract.Converter = ResolveContractConverter(contract.UnderlyingType);
-
-      // then see whether object is compadible with any of the built in converters
-      contract.InternalConverter = JsonSerializer.GetMatchingConverter(BuiltInConverters, contract.UnderlyingType);
-
-      if (ReflectionUtils.HasDefaultConstructor(contract.CreatedType, true)
-        || contract.CreatedType.IsValueType)
-      {
-        contract.DefaultCreator = GetDefaultCreator(contract.CreatedType);
-
-        contract.DefaultCreatorNonPublic = (!contract.CreatedType.IsValueType &&
-                                            ReflectionUtils.GetDefaultConstructor(contract.CreatedType) == null);
-      }
-
-      foreach (MethodInfo method in contract.UnderlyingType.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
-      {
-        // compact framework errors when getting parameters for a generic method
-        // lame, but generic methods should not be callbacks anyway
-        if (method.ContainsGenericParameters)
-          continue;
-
-        Type prevAttributeType = null;
-        ParameterInfo[] parameters = method.GetParameters();
-
-#if !PocketPC
-        if (IsValidCallback(method, parameters, typeof(OnSerializingAttribute), contract.OnSerializing, ref prevAttributeType))
-        {
-          contract.OnSerializing = method;
-        }
-        if (IsValidCallback(method, parameters, typeof(OnSerializedAttribute), contract.OnSerialized, ref prevAttributeType))
-        {
-          contract.OnSerialized = method;
-        }
-        if (IsValidCallback(method, parameters, typeof(OnDeserializingAttribute), contract.OnDeserializing, ref prevAttributeType))
-        {
-          contract.OnDeserializing = method;
-        }
-        if (IsValidCallback(method, parameters, typeof(OnDeserializedAttribute), contract.OnDeserialized, ref prevAttributeType))
-        {
-          contract.OnDeserialized = method;
-        }
-#endif
-        if (IsValidCallback(method, parameters, typeof(OnErrorAttribute), contract.OnError, ref prevAttributeType))
-        {
-          contract.OnError = method;
-        }
-      }
-    }
-
-    /// <summary>
-    /// Creates a <see cref="JsonDictionaryContract"/> for the given type.
-    /// </summary>
-    /// <param name="objectType">Type of the object.</param>
-    /// <returns>A <see cref="JsonDictionaryContract"/> for the given type.</returns>
-    protected virtual JsonDictionaryContract CreateDictionaryContract(Type objectType)
-    {
-      JsonDictionaryContract contract = new JsonDictionaryContract(objectType);
-      InitializeContract(contract);
-
-      return contract;
-    }
-
-    /// <summary>
-    /// Creates a <see cref="JsonArrayContract"/> for the given type.
-    /// </summary>
-    /// <param name="objectType">Type of the object.</param>
-    /// <returns>A <see cref="JsonArrayContract"/> for the given type.</returns>
-    protected virtual JsonArrayContract CreateArrayContract(Type objectType)
-    {
-      JsonArrayContract contract = new JsonArrayContract(objectType);
-      InitializeContract(contract);
-
-      return contract;
-    }
-
-    /// <summary>
-    /// Creates a <see cref="JsonPrimitiveContract"/> for the given type.
-    /// </summary>
-    /// <param name="objectType">Type of the object.</param>
-    /// <returns>A <see cref="JsonPrimitiveContract"/> for the given type.</returns>
-    protected virtual JsonPrimitiveContract CreatePrimitiveContract(Type objectType)
-    {
-      JsonPrimitiveContract contract = new JsonPrimitiveContract(objectType);
-      InitializeContract(contract);
-      
-      return contract;
-    }
-
-    /// <summary>
-    /// Creates a <see cref="JsonLinqContract"/> for the given type.
-    /// </summary>
-    /// <param name="objectType">Type of the object.</param>
-    /// <returns>A <see cref="JsonLinqContract"/> for the given type.</returns>
-    protected virtual JsonLinqContract CreateLinqContract(Type objectType)
-    {
-      JsonLinqContract contract = new JsonLinqContract(objectType);
-      InitializeContract(contract);
-
-      return contract;
-    }
-
-#if !SILVERLIGHT && !PocketPC
-    /// <summary>
-    /// Creates a <see cref="JsonISerializableContract"/> for the given type.
-    /// </summary>
-    /// <param name="objectType">Type of the object.</param>
-    /// <returns>A <see cref="JsonISerializableContract"/> for the given type.</returns>
-    protected virtual JsonISerializableContract CreateISerializableContract(Type objectType)
-    {
-      JsonISerializableContract contract = new JsonISerializableContract(objectType);
-      InitializeContract(contract);
-
-      ConstructorInfo constructorInfo = objectType.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new [] {typeof (SerializationInfo), typeof (StreamingContext)}, null);
-      if (constructorInfo != null)
-      {
-        MethodCall<object, object> methodCall = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall<object>(constructorInfo);
-
-        contract.ISerializableCreator = (args => methodCall(null, args));
-      }
-
-      return contract;
-    }
-#endif
-
-    /// <summary>
-    /// Creates a <see cref="JsonStringContract"/> for the given type.
-    /// </summary>
-    /// <param name="objectType">Type of the object.</param>
-    /// <returns>A <see cref="JsonStringContract"/> for the given type.</returns>
-    protected virtual JsonStringContract CreateStringContract(Type objectType)
-    {
-      JsonStringContract contract = new JsonStringContract(objectType);
-      InitializeContract(contract);
-
-      return contract;
-    }
-
-    /// <summary>
-    /// Determines which contract type is created for the given type.
-    /// </summary>
-    /// <param name="objectType">Type of the object.</param>
-    /// <returns>A <see cref="JsonContract"/> for the given type.</returns>
-    protected virtual JsonContract CreateContract(Type objectType)
-    {
-      if (JsonConvert.IsJsonPrimitiveType(objectType))
-        return CreatePrimitiveContract(objectType);
-
-      if (JsonTypeReflector.GetJsonObjectAttribute(objectType) != null)
-        return CreateObjectContract(objectType);
-
-      if (JsonTypeReflector.GetJsonArrayAttribute(objectType) != null)
-        return CreateArrayContract(objectType);
-
-      if (objectType.IsSubclassOf(typeof(JToken)))
-        return CreateLinqContract(objectType);
-
-      if (CollectionUtils.IsDictionaryType(objectType))
-        return CreateDictionaryContract(objectType);
-
-      if (typeof(IEnumerable).IsAssignableFrom(objectType))
-        return CreateArrayContract(objectType);
-
-      if (CanConvertToString(objectType))
-        return CreateStringContract(objectType);
-
-#if !SILVERLIGHT && !PocketPC
-      if (typeof(ISerializable).IsAssignableFrom(objectType))
-        return CreateISerializableContract(objectType);
-#endif
-
-      return CreateObjectContract(objectType);
-    }
-
-    internal static bool CanConvertToString(Type type)
-    {
-#if !PocketPC
-      TypeConverter converter = ConvertUtils.GetConverter(type);
-
-      // use the objectType's TypeConverter if it has one and can convert to a string
-      if (converter != null
-#if !SILVERLIGHT
- && !(converter is ComponentConverter)
- && !(converter is ReferenceConverter)
-#endif
- && converter.GetType() != typeof(TypeConverter))
-      {
-        if (converter.CanConvertTo(typeof(string)))
-          return true;
-      }
-#endif
-
-      if (type == typeof(Type) || type.IsSubclassOf(typeof(Type)))
-        return true;
-
-#if SILVERLIGHT || PocketPC
-      if (type == typeof(Guid) || type == typeof(Uri) || type == typeof(TimeSpan))
-        return true;
-#endif
-
-      return false;
-    }
-
-    private static bool IsValidCallback(MethodInfo method, ParameterInfo[] parameters, Type attributeType, MethodInfo currentCallback, ref Type prevAttributeType)
-    {
-      if (!method.IsDefined(attributeType, false))
-        return false;
-
-      if (currentCallback != null)
-        throw new Exception("Invalid attribute. Both '{0}' and '{1}' in type '{2}' have '{3}'.".FormatWith(CultureInfo.InvariantCulture, method, currentCallback, GetClrTypeFullName(method.DeclaringType), attributeType));
-
-      if (prevAttributeType != null)
-        throw new Exception("Invalid Callback. Method '{3}' in type '{2}' has both '{0}' and '{1}'.".FormatWith(CultureInfo.InvariantCulture, prevAttributeType, attributeType, GetClrTypeFullName(method.DeclaringType), method));
-
-      if (method.IsVirtual)
-        throw new Exception("Virtual Method '{0}' of type '{1}' cannot be marked with '{2}' attribute.".FormatWith(CultureInfo.InvariantCulture, method, GetClrTypeFullName(method.DeclaringType), attributeType));
-
-      if (method.ReturnType != typeof(void))
-        throw new Exception("Serialization Callback '{1}' in type '{0}' must return void.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(method.DeclaringType), method));
-
-      if (attributeType == typeof(OnErrorAttribute))
-      {
-        if (parameters == null || parameters.Length != 2 || parameters[0].ParameterType != typeof(StreamingContext) || parameters[1].ParameterType != typeof(ErrorContext))
-          throw new Exception("Serialization Error Callback '{1}' in type '{0}' must have two parameters of type '{2}' and '{3}'.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(method.DeclaringType), method, typeof (StreamingContext), typeof(ErrorContext)));
-      }
-      else
-      {
-        if (parameters == null || parameters.Length != 1 || parameters[0].ParameterType != typeof(StreamingContext))
-          throw new Exception("Serialization Callback '{1}' in type '{0}' must have a single parameter of type '{2}'.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(method.DeclaringType), method, typeof(StreamingContext)));
-      }
-
-      prevAttributeType = attributeType;
-
-      return true;
-    }
-
-    internal static string GetClrTypeFullName(Type type)
-    {
-      if (type.IsGenericTypeDefinition || !type.ContainsGenericParameters)
-        return type.FullName;
-
-      return string.Format(CultureInfo.InvariantCulture, "{0}.{1}", new object[] { type.Namespace, type.Name });
-    }
-
-    /// <summary>
-    /// Creates properties for the given <see cref="JsonObjectContract"/>.
-    /// </summary>
-    /// <param name="contract">The contract to create properties for.</param>
-    /// <returns>Properties for the given <see cref="JsonObjectContract"/>.</returns>
-    protected virtual IList<JsonProperty> CreateProperties(JsonObjectContract contract)
-    {
-      List<MemberInfo> members = GetSerializableMembers(contract.UnderlyingType);
-      if (members == null)
-        throw new JsonSerializationException("Null collection of seralizable members returned.");
-
-      JsonPropertyCollection properties = new JsonPropertyCollection(contract);
-
-      foreach (MemberInfo member in members)
-      {
-        JsonProperty property = CreateProperty(contract, member);
-
-        if (property != null)
-          properties.AddProperty(property);
-      }
-
-      return properties;
-    }
-
-    /// <summary>
-    /// Creates the <see cref="IValueProvider"/> used by the serializer to get and set values from a member.
-    /// </summary>
-    /// <param name="member">The member.</param>
-    /// <returns>The <see cref="IValueProvider"/> used by the serializer to get and set values from a member.</returns>
-    protected virtual IValueProvider CreateMemberValueProvider(MemberInfo member)
-    {
-#if !PocketPC && !SILVERLIGHT
-      if (DynamicCodeGeneration)
-        return new DynamicValueProvider(member);
-#endif
-
-      return new ReflectionValueProvider(member);
-    }
-
-    /// <summary>
-    /// Creates a <see cref="JsonProperty"/> for the given <see cref="MemberInfo"/>.
-    /// </summary>
-    /// <param name="contract">The member's declaring types <see cref="JsonObjectContract"/>.</param>
-    /// <param name="member">The member to create a <see cref="JsonProperty"/> for.</param>
-    /// <returns>A created <see cref="JsonProperty"/> for the given <see cref="MemberInfo"/>.</returns>
-    protected virtual JsonProperty CreateProperty(JsonObjectContract contract, MemberInfo member)
-    {
-      JsonProperty property = new JsonProperty();
-      property.PropertyType = ReflectionUtils.GetMemberUnderlyingType(member);
-      property.ValueProvider = CreateMemberValueProvider(member);
-      
-      // resolve converter for property
-      // the class type might have a converter but the property converter takes presidence
-      property.Converter = JsonTypeReflector.GetJsonConverter(member, property.PropertyType);
-
-#if !PocketPC && !NET20
-      DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(member.DeclaringType);
-
-      DataMemberAttribute dataMemberAttribute;
-      if (dataContractAttribute != null)
-        dataMemberAttribute = JsonTypeReflector.GetAttribute<DataMemberAttribute>(member);
-      else
-        dataMemberAttribute = null;
-#endif
-
-      JsonPropertyAttribute propertyAttribute = JsonTypeReflector.GetAttribute<JsonPropertyAttribute>(member);
-      bool hasIgnoreAttribute = (JsonTypeReflector.GetAttribute<JsonIgnoreAttribute>(member) != null);
-
-      string mappedName;
-      if (propertyAttribute != null && propertyAttribute.PropertyName != null)
-        mappedName = propertyAttribute.PropertyName;
-#if !PocketPC && !NET20
-      else if (dataMemberAttribute != null && dataMemberAttribute.Name != null)
-        mappedName = dataMemberAttribute.Name;
-#endif
-      else
-        mappedName = member.Name;
-
-      property.PropertyName = ResolvePropertyName(mappedName);
-
-      if (propertyAttribute != null)
-        property.Required = propertyAttribute.Required;
-#if !PocketPC && !NET20
-      else if (dataMemberAttribute != null)
-        property.Required = (dataMemberAttribute.IsRequired) ? Required.AllowNull : Required.Default;
-#endif
-      else
-        property.Required = Required.Default;
-
-      property.Ignored = (hasIgnoreAttribute ||
-                      (contract.MemberSerialization == MemberSerialization.OptIn
-                       && propertyAttribute == null
-#if !PocketPC && !NET20
-                       && dataMemberAttribute == null
-#endif
-));
-
-      bool allowNonPublicAccess = false;
-      if ((DefaultMembersSearchFlags & BindingFlags.NonPublic) == BindingFlags.NonPublic)
-        allowNonPublicAccess = true;
-      if (propertyAttribute != null)
-        allowNonPublicAccess = true;
-#if !PocketPC && !NET20
-      if (dataMemberAttribute != null)
-        allowNonPublicAccess = true;
-#endif
-
-      property.Readable = ReflectionUtils.CanReadMemberValue(member, allowNonPublicAccess);
-      property.Writable = ReflectionUtils.CanSetMemberValue(member, allowNonPublicAccess);
-
-      property.MemberConverter = JsonTypeReflector.GetJsonConverter(member, ReflectionUtils.GetMemberUnderlyingType(member));
-
-      DefaultValueAttribute defaultValueAttribute = JsonTypeReflector.GetAttribute<DefaultValueAttribute>(member);
-      property.DefaultValue = (defaultValueAttribute != null) ? defaultValueAttribute.Value : null;
-
-      property.NullValueHandling = (propertyAttribute != null) ? propertyAttribute._nullValueHandling : null;
-      property.DefaultValueHandling = (propertyAttribute != null) ? propertyAttribute._defaultValueHandling : null;
-      property.ReferenceLoopHandling = (propertyAttribute != null) ? propertyAttribute._referenceLoopHandling : null;
-      property.ObjectCreationHandling = (propertyAttribute != null) ? propertyAttribute._objectCreationHandling : null;
-      property.TypeNameHandling = (propertyAttribute != null) ? propertyAttribute._typeNameHandling : null;
-      property.IsReference = (propertyAttribute != null) ? propertyAttribute._isReference : null;
-
-      property.ShouldSerialize = CreateShouldSerializeTest(member);
-
-      return property;
-    }
-
-    private Predicate<object> CreateShouldSerializeTest(MemberInfo member)
-    {
-      MethodInfo shouldSerializeMethod = member.DeclaringType.GetMethod(JsonTypeReflector.ShouldSerializePrefix + member.Name, new Type[0]);
-
-      if (shouldSerializeMethod == null || shouldSerializeMethod.ReturnType != typeof(bool))
-        return null;
-
-      MethodCall<object, object> shouldSerializeCall =
-        JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall<object>(shouldSerializeMethod);
-
-      return o => (bool) shouldSerializeCall(o);
-    }
-
-    /// <summary>
-    /// Resolves the name of the property.
-    /// </summary>
-    /// <param name="propertyName">Name of the property.</param>
-    /// <returns>Name of the property.</returns>
-    protected virtual string ResolvePropertyName(string propertyName)
-    {
-      return propertyName;
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections;
+#if !(NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE)
+using System.Collections.Concurrent;
+#endif
+using System.Collections.Generic;
+using System.ComponentModel;
+#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
+using System.Dynamic;
+#endif
+using System.Globalization;
+using System.Reflection;
+using System.Runtime.Serialization;
+#if !(NETFX_CORE || PORTABLE)
+using System.Security.Permissions;
+#endif
+using System.Xml.Serialization;
+using Newtonsoft.Json.Converters;
+using Newtonsoft.Json.Utilities;
+using Newtonsoft.Json.Linq;
+using System.Runtime.CompilerServices;
+#if NETFX_CORE || PORTABLE
+using ICustomAttributeProvider = Newtonsoft.Json.Utilities.CustomAttributeProvider;
+#endif
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#else
+using System.Linq;
+#endif
+
+namespace Newtonsoft.Json.Serialization
+{
+  internal struct ResolverContractKey : IEquatable<ResolverContractKey>
+  {
+    private readonly Type _resolverType;
+    private readonly Type _contractType;
+
+    public ResolverContractKey(Type resolverType, Type contractType)
+    {
+      _resolverType = resolverType;
+      _contractType = contractType;
+    }
+
+    public override int GetHashCode()
+    {
+      return _resolverType.GetHashCode() ^ _contractType.GetHashCode();
+    }
+
+    public override bool Equals(object obj)
+    {
+      if (!(obj is ResolverContractKey))
+        return false;
+
+      return Equals((ResolverContractKey)obj);
+    }
+
+    public bool Equals(ResolverContractKey other)
+    {
+      return (_resolverType == other._resolverType && _contractType == other._contractType);
+    }
+  }
+
+  /// <summary>
+  /// Used by <see cref="JsonSerializer"/> to resolves a <see cref="JsonContract"/> for a given <see cref="Type"/>.
+  /// </summary>
+  public class DefaultContractResolver : IContractResolver
+  {
+    private static readonly IContractResolver _instance = new DefaultContractResolver(true);
+    internal static IContractResolver Instance
+    {
+        get { return _instance; }
+    }
+    private static readonly IList<JsonConverter> BuiltInConverters = new List<JsonConverter>
+      {
+#if !(SILVERLIGHT || NET20 || NETFX_CORE || PORTABLE)
+        new EntityKeyMemberConverter(),
+#endif
+#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
+        new ExpandoObjectConverter(),
+#endif
+#if (!(SILVERLIGHT || PORTABLE) || WINDOWS_PHONE)
+        new XmlNodeConverter(),
+#endif
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+        new BinaryConverter(),
+        new DataSetConverter(),
+        new DataTableConverter(),
+#endif
+        new KeyValuePairConverter(),
+        new BsonObjectIdConverter()
+      };
+
+    private static Dictionary<ResolverContractKey, JsonContract> _sharedContractCache;
+    private static readonly object _typeContractCacheLock = new object();
+
+    private Dictionary<ResolverContractKey, JsonContract> _instanceContractCache;
+    private readonly bool _sharedCache;
+
+    /// <summary>
+    /// Gets a value indicating whether members are being get and set using dynamic code generation.
+    /// This value is determined by the runtime permissions available.
+    /// </summary>
+    /// <value>
+    /// 	<c>true</c> if using dynamic code generation; otherwise, <c>false</c>.
+    /// </value>
+    public bool DynamicCodeGeneration
+    {
+      get { return JsonTypeReflector.DynamicCodeGeneration; }
+    }
+
+#if !NETFX_CORE
+    /// <summary>
+    /// Gets or sets the default members search flags.
+    /// </summary>
+    /// <value>The default members search flags.</value>
+    public BindingFlags DefaultMembersSearchFlags { get; set; }
+#else
+    private BindingFlags DefaultMembersSearchFlags = BindingFlags.Instance | BindingFlags.Public;
+#endif
+
+    /// <summary>
+    /// Gets or sets a value indicating whether compiler generated members should be serialized.
+    /// </summary>
+    /// <value>
+    /// 	<c>true</c> if serialized compiler generated members; otherwise, <c>false</c>.
+    /// </value>
+    public bool SerializeCompilerGeneratedMembers { get; set; }
+
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+    /// <summary>
+    /// Gets or sets a value indicating whether to ignore the <see cref="ISerializable"/> interface when serializing and deserializing types.
+    /// </summary>
+    /// <value>
+    /// 	<c>true</c> if the <see cref="ISerializable"/> interface will be ignored when serializing and deserializing types; otherwise, <c>false</c>.
+    /// </value>
+    public bool IgnoreSerializableInterface { get; set; }
+
+    /// <summary>
+    /// Gets or sets a value indicating whether to ignore the <see cref="SerializableAttribute"/> attribute when serializing and deserializing types.
+    /// </summary>
+    /// <value>
+    /// 	<c>true</c> if the <see cref="SerializableAttribute"/> attribute will be ignored when serializing and deserializing types; otherwise, <c>false</c>.
+    /// </value>
+    public bool IgnoreSerializableAttribute { get; set; }
+#endif
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="DefaultContractResolver"/> class.
+    /// </summary>
+    public DefaultContractResolver()
+      : this(false)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="DefaultContractResolver"/> class.
+    /// </summary>
+    /// <param name="shareCache">
+    /// If set to <c>true</c> the <see cref="DefaultContractResolver"/> will use a cached shared with other resolvers of the same type.
+    /// Sharing the cache will significantly performance because expensive reflection will only happen once but could cause unexpected
+    /// behavior if different instances of the resolver are suppose to produce different results. When set to false it is highly
+    /// recommended to reuse <see cref="DefaultContractResolver"/> instances with the <see cref="JsonSerializer"/>.
+    /// </param>
+    public DefaultContractResolver(bool shareCache)
+    {
+#if !NETFX_CORE
+      DefaultMembersSearchFlags = BindingFlags.Public | BindingFlags.Instance;
+#endif
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+      IgnoreSerializableAttribute = true;
+#endif
+
+      _sharedCache = shareCache;
+    }
+
+    private Dictionary<ResolverContractKey, JsonContract> GetCache()
+    {
+      if (_sharedCache)
+        return _sharedContractCache;
+      else
+        return _instanceContractCache;
+    }
+
+    private void UpdateCache(Dictionary<ResolverContractKey, JsonContract> cache)
+    {
+      if (_sharedCache)
+        _sharedContractCache = cache;
+      else
+        _instanceContractCache = cache;
+    }
+
+    /// <summary>
+    /// Resolves the contract for a given type.
+    /// </summary>
+    /// <param name="type">The type to resolve a contract for.</param>
+    /// <returns>The contract for a given type.</returns>
+    public virtual JsonContract ResolveContract(Type type)
+    {
+      if (type == null)
+        throw new ArgumentNullException("type");
+
+      JsonContract contract;
+      ResolverContractKey key = new ResolverContractKey(GetType(), type);
+      Dictionary<ResolverContractKey, JsonContract> cache = GetCache();
+      if (cache == null || !cache.TryGetValue(key, out contract))
+      {
+        contract = CreateContract(type);
+
+        // avoid the possibility of modifying the cache dictionary while another thread is accessing it
+        lock (_typeContractCacheLock)
+        {
+          cache = GetCache();
+          Dictionary<ResolverContractKey, JsonContract> updatedCache =
+            (cache != null)
+              ? new Dictionary<ResolverContractKey, JsonContract>(cache)
+              : new Dictionary<ResolverContractKey, JsonContract>();
+          updatedCache[key] = contract;
+
+          UpdateCache(updatedCache);
+        }
+      }
+
+      return contract;
+    }
+
+    /// <summary>
+    /// Gets the serializable members for the type.
+    /// </summary>
+    /// <param name="objectType">The type to get serializable members for.</param>
+    /// <returns>The serializable members for the type.</returns>
+    protected virtual List<MemberInfo> GetSerializableMembers(Type objectType)
+    {
+      bool ignoreSerializableAttribute;
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+      ignoreSerializableAttribute = IgnoreSerializableAttribute;
+#else
+      ignoreSerializableAttribute = true;
+#endif
+
+      MemberSerialization memberSerialization = JsonTypeReflector.GetObjectMemberSerialization(objectType, ignoreSerializableAttribute);
+
+      List<MemberInfo> allMembers = ReflectionUtils.GetFieldsAndProperties(objectType, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)
+        .Where(m => !ReflectionUtils.IsIndexedProperty(m)).ToList();
+
+      List<MemberInfo> serializableMembers = new List<MemberInfo>();
+      
+      if (memberSerialization != MemberSerialization.Fields)
+      {
+#if !PocketPC && !NET20
+        DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(objectType);
+#endif
+
+        List<MemberInfo> defaultMembers = ReflectionUtils.GetFieldsAndProperties(objectType, DefaultMembersSearchFlags)
+         .Where(m => !ReflectionUtils.IsIndexedProperty(m)).ToList();
+        
+        foreach (MemberInfo member in allMembers)
+        {
+          // exclude members that are compiler generated if set
+          if (SerializeCompilerGeneratedMembers || !member.IsDefined(typeof (CompilerGeneratedAttribute), true))
+          {
+            if (defaultMembers.Contains(member))
+            {
+              // add all members that are found by default member search
+              serializableMembers.Add(member);
+            }
+            else
+            {
+              // add members that are explicitly marked with JsonProperty/DataMember attribute
+              // or are a field if serializing just fields
+              if (JsonTypeReflector.GetAttribute<JsonPropertyAttribute>(member.GetCustomAttributeProvider()) != null)
+                serializableMembers.Add(member);
+#if !PocketPC && !NET20
+              else if (dataContractAttribute != null && JsonTypeReflector.GetAttribute<DataMemberAttribute>(member.GetCustomAttributeProvider()) != null)
+                serializableMembers.Add(member);
+#endif
+              else if (memberSerialization == MemberSerialization.Fields && member.MemberType() == MemberTypes.Field)
+                serializableMembers.Add(member);
+            }
+          }
+        }
+
+#if !PocketPC && !SILVERLIGHT && !NET20
+        Type match;
+        // don't include EntityKey on entities objects... this is a bit hacky
+        if (objectType.AssignableToTypeName("System.Data.Objects.DataClasses.EntityObject", out match))
+          serializableMembers = serializableMembers.Where(ShouldSerializeEntityMember).ToList();
+#endif
+      }
+      else
+      {
+        // serialize all fields
+        foreach (MemberInfo member in allMembers)
+        {
+          if (member.MemberType() == MemberTypes.Field)
+            serializableMembers.Add(member);
+        }
+      }
+
+      return serializableMembers;
+    }
+
+#if !PocketPC && !SILVERLIGHT && !NET20
+    private bool ShouldSerializeEntityMember(MemberInfo memberInfo)
+    {
+      PropertyInfo propertyInfo = memberInfo as PropertyInfo;
+      if (propertyInfo != null)
+      {
+        if (propertyInfo.PropertyType.IsGenericType() && propertyInfo.PropertyType.GetGenericTypeDefinition().FullName == "System.Data.Objects.DataClasses.EntityReference`1")
+          return false;
+      }
+
+      return true;
+    }
+#endif
+
+    /// <summary>
+    /// Creates a <see cref="JsonObjectContract"/> for the given type.
+    /// </summary>
+    /// <param name="objectType">Type of the object.</param>
+    /// <returns>A <see cref="JsonObjectContract"/> for the given type.</returns>
+    protected virtual JsonObjectContract CreateObjectContract(Type objectType)
+    {
+      JsonObjectContract contract = new JsonObjectContract(objectType);
+      InitializeContract(contract);
+
+      bool ignoreSerializableAttribute;
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+      ignoreSerializableAttribute = IgnoreSerializableAttribute;
+#else
+      ignoreSerializableAttribute = true;
+#endif
+
+      contract.MemberSerialization = JsonTypeReflector.GetObjectMemberSerialization(contract.NonNullableUnderlyingType, ignoreSerializableAttribute);
+      contract.Properties.AddRange(CreateProperties(contract.NonNullableUnderlyingType, contract.MemberSerialization));
+
+      JsonObjectAttribute attribute = JsonTypeReflector.GetJsonObjectAttribute(contract.NonNullableUnderlyingType);
+      if (attribute != null)
+        contract.ItemRequired = attribute._itemRequired;
+
+      // check if a JsonConstructorAttribute has been defined and use that
+      if (contract.NonNullableUnderlyingType.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Any(c => c.IsDefined(typeof(JsonConstructorAttribute), true)))
+      {
+        ConstructorInfo constructor = GetAttributeConstructor(contract.NonNullableUnderlyingType);
+        if (constructor != null)
+        {
+          contract.OverrideConstructor = constructor;
+          contract.ConstructorParameters.AddRange(CreateConstructorParameters(constructor, contract.Properties));
+        }
+      }
+      else if (contract.MemberSerialization == MemberSerialization.Fields)
+      {
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+        // mimic DataContractSerializer behaviour when populating fields by overriding default creator to create an uninitialized object
+        // note that this is only possible when the application is fully trusted so fall back to using the default constructor (if available) in partial trust
+        if (JsonTypeReflector.FullyTrusted)
+          contract.DefaultCreator = contract.GetUninitializedObject;
+#endif
+      }
+      else if (contract.DefaultCreator == null || contract.DefaultCreatorNonPublic)
+      {
+        ConstructorInfo constructor = GetParametrizedConstructor(contract.NonNullableUnderlyingType);
+        if (constructor != null)
+        {
+          contract.ParametrizedConstructor = constructor;
+          contract.ConstructorParameters.AddRange(CreateConstructorParameters(constructor, contract.Properties));
+        }
+      }
+      return contract;
+    }
+
+    private ConstructorInfo GetAttributeConstructor(Type objectType)
+    {
+      IList<ConstructorInfo> markedConstructors = objectType.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Where(c => c.IsDefined(typeof(JsonConstructorAttribute), true)).ToList();
+
+      if (markedConstructors.Count > 1)
+        throw new JsonException("Multiple constructors with the JsonConstructorAttribute.");
+      else if (markedConstructors.Count == 1)
+        return markedConstructors[0];
+
+      return null;
+    }
+
+    private ConstructorInfo GetParametrizedConstructor(Type objectType)
+    {
+      IList<ConstructorInfo> constructors = objectType.GetConstructors(BindingFlags.Public | BindingFlags.Instance).ToList();
+
+      if (constructors.Count == 1)
+        return constructors[0];
+      else
+        return null;
+    }
+
+    /// <summary>
+    /// Creates the constructor parameters.
+    /// </summary>
+    /// <param name="constructor">The constructor to create properties for.</param>
+    /// <param name="memberProperties">The type's member properties.</param>
+    /// <returns>Properties for the given <see cref="ConstructorInfo"/>.</returns>
+    protected virtual IList<JsonProperty> CreateConstructorParameters(ConstructorInfo constructor, JsonPropertyCollection memberProperties)
+    {
+      var constructorParameters = constructor.GetParameters();
+
+      JsonPropertyCollection parameterCollection = new JsonPropertyCollection(constructor.DeclaringType);
+
+      foreach (ParameterInfo parameterInfo in constructorParameters)
+      {
+        JsonProperty matchingMemberProperty = memberProperties.GetClosestMatchProperty(parameterInfo.Name);
+        // type must match as well as name
+        if (matchingMemberProperty != null && matchingMemberProperty.PropertyType != parameterInfo.ParameterType)
+          matchingMemberProperty = null;
+
+        JsonProperty property = CreatePropertyFromConstructorParameter(matchingMemberProperty, parameterInfo);
+
+        if (property != null)
+        {
+          parameterCollection.AddProperty(property);
+        }
+      }
+
+      return parameterCollection;
+    }
+
+    /// <summary>
+    /// Creates a <see cref="JsonProperty"/> for the given <see cref="ParameterInfo"/>.
+    /// </summary>
+    /// <param name="matchingMemberProperty">The matching member property.</param>
+    /// <param name="parameterInfo">The constructor parameter.</param>
+    /// <returns>A created <see cref="JsonProperty"/> for the given <see cref="ParameterInfo"/>.</returns>
+    protected virtual JsonProperty CreatePropertyFromConstructorParameter(JsonProperty matchingMemberProperty, ParameterInfo parameterInfo)
+    {
+      JsonProperty property = new JsonProperty();
+      property.PropertyType = parameterInfo.ParameterType;
+
+      bool allowNonPublicAccess;
+      SetPropertySettingsFromAttributes(property, parameterInfo.GetCustomAttributeProvider(), parameterInfo.Name, parameterInfo.Member.DeclaringType, MemberSerialization.OptOut, out allowNonPublicAccess);
+
+      property.Readable = false;
+      property.Writable = true;
+
+      // "inherit" values from matching member property if unset on parameter
+      if (matchingMemberProperty != null)
+      {
+        property.PropertyName = (property.PropertyName != parameterInfo.Name) ? property.PropertyName : matchingMemberProperty.PropertyName;
+        property.Converter = property.Converter ?? matchingMemberProperty.Converter;
+        property.MemberConverter = property.MemberConverter ?? matchingMemberProperty.MemberConverter;
+        property.DefaultValue = property.DefaultValue ?? matchingMemberProperty.DefaultValue;
+        property._required = property._required ?? matchingMemberProperty._required;
+        property.IsReference = property.IsReference ?? matchingMemberProperty.IsReference;
+        property.NullValueHandling = property.NullValueHandling ?? matchingMemberProperty.NullValueHandling;
+        property.DefaultValueHandling = property.DefaultValueHandling ?? matchingMemberProperty.DefaultValueHandling;
+        property.ReferenceLoopHandling = property.ReferenceLoopHandling ?? matchingMemberProperty.ReferenceLoopHandling;
+        property.ObjectCreationHandling = property.ObjectCreationHandling ?? matchingMemberProperty.ObjectCreationHandling;
+        property.TypeNameHandling = property.TypeNameHandling ?? matchingMemberProperty.TypeNameHandling;
+      }
+
+      return property;
+    }
+
+    /// <summary>
+    /// Resolves the default <see cref="JsonConverter" /> for the contract.
+    /// </summary>
+    /// <param name="objectType">Type of the object.</param>
+    /// <returns>The contract's default <see cref="JsonConverter" />.</returns>
+    protected virtual JsonConverter ResolveContractConverter(Type objectType)
+    {
+      return JsonTypeReflector.GetJsonConverter(objectType.GetCustomAttributeProvider(), objectType);
+    }
+
+    private Func<object> GetDefaultCreator(Type createdType)
+    {
+      return JsonTypeReflector.ReflectionDelegateFactory.CreateDefaultConstructor<object>(createdType);
+    }
+
+#if !PocketPC && !NET20
+    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Portability", "CA1903:UseOnlyApiFromTargetedFramework", MessageId = "System.Runtime.Serialization.DataContractAttribute.#get_IsReference()")]
+#endif
+    private void InitializeContract(JsonContract contract)
+    {
+      JsonContainerAttribute containerAttribute = JsonTypeReflector.GetJsonContainerAttribute(contract.NonNullableUnderlyingType);
+      if (containerAttribute != null)
+      {
+        contract.IsReference = containerAttribute._isReference;
+      }
+#if !PocketPC && !NET20
+      else
+      {
+        DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(contract.NonNullableUnderlyingType);
+        // doesn't have a null value
+        if (dataContractAttribute != null && dataContractAttribute.IsReference)
+          contract.IsReference = true;
+      }
+#endif
+
+      contract.Converter = ResolveContractConverter(contract.NonNullableUnderlyingType);
+
+      // then see whether object is compadible with any of the built in converters
+      contract.InternalConverter = JsonSerializer.GetMatchingConverter(BuiltInConverters, contract.NonNullableUnderlyingType);
+
+      if (ReflectionUtils.HasDefaultConstructor(contract.CreatedType, true)
+        || contract.CreatedType.IsValueType())
+      {
+        contract.DefaultCreator = GetDefaultCreator(contract.CreatedType);
+
+        contract.DefaultCreatorNonPublic = (!contract.CreatedType.IsValueType() &&
+                                            ReflectionUtils.GetDefaultConstructor(contract.CreatedType) == null);
+      }
+
+      ResolveCallbackMethods(contract, contract.NonNullableUnderlyingType);
+    }
+
+    private void ResolveCallbackMethods(JsonContract contract, Type t)
+    {
+      if (t.BaseType() != null)
+        ResolveCallbackMethods(contract, t.BaseType());
+
+      MethodInfo onSerializing;
+      MethodInfo onSerialized;
+      MethodInfo onDeserializing;
+      MethodInfo onDeserialized;
+      MethodInfo onError;
+
+      GetCallbackMethodsForType(t, out onSerializing, out onSerialized, out onDeserializing, out onDeserialized, out onError);
+
+      if (onSerializing != null)
+      {
+#if NETFX_CORE
+        if (!t.IsGenericType() || (t.GetGenericTypeDefinition() != typeof(ConcurrentDictionary<,>)))
+          contract.OnSerializing = onSerializing;
+#else
+        contract.OnSerializing = onSerializing;
+#endif
+      }
+
+      if (onSerialized != null)
+        contract.OnSerialized = onSerialized;
+
+      if (onDeserializing != null)
+        contract.OnDeserializing = onDeserializing;
+
+      if (onDeserialized != null)
+      {
+        // ConcurrentDictionary throws an error here so don't use its OnDeserialized - http://json.codeplex.com/discussions/257093
+#if !(NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE)
+        if (!t.IsGenericType() || (t.GetGenericTypeDefinition() != typeof(ConcurrentDictionary<,>)))
+          contract.OnDeserialized = onDeserialized;
+#else
+        contract.OnDeserialized = onDeserialized;
+#endif
+      }
+
+      if (onError != null)
+        contract.OnError = onError;
+    }
+
+    private void GetCallbackMethodsForType(Type type, out MethodInfo onSerializing, out MethodInfo onSerialized, out MethodInfo onDeserializing, out MethodInfo onDeserialized, out MethodInfo onError)
+    {
+      onSerializing = null;
+      onSerialized = null;
+      onDeserializing = null;
+      onDeserialized = null;
+      onError = null;
+
+      foreach (MethodInfo method in type.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
+      {
+        // compact framework errors when getting parameters for a generic method
+        // lame, but generic methods should not be callbacks anyway
+        if (method.ContainsGenericParameters)
+          continue;
+
+        Type prevAttributeType = null;
+        ParameterInfo[] parameters = method.GetParameters();
+
+        if (IsValidCallback(method, parameters, typeof(OnSerializingAttribute), onSerializing, ref prevAttributeType))
+        {
+          onSerializing = method;
+        }
+        if (IsValidCallback(method, parameters, typeof(OnSerializedAttribute), onSerialized, ref prevAttributeType))
+        {
+          onSerialized = method;
+        }
+        if (IsValidCallback(method, parameters, typeof(OnDeserializingAttribute), onDeserializing, ref prevAttributeType))
+        {
+          onDeserializing = method;
+        }
+        if (IsValidCallback(method, parameters, typeof(OnDeserializedAttribute), onDeserialized, ref prevAttributeType))
+        {
+          onDeserialized = method;
+        }
+        if (IsValidCallback(method, parameters, typeof(OnErrorAttribute), onError, ref prevAttributeType))
+        {
+          onError = method;
+        }
+      }
+    }
+
+    /// <summary>
+    /// Creates a <see cref="JsonDictionaryContract"/> for the given type.
+    /// </summary>
+    /// <param name="objectType">Type of the object.</param>
+    /// <returns>A <see cref="JsonDictionaryContract"/> for the given type.</returns>
+    protected virtual JsonDictionaryContract CreateDictionaryContract(Type objectType)
+    {
+      JsonDictionaryContract contract = new JsonDictionaryContract(objectType);
+      InitializeContract(contract);
+
+      contract.PropertyNameResolver = ResolvePropertyName;
+
+      return contract;
+    }
+
+    /// <summary>
+    /// Creates a <see cref="JsonArrayContract"/> for the given type.
+    /// </summary>
+    /// <param name="objectType">Type of the object.</param>
+    /// <returns>A <see cref="JsonArrayContract"/> for the given type.</returns>
+    protected virtual JsonArrayContract CreateArrayContract(Type objectType)
+    {
+      JsonArrayContract contract = new JsonArrayContract(objectType);
+      InitializeContract(contract);
+
+      return contract;
+    }
+
+    /// <summary>
+    /// Creates a <see cref="JsonPrimitiveContract"/> for the given type.
+    /// </summary>
+    /// <param name="objectType">Type of the object.</param>
+    /// <returns>A <see cref="JsonPrimitiveContract"/> for the given type.</returns>
+    protected virtual JsonPrimitiveContract CreatePrimitiveContract(Type objectType)
+    {
+      JsonPrimitiveContract contract = new JsonPrimitiveContract(objectType);
+      InitializeContract(contract);
+
+      return contract;
+    }
+
+    /// <summary>
+    /// Creates a <see cref="JsonLinqContract"/> for the given type.
+    /// </summary>
+    /// <param name="objectType">Type of the object.</param>
+    /// <returns>A <see cref="JsonLinqContract"/> for the given type.</returns>
+    protected virtual JsonLinqContract CreateLinqContract(Type objectType)
+    {
+      JsonLinqContract contract = new JsonLinqContract(objectType);
+      InitializeContract(contract);
+
+      return contract;
+    }
+
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+    /// <summary>
+    /// Creates a <see cref="JsonISerializableContract"/> for the given type.
+    /// </summary>
+    /// <param name="objectType">Type of the object.</param>
+    /// <returns>A <see cref="JsonISerializableContract"/> for the given type.</returns>
+    protected virtual JsonISerializableContract CreateISerializableContract(Type objectType)
+    {
+      JsonISerializableContract contract = new JsonISerializableContract(objectType);
+      InitializeContract(contract);
+
+      ConstructorInfo constructorInfo = contract.NonNullableUnderlyingType.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { typeof(SerializationInfo), typeof(StreamingContext) }, null);
+      if (constructorInfo != null)
+      {
+        MethodCall<object, object> methodCall = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall<object>(constructorInfo);
+
+        contract.ISerializableCreator = (args => methodCall(null, args));
+      }
+
+      return contract;
+    }
+#endif
+
+#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
+    /// <summary>
+    /// Creates a <see cref="JsonDynamicContract"/> for the given type.
+    /// </summary>
+    /// <param name="objectType">Type of the object.</param>
+    /// <returns>A <see cref="JsonDynamicContract"/> for the given type.</returns>
+    protected virtual JsonDynamicContract CreateDynamicContract(Type objectType)
+    {
+      JsonDynamicContract contract = new JsonDynamicContract(objectType);
+      InitializeContract(contract);
+
+      contract.PropertyNameResolver = ResolvePropertyName;
+      contract.Properties.AddRange(CreateProperties(objectType, MemberSerialization.OptOut));
+
+      return contract;
+    }
+#endif
+
+    /// <summary>
+    /// Creates a <see cref="JsonStringContract"/> for the given type.
+    /// </summary>
+    /// <param name="objectType">Type of the object.</param>
+    /// <returns>A <see cref="JsonStringContract"/> for the given type.</returns>
+    protected virtual JsonStringContract CreateStringContract(Type objectType)
+    {
+      JsonStringContract contract = new JsonStringContract(objectType);
+      InitializeContract(contract);
+
+      return contract;
+    }
+
+    /// <summary>
+    /// Determines which contract type is created for the given type.
+    /// </summary>
+    /// <param name="objectType">Type of the object.</param>
+    /// <returns>A <see cref="JsonContract"/> for the given type.</returns>
+    protected virtual JsonContract CreateContract(Type objectType)
+    {
+      Type t = ReflectionUtils.EnsureNotNullableType(objectType);
+
+      if (JsonConvert.IsJsonPrimitiveType(t))
+        return CreatePrimitiveContract(objectType);
+
+      if (JsonTypeReflector.GetJsonObjectAttribute(t) != null)
+        return CreateObjectContract(objectType);
+
+      if (JsonTypeReflector.GetJsonArrayAttribute(t) != null)
+        return CreateArrayContract(objectType);
+
+      if (JsonTypeReflector.GetJsonDictionaryAttribute(t) != null)
+        return CreateDictionaryContract(objectType);
+
+      if (t == typeof(JToken) || t.IsSubclassOf(typeof(JToken)))
+        return CreateLinqContract(objectType);
+
+      if (CollectionUtils.IsDictionaryType(t))
+        return CreateDictionaryContract(objectType);
+
+      if (typeof(IEnumerable).IsAssignableFrom(t))
+        return CreateArrayContract(objectType);
+
+      if (CanConvertToString(t))
+        return CreateStringContract(objectType);
+
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+      if (!IgnoreSerializableInterface && typeof(ISerializable).IsAssignableFrom(t))
+        return CreateISerializableContract(objectType);
+#endif
+
+#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
+      if (typeof(IDynamicMetaObjectProvider).IsAssignableFrom(t))
+        return CreateDynamicContract(objectType);
+#endif
+
+      return CreateObjectContract(objectType);
+    }
+
+    internal static bool CanConvertToString(Type type)
+    {
+#if !(NETFX_CORE || PORTABLE)
+      TypeConverter converter = ConvertUtils.GetConverter(type);
+
+      // use the objectType's TypeConverter if it has one and can convert to a string
+      if (converter != null
+#if !SILVERLIGHT
+ && !(converter is ComponentConverter)
+ && !(converter is ReferenceConverter)
+#endif
+ && converter.GetType() != typeof(TypeConverter))
+      {
+        if (converter.CanConvertTo(typeof(string)))
+          return true;
+      }
+#endif
+
+      if (type == typeof(Type) || type.IsSubclassOf(typeof(Type)))
+        return true;
+
+#if SILVERLIGHT || PocketPC
+      if (type == typeof(Guid) || type == typeof(Uri) || type == typeof(TimeSpan))
+        return true;
+#endif
+
+      return false;
+    }
+
+    private static bool IsValidCallback(MethodInfo method, ParameterInfo[] parameters, Type attributeType, MethodInfo currentCallback, ref Type prevAttributeType)
+    {
+      if (!method.IsDefined(attributeType, false))
+        return false;
+
+      if (currentCallback != null)
+        throw new JsonException("Invalid attribute. Both '{0}' and '{1}' in type '{2}' have '{3}'.".FormatWith(CultureInfo.InvariantCulture, method, currentCallback, GetClrTypeFullName(method.DeclaringType), attributeType));
+
+      if (prevAttributeType != null)
+        throw new JsonException("Invalid Callback. Method '{3}' in type '{2}' has both '{0}' and '{1}'.".FormatWith(CultureInfo.InvariantCulture, prevAttributeType, attributeType, GetClrTypeFullName(method.DeclaringType), method));
+
+      if (method.IsVirtual)
+        throw new JsonException("Virtual Method '{0}' of type '{1}' cannot be marked with '{2}' attribute.".FormatWith(CultureInfo.InvariantCulture, method, GetClrTypeFullName(method.DeclaringType), attributeType));
+
+      if (method.ReturnType != typeof(void))
+        throw new JsonException("Serialization Callback '{1}' in type '{0}' must return void.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(method.DeclaringType), method));
+
+      if (attributeType == typeof(OnErrorAttribute))
+      {
+        if (parameters == null || parameters.Length != 2 || parameters[0].ParameterType != typeof(StreamingContext) || parameters[1].ParameterType != typeof(ErrorContext))
+          throw new JsonException("Serialization Error Callback '{1}' in type '{0}' must have two parameters of type '{2}' and '{3}'.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(method.DeclaringType), method, typeof(StreamingContext), typeof(ErrorContext)));
+      }
+      else
+      {
+        if (parameters == null || parameters.Length != 1 || parameters[0].ParameterType != typeof(StreamingContext))
+          throw new JsonException("Serialization Callback '{1}' in type '{0}' must have a single parameter of type '{2}'.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(method.DeclaringType), method, typeof(StreamingContext)));
+      }
+
+      prevAttributeType = attributeType;
+
+      return true;
+    }
+
+    internal static string GetClrTypeFullName(Type type)
+    {
+      if (type.IsGenericTypeDefinition() || !type.ContainsGenericParameters())
+        return type.FullName;
+
+      return string.Format(CultureInfo.InvariantCulture, "{0}.{1}", new object[] { type.Namespace, type.Name });
+    }
+
+    /// <summary>
+    /// Creates properties for the given <see cref="JsonContract"/>.
+    /// </summary>
+    /// <param name="type">The type to create properties for.</param>
+    /// /// <param name="memberSerialization">The member serialization mode for the type.</param>
+    /// <returns>Properties for the given <see cref="JsonContract"/>.</returns>
+    protected virtual IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
+    {
+      List<MemberInfo> members = GetSerializableMembers(type);
+      if (members == null)
+        throw new JsonSerializationException("Null collection of seralizable members returned.");
+
+      JsonPropertyCollection properties = new JsonPropertyCollection(type);
+
+      foreach (MemberInfo member in members)
+      {
+        JsonProperty property = CreateProperty(member, memberSerialization);
+
+        if (property != null)
+          properties.AddProperty(property);
+      }
+
+      IList<JsonProperty> orderedProperties = properties.OrderBy(p => p.Order ?? -1).ToList();
+      return orderedProperties;
+    }
+
+    /// <summary>
+    /// Creates the <see cref="IValueProvider"/> used by the serializer to get and set values from a member.
+    /// </summary>
+    /// <param name="member">The member.</param>
+    /// <returns>The <see cref="IValueProvider"/> used by the serializer to get and set values from a member.</returns>
+    protected virtual IValueProvider CreateMemberValueProvider(MemberInfo member)
+    {
+      // warning - this method use to cause errors with Intellitrace. Retest in VS Ultimate after changes
+      IValueProvider valueProvider;
+
+#if !(SILVERLIGHT || PORTABLE || NETFX_CORE)
+      if (DynamicCodeGeneration)
+        valueProvider = new DynamicValueProvider(member);
+      else
+        valueProvider = new ReflectionValueProvider(member);
+#else
+      valueProvider = new ReflectionValueProvider(member);
+#endif
+
+      return valueProvider;
+    }
+
+    /// <summary>
+    /// Creates a <see cref="JsonProperty"/> for the given <see cref="MemberInfo"/>.
+    /// </summary>
+    /// <param name="memberSerialization">The member's parent <see cref="MemberSerialization"/>.</param>
+    /// <param name="member">The member to create a <see cref="JsonProperty"/> for.</param>
+    /// <returns>A created <see cref="JsonProperty"/> for the given <see cref="MemberInfo"/>.</returns>
+    protected virtual JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
+    {
+      JsonProperty property = new JsonProperty();
+      property.PropertyType = ReflectionUtils.GetMemberUnderlyingType(member);
+      property.DeclaringType = member.DeclaringType;
+      property.ValueProvider = CreateMemberValueProvider(member);
+
+      bool allowNonPublicAccess;
+      SetPropertySettingsFromAttributes(property, member.GetCustomAttributeProvider(), member.Name, member.DeclaringType, memberSerialization, out allowNonPublicAccess);
+
+      if (memberSerialization != MemberSerialization.Fields)
+      {
+        property.Readable = ReflectionUtils.CanReadMemberValue(member, allowNonPublicAccess);
+        property.Writable = ReflectionUtils.CanSetMemberValue(member, allowNonPublicAccess, property.HasMemberAttribute);
+      }
+      else
+      {
+        // write to readonly fields
+        property.Readable = true;
+        property.Writable = true;
+      }
+      property.ShouldSerialize = CreateShouldSerializeTest(member);
+
+      SetIsSpecifiedActions(property, member, allowNonPublicAccess);
+
+      return property;
+    }
+
+    private void SetPropertySettingsFromAttributes(JsonProperty property, ICustomAttributeProvider attributeProvider, string name, Type declaringType, MemberSerialization memberSerialization, out bool allowNonPublicAccess)
+    {
+#if !PocketPC && !NET20
+      DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(declaringType);
+
+      MemberInfo memberInfo = null;
+#if !(NETFX_CORE || PORTABLE)
+      memberInfo = attributeProvider as MemberInfo;
+#else
+      memberInfo = attributeProvider.UnderlyingObject as MemberInfo;
+#endif
+
+      DataMemberAttribute dataMemberAttribute;
+      if (dataContractAttribute != null && memberInfo != null)
+        dataMemberAttribute = JsonTypeReflector.GetDataMemberAttribute((MemberInfo) memberInfo);
+      else
+        dataMemberAttribute = null;
+#endif
+
+      JsonPropertyAttribute propertyAttribute = JsonTypeReflector.GetAttribute<JsonPropertyAttribute>(attributeProvider);
+      if (propertyAttribute != null)
+        property.HasMemberAttribute = true;
+
+      string mappedName;
+      if (propertyAttribute != null && propertyAttribute.PropertyName != null)
+        mappedName = propertyAttribute.PropertyName;
+#if !PocketPC && !NET20
+      else if (dataMemberAttribute != null && dataMemberAttribute.Name != null)
+        mappedName = dataMemberAttribute.Name;
+#endif
+      else
+        mappedName = name;
+
+      property.PropertyName = ResolvePropertyName(mappedName);
+      property.UnderlyingName = name;
+
+      bool hasMemberAttribute = false;
+      if (propertyAttribute != null)
+      {
+        property._required = propertyAttribute._required;
+        property.Order = propertyAttribute._order;
+        hasMemberAttribute = true;
+      }
+#if !PocketPC && !NET20
+      else if (dataMemberAttribute != null)
+      {
+        property._required = (dataMemberAttribute.IsRequired) ? Required.AllowNull : Required.Default;
+        property.Order = (dataMemberAttribute.Order != -1) ? (int?) dataMemberAttribute.Order : null;
+        hasMemberAttribute = true;
+      }
+#endif
+
+      bool hasJsonIgnoreAttribute =
+        JsonTypeReflector.GetAttribute<JsonIgnoreAttribute>(attributeProvider) != null
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+        || JsonTypeReflector.GetAttribute<NonSerializedAttribute>(attributeProvider) != null
+#endif
+        ;
+
+      if (memberSerialization != MemberSerialization.OptIn)
+      {
+       bool hasIgnoreDataMemberAttribute = false;
+        
+#if !(NET20 || NET35)
+        hasIgnoreDataMemberAttribute = (JsonTypeReflector.GetAttribute<IgnoreDataMemberAttribute>(attributeProvider) != null);
+#endif
+
+        // ignored if it has JsonIgnore or NonSerialized or IgnoreDataMember attributes
+        property.Ignored = (hasJsonIgnoreAttribute || hasIgnoreDataMemberAttribute);
+      }
+      else
+      {
+        // ignored if it has JsonIgnore/NonSerialized or does not have DataMember or JsonProperty attributes
+        property.Ignored = (hasJsonIgnoreAttribute || !hasMemberAttribute);
+      }
+
+      // resolve converter for property
+      // the class type might have a converter but the property converter takes presidence
+      property.Converter = JsonTypeReflector.GetJsonConverter(attributeProvider, property.PropertyType);
+      property.MemberConverter = JsonTypeReflector.GetJsonConverter(attributeProvider, property.PropertyType);
+
+      DefaultValueAttribute defaultValueAttribute = JsonTypeReflector.GetAttribute<DefaultValueAttribute>(attributeProvider);
+      property.DefaultValue = (defaultValueAttribute != null) ? defaultValueAttribute.Value : null;
+
+      property.NullValueHandling = (propertyAttribute != null) ? propertyAttribute._nullValueHandling : null;
+      property.DefaultValueHandling = (propertyAttribute != null) ? propertyAttribute._defaultValueHandling : null;
+      property.ReferenceLoopHandling = (propertyAttribute != null) ? propertyAttribute._referenceLoopHandling : null;
+      property.ObjectCreationHandling = (propertyAttribute != null) ? propertyAttribute._objectCreationHandling : null;
+      property.TypeNameHandling = (propertyAttribute != null) ? propertyAttribute._typeNameHandling : null;
+      property.IsReference = (propertyAttribute != null) ? propertyAttribute._isReference : null;
+
+      property.ItemIsReference = (propertyAttribute != null) ? propertyAttribute._itemIsReference : null;
+      property.ItemConverter =
+        (propertyAttribute != null && propertyAttribute.ItemConverterType != null)
+          ? JsonConverterAttribute.CreateJsonConverterInstance(propertyAttribute.ItemConverterType)
+          : null;
+      property.ItemReferenceLoopHandling = (propertyAttribute != null) ? propertyAttribute._itemReferenceLoopHandling : null;
+      property.ItemTypeNameHandling = (propertyAttribute != null) ? propertyAttribute._itemTypeNameHandling : null;
+
+      allowNonPublicAccess = false;
+      if ((DefaultMembersSearchFlags & BindingFlags.NonPublic) == BindingFlags.NonPublic)
+        allowNonPublicAccess = true;
+      if (propertyAttribute != null)
+        allowNonPublicAccess = true;
+      if (memberSerialization == MemberSerialization.Fields)
+        allowNonPublicAccess = true;
+
+#if !PocketPC && !NET20
+      if (dataMemberAttribute != null)
+      {
+        allowNonPublicAccess = true;
+        property.HasMemberAttribute = true;
+      }
+#endif
+    }
+
+    private Predicate<object> CreateShouldSerializeTest(MemberInfo member)
+    {
+      MethodInfo shouldSerializeMethod = member.DeclaringType.GetMethod(JsonTypeReflector.ShouldSerializePrefix + member.Name, ReflectionUtils.EmptyTypes);
+
+      if (shouldSerializeMethod == null || shouldSerializeMethod.ReturnType != typeof(bool))
+        return null;
+
+      MethodCall<object, object> shouldSerializeCall =
+        JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall<object>(shouldSerializeMethod);
+
+      return o => (bool)shouldSerializeCall(o);
+    }
+
+    private void SetIsSpecifiedActions(JsonProperty property, MemberInfo member, bool allowNonPublicAccess)
+    {
+      MemberInfo specifiedMember = member.DeclaringType.GetProperty(member.Name + JsonTypeReflector.SpecifiedPostfix);
+      if (specifiedMember == null)
+        specifiedMember = member.DeclaringType.GetField(member.Name + JsonTypeReflector.SpecifiedPostfix);
+
+      if (specifiedMember == null || ReflectionUtils.GetMemberUnderlyingType(specifiedMember) != typeof(bool))
+      {
+        return;
+      }
+
+      Func<object, object> specifiedPropertyGet = JsonTypeReflector.ReflectionDelegateFactory.CreateGet<object>(specifiedMember);
+
+      property.GetIsSpecified = o => (bool)specifiedPropertyGet(o);
+
+      if (ReflectionUtils.CanSetMemberValue(specifiedMember, allowNonPublicAccess, false))
+        property.SetIsSpecified = JsonTypeReflector.ReflectionDelegateFactory.CreateSet<object>(specifiedMember);
+    }
+
+    /// <summary>
+    /// Resolves the name of the property.
+    /// </summary>
+    /// <param name="propertyName">Name of the property.</param>
+    /// <returns>Name of the property.</returns>
+    protected internal virtual string ResolvePropertyName(string propertyName)
+    {
+      return propertyName;
+    }
+
+    /// <summary>
+    /// Gets the resolved name of the property.
+    /// </summary>
+    /// <param name="propertyName">Name of the property.</param>
+    /// <returns>Name of the property.</returns>
+    public string GetResolvedPropertyName(string propertyName)
+    {
+      // this is a new method rather than changing the visibility of ResolvePropertyName to avoid
+      // a breaking change for anyone who has overidden the method
+      return ResolvePropertyName(propertyName);
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/DefaultReferenceResolver.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/DefaultReferenceResolver.cs
index cd226ff..02bb189 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/DefaultReferenceResolver.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/DefaultReferenceResolver.cs
@@ -1,106 +1,83 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.CompilerServices;
-using System.Text;
-using Newtonsoft.Json.Utilities;
-using System.Globalization;
-
-namespace Newtonsoft.Json.Serialization
-{
-  internal class DefaultReferenceResolver : IReferenceResolver
-  {
-    private class ReferenceEqualsEqualityComparer : IEqualityComparer<object>
-    {
-      bool IEqualityComparer<object>.Equals(object x, object y)
-      {
-        return ReferenceEquals(x, y);
-      }
-
-      int IEqualityComparer<object>.GetHashCode(object obj)
-      {
-#if !PocketPC
-        // put objects in a bucket based on their reference
-        return RuntimeHelpers.GetHashCode(obj);
-#else
-        // put all objects in the same bucket so ReferenceEquals is called on all
-        return -1;
-#endif
-      }
-    }
-
-    private int _referenceCount;
-    private BidirectionalDictionary<string, object> _mappings;
-
-    private BidirectionalDictionary<string, object> Mappings
-    {
-      get
-      {
-        // override equality comparer for object key dictionary
-        // object will be modified as it deserializes and might have mutable hashcode
-        if (_mappings == null)
-          _mappings = new BidirectionalDictionary<string, object>(
-            EqualityComparer<string>.Default,
-            new ReferenceEqualsEqualityComparer());
-
-        return _mappings;
-      }
-    }
-
-    public object ResolveReference(string reference)
-    {
-      object value;
-      Mappings.TryGetByFirst(reference, out value);
-      return value;
-    }
-
-    public string GetReference(object value)
-    {
-      string reference;
-      if (!Mappings.TryGetBySecond(value, out reference))
-      {
-        _referenceCount++;
-        reference = _referenceCount.ToString(CultureInfo.InvariantCulture);
-        Mappings.Add(reference, value);
-      }
-
-      return reference;
-    }
-
-    public void AddReference(string reference, object value)
-    {
-      Mappings.Add(reference, value);
-    }
-
-    public bool IsReferenced(object value)
-    {
-      string reference;
-      return Mappings.TryGetBySecond(value, out reference);
-    }
-  }
-}
+#region License
+// 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.
+#endregion
+
+using System;
+using Newtonsoft.Json.Utilities;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Serialization
+{
+  internal class DefaultReferenceResolver : IReferenceResolver
+  {
+    private int _referenceCount;
+
+    private BidirectionalDictionary<string, object> GetMappings(object context)
+    {
+      JsonSerializerInternalBase internalSerializer;
+
+      if (context is JsonSerializerInternalBase)
+        internalSerializer = (JsonSerializerInternalBase) context;
+      else if (context is JsonSerializerProxy)
+        internalSerializer = ((JsonSerializerProxy) context).GetInternalSerializer();
+      else
+        throw new JsonException("The DefaultReferenceResolver can only be used internally.");
+
+      return internalSerializer.DefaultReferenceMappings;
+    }
+
+    public object ResolveReference(object context, string reference)
+    {
+      object value;
+      GetMappings(context).TryGetByFirst(reference, out value);
+      return value;
+    }
+
+    public string GetReference(object context, object value)
+    {
+      var mappings = GetMappings(context);
+
+      string reference;
+      if (!mappings.TryGetBySecond(value, out reference))
+      {
+        _referenceCount++;
+        reference = _referenceCount.ToString(CultureInfo.InvariantCulture);
+        mappings.Add(reference, value);
+      }
+
+      return reference;
+    }
+
+    public void AddReference(object context, string reference, object value)
+    {
+      GetMappings(context).Add(reference, value);
+    }
+
+    public bool IsReferenced(object context, object value)
+    {
+      string reference;
+      return GetMappings(context).TryGetBySecond(value, out reference);
+    }
+  }
+}
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/DefaultSerializationBinder.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/DefaultSerializationBinder.cs
index c4b6145..ed1c904 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/DefaultSerializationBinder.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/DefaultSerializationBinder.cs
@@ -1,80 +1,144 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Runtime.Serialization;
-using System.Reflection;
-using System.Globalization;
-using Newtonsoft.Json.Utilities;
-
-namespace Newtonsoft.Json.Serialization
-{
-  /// <summary>
-  /// The default serialization binder used when resolving and loading classes from type names.
-  /// </summary>
-  public class DefaultSerializationBinder : SerializationBinder
-  {
-    internal static readonly DefaultSerializationBinder Instance = new DefaultSerializationBinder();
-
-    /// <summary>
-    /// When overridden in a derived class, controls the binding of a serialized object to a type.
-    /// </summary>
-    /// <param name="assemblyName">Specifies the <see cref="T:System.Reflection.Assembly"/> name of the serialized object.</param>
-    /// <param name="typeName">Specifies the <see cref="T:System.Type"/> name of the serialized object.</param>
-    /// <returns>
-    /// The type of the object the formatter creates a new instance of.
-    /// </returns>
-    public override Type BindToType(string assemblyName, string typeName)
-    {
-      if (assemblyName != null)
-      {
-        Assembly assembly;
-
-#if !SILVERLIGHT && !PocketPC
-        // look, I don't like using obsolete methods as much as you do but this is the only way
-        // Assembly.Load won't check the GAC for a partial name
-#pragma warning disable 618,612
-        assembly = Assembly.LoadWithPartialName(assemblyName);
-#pragma warning restore 618,612
-#else
-        assembly = Assembly.Load(assemblyName);
-#endif
-
-        if (assembly == null)
-          throw new JsonSerializationException("Could not load assembly '{0}'.".FormatWith(CultureInfo.InvariantCulture, assemblyName));
-
-        Type type = assembly.GetType(typeName);
-        if (type == null)
-          throw new JsonSerializationException("Could not find type '{0}' in assembly '{1}'.".FormatWith(CultureInfo.InvariantCulture, typeName, assembly.FullName));
-
-        return type;
-      }
-      else
-      {
-        return Type.GetType(typeName);
-      }
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Runtime.Serialization;
+using System.Reflection;
+using System.Globalization;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// The default serialization binder used when resolving and loading classes from type names.
+  /// </summary>
+  public class DefaultSerializationBinder : SerializationBinder
+  {
+    internal static readonly DefaultSerializationBinder Instance = new DefaultSerializationBinder();
+
+    private readonly ThreadSafeStore<TypeNameKey, Type> _typeCache = new ThreadSafeStore<TypeNameKey, Type>(GetTypeFromTypeNameKey);
+
+    private static Type GetTypeFromTypeNameKey(TypeNameKey typeNameKey)
+    {
+      string assemblyName = typeNameKey.AssemblyName;
+      string typeName = typeNameKey.TypeName;
+
+      if (assemblyName != null)
+      {
+        Assembly assembly;
+
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+        // look, I don't like using obsolete methods as much as you do but this is the only way
+        // Assembly.Load won't check the GAC for a partial name
+#pragma warning disable 618,612
+        assembly = Assembly.LoadWithPartialName(assemblyName);
+#pragma warning restore 618,612
+#elif NETFX_CORE
+        assembly = Assembly.Load(new AssemblyName(assemblyName));
+#else
+        assembly = Assembly.Load(assemblyName);
+#endif
+
+        if (assembly == null)
+          throw new JsonSerializationException("Could not load assembly '{0}'.".FormatWith(CultureInfo.InvariantCulture, assemblyName));
+
+        Type type = assembly.GetType(typeName);
+        if (type == null)
+          throw new JsonSerializationException("Could not find type '{0}' in assembly '{1}'.".FormatWith(CultureInfo.InvariantCulture, typeName, assembly.FullName));
+
+        return type;
+      }
+      else
+      {
+        return Type.GetType(typeName);
+      }
+    }
+
+    internal struct TypeNameKey : IEquatable<TypeNameKey>
+    {
+      internal readonly string AssemblyName;
+      internal readonly string TypeName;
+
+      public TypeNameKey(string assemblyName, string typeName)
+      {
+        AssemblyName = assemblyName;
+        TypeName = typeName;
+      }
+
+      public override int GetHashCode()
+      {
+        return ((AssemblyName != null) ? AssemblyName.GetHashCode() : 0) ^ ((TypeName != null) ? TypeName.GetHashCode() : 0);
+      }
+
+      public override bool Equals(object obj)
+      {
+        if (!(obj is TypeNameKey))
+          return false;
+
+        return Equals((TypeNameKey)obj);
+      }
+
+      public bool Equals(TypeNameKey other)
+      {
+        return (AssemblyName == other.AssemblyName && TypeName == other.TypeName);
+      }
+    }
+
+    /// <summary>
+    /// When overridden in a derived class, controls the binding of a serialized object to a type.
+    /// </summary>
+    /// <param name="assemblyName">Specifies the <see cref="T:System.Reflection.Assembly"/> name of the serialized object.</param>
+    /// <param name="typeName">Specifies the <see cref="T:System.Type"/> name of the serialized object.</param>
+    /// <returns>
+    /// The type of the object the formatter creates a new instance of.
+    /// </returns>
+    public override Type BindToType(string assemblyName, string typeName)
+    {
+      return _typeCache.Get(new TypeNameKey(assemblyName, typeName));
+    }
+
+#if !(NET35 || NET20)
+    /// <summary>
+    /// When overridden in a derived class, controls the binding of a serialized object to a type.
+    /// </summary>
+    /// <param name="serializedType">The type of the object the formatter creates a new instance of.</param>
+    /// <param name="assemblyName">Specifies the <see cref="T:System.Reflection.Assembly"/> name of the serialized object. </param>
+    /// <param name="typeName">Specifies the <see cref="T:System.Type"/> name of the serialized object. </param>
+    public override void BindToName(Type serializedType, out string assemblyName, out string typeName)
+    {
+#if NETFX_CORE
+      assemblyName = serializedType.GetTypeInfo().Assembly.FullName;
+      typeName = serializedType.FullName;
+#elif !SILVERLIGHT
+      assemblyName = serializedType.Assembly.FullName;
+      typeName = serializedType.FullName;
+#else
+      assemblyName = null;
+      typeName = serializedType.AssemblyQualifiedName;
+#endif
+    }
+#endif
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/DynamicValueProvider.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/DynamicValueProvider.cs
index ec302bb..a6d178f 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/DynamicValueProvider.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/DynamicValueProvider.cs
@@ -1,111 +1,113 @@
-#region License
-// 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.
-#endregion
-
-#if !PocketPC && !SILVERLIGHT
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Reflection;
-using Newtonsoft.Json.Utilities;
-using System.Globalization;
-
-namespace Newtonsoft.Json.Serialization
-{
-  /// <summary>
-  /// Get and set values for a <see cref="MemberInfo"/> using dynamic methods.
-  /// </summary>
-  public class DynamicValueProvider : IValueProvider
-  {
-    private readonly MemberInfo _memberInfo;
-    private Func<object, object> _getter;
-    private Action<object, object> _setter;
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="DynamicValueProvider"/> class.
-    /// </summary>
-    /// <param name="memberInfo">The member info.</param>
-    public DynamicValueProvider(MemberInfo memberInfo)
-    {
-      ValidationUtils.ArgumentNotNull(memberInfo, "memberInfo");
-      _memberInfo = memberInfo;
-    }
-
-    /// <summary>
-    /// Sets the value.
-    /// </summary>
-    /// <param name="target">The target to set the value on.</param>
-    /// <param name="value">The value to set on the target.</param>
-    public void SetValue(object target, object value)
-    {
-      try
-      {
-        if (_setter == null)
-          _setter = DynamicReflectionDelegateFactory.Instance.CreateSet<object>(_memberInfo);
-
-#if DEBUG
-        // dynamic method doesn't check whether the type is 'legal' to set
-        // add this check for unit tests
-        if (value == null)
-        {
-          if (!ReflectionUtils.IsNullable(ReflectionUtils.GetMemberUnderlyingType(_memberInfo)))
-            throw new Exception("Incompatible value. Cannot set {0} to null.".FormatWith(CultureInfo.InvariantCulture, _memberInfo));
-        }
-        else if (!ReflectionUtils.GetMemberUnderlyingType(_memberInfo).IsAssignableFrom(value.GetType()))
-        {
-            throw new Exception("Incompatible value. Cannot set {0} to type {1}.".FormatWith(CultureInfo.InvariantCulture, _memberInfo, value.GetType()));
-        }
-#endif
-
-        _setter(target, value);
-      }
-      catch (Exception ex)
-      {
-        throw new JsonSerializationException("Error setting value to '{0}' on '{1}'.".FormatWith(CultureInfo.InvariantCulture, _memberInfo.Name, target.GetType()), ex);
-      }
-    }
-
-    /// <summary>
-    /// Gets the value.
-    /// </summary>
-    /// <param name="target">The target to get the value from.</param>
-    /// <returns>The value.</returns>
-    public object GetValue(object target)
-    {
-      try
-      {
-        if (_getter == null)
-          _getter = DynamicReflectionDelegateFactory.Instance.CreateGet<object>(_memberInfo);
-
-        return _getter(target);
-      }
-      catch (Exception ex)
-      {
-        throw new JsonSerializationException("Error getting value from '{0}' on '{1}'.".FormatWith(CultureInfo.InvariantCulture, _memberInfo.Name, target.GetType()), ex);
-      }
-    }
-  }
-}
+#region License
+// 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.
+#endregion
+
+#if !(SILVERLIGHT || PORTABLE || NETFX_CORE)
+using System;
+using System.Collections.Generic;
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#endif
+using System.Text;
+using System.Reflection;
+using Newtonsoft.Json.Utilities;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Get and set values for a <see cref="MemberInfo"/> using dynamic methods.
+  /// </summary>
+  public class DynamicValueProvider : IValueProvider
+  {
+    private readonly MemberInfo _memberInfo;
+    private Func<object, object> _getter;
+    private Action<object, object> _setter;
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="DynamicValueProvider"/> class.
+    /// </summary>
+    /// <param name="memberInfo">The member info.</param>
+    public DynamicValueProvider(MemberInfo memberInfo)
+    {
+      ValidationUtils.ArgumentNotNull(memberInfo, "memberInfo");
+      _memberInfo = memberInfo;
+    }
+
+    /// <summary>
+    /// Sets the value.
+    /// </summary>
+    /// <param name="target">The target to set the value on.</param>
+    /// <param name="value">The value to set on the target.</param>
+    public void SetValue(object target, object value)
+    {
+      try
+      {
+        if (_setter == null)
+          _setter = DynamicReflectionDelegateFactory.Instance.CreateSet<object>(_memberInfo);
+
+#if DEBUG
+        // dynamic method doesn't check whether the type is 'legal' to set
+        // add this check for unit tests
+        if (value == null)
+        {
+          if (!ReflectionUtils.IsNullable(ReflectionUtils.GetMemberUnderlyingType(_memberInfo)))
+            throw new JsonSerializationException("Incompatible value. Cannot set {0} to null.".FormatWith(CultureInfo.InvariantCulture, _memberInfo));
+        }
+        else if (!ReflectionUtils.GetMemberUnderlyingType(_memberInfo).IsAssignableFrom(value.GetType()))
+        {
+          throw new JsonSerializationException("Incompatible value. Cannot set {0} to type {1}.".FormatWith(CultureInfo.InvariantCulture, _memberInfo, value.GetType()));
+        }
+#endif
+
+        _setter(target, value);
+      }
+      catch (Exception ex)
+      {
+        throw new JsonSerializationException("Error setting value to '{0}' on '{1}'.".FormatWith(CultureInfo.InvariantCulture, _memberInfo.Name, target.GetType()), ex);
+      }
+    }
+
+    /// <summary>
+    /// Gets the value.
+    /// </summary>
+    /// <param name="target">The target to get the value from.</param>
+    /// <returns>The value.</returns>
+    public object GetValue(object target)
+    {
+      try
+      {
+        if (_getter == null)
+          _getter = DynamicReflectionDelegateFactory.Instance.CreateGet<object>(_memberInfo);
+
+        return _getter(target);
+      }
+      catch (Exception ex)
+      {
+        throw new JsonSerializationException("Error getting value from '{0}' on '{1}'.".FormatWith(CultureInfo.InvariantCulture, _memberInfo.Name, target.GetType()), ex);
+      }
+    }
+  }
+}
 #endif
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/ErrorContext.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/ErrorContext.cs
index 2756d93..ae1b33e 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/ErrorContext.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/ErrorContext.cs
@@ -1,66 +1,69 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Newtonsoft.Json.Serialization
-{
-  /// <summary>
-  /// Provides information surrounding an error.
-  /// </summary>
-  public class ErrorContext
-  {
-    internal ErrorContext(object originalObject, object member, Exception error)
-    {
-      OriginalObject = originalObject;
-      Member = member;
-      Error = error;
-    }
-
-    /// <summary>
-    /// Gets or sets the error.
-    /// </summary>
-    /// <value>The error.</value>
-    public Exception Error { get; private set; }
-    /// <summary>
-    /// Gets the original object that caused the error.
-    /// </summary>
-    /// <value>The original object that caused the error.</value>
-    public object OriginalObject { get; private set; }
-    /// <summary>
-    /// Gets the member that caused the error.
-    /// </summary>
-    /// <value>The member that caused the error.</value>
-    public object Member { get; private set; }
-    /// <summary>
-    /// Gets or sets a value indicating whether this <see cref="ErrorContext"/> is handled.
-    /// </summary>
-    /// <value><c>true</c> if handled; otherwise, <c>false</c>.</value>
-    public bool Handled { get; set; }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Provides information surrounding an error.
+  /// </summary>
+  public class ErrorContext
+  {
+    internal ErrorContext(object originalObject, object member, string path, Exception error)
+    {
+      OriginalObject = originalObject;
+      Member = member;
+      Error = error;
+      Path = path;
+    }
+
+    /// <summary>
+    /// Gets or sets the error.
+    /// </summary>
+    /// <value>The error.</value>
+    public Exception Error { get; private set; }
+    /// <summary>
+    /// Gets the original object that caused the error.
+    /// </summary>
+    /// <value>The original object that caused the error.</value>
+    public object OriginalObject { get; private set; }
+    /// <summary>
+    /// Gets the member that caused the error.
+    /// </summary>
+    /// <value>The member that caused the error.</value>
+    public object Member { get; private set; }
+    /// <summary>
+    /// Gets the path of the JSON location where the error occurred.
+    /// </summary>
+    /// <value>The path of the JSON location where the error occurred.</value>
+    public string Path { get; private set; }
+    /// <summary>
+    /// Gets or sets a value indicating whether this <see cref="ErrorContext"/> is handled.
+    /// </summary>
+    /// <value><c>true</c> if handled; otherwise, <c>false</c>.</value>
+    public bool Handled { get; set; }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/ErrorEventArgs.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/ErrorEventArgs.cs
index f4c7c5b..daa6dbe 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/ErrorEventArgs.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/ErrorEventArgs.cs
@@ -1,35 +1,57 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Newtonsoft.Json.Serialization
-{
-  /// <summary>
-  /// Provides data for the Error event.
-  /// </summary>
-  public class ErrorEventArgs : EventArgs
-  {
-    /// <summary>
-    /// Gets the current object the error event is being raised against.
-    /// </summary>
-    /// <value>The current object the error event is being raised against.</value>
-    public object CurrentObject { get; private set; }
-    /// <summary>
-    /// Gets the error context.
-    /// </summary>
-    /// <value>The error context.</value>
-    public ErrorContext ErrorContext { get; private set; }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="ErrorEventArgs"/> class.
-    /// </summary>
-    /// <param name="currentObject">The current object.</param>
-    /// <param name="errorContext">The error context.</param>
-    public ErrorEventArgs(object currentObject, ErrorContext errorContext)
-    {
-      CurrentObject = currentObject;
-      ErrorContext = errorContext;
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Provides data for the Error event.
+  /// </summary>
+  public class ErrorEventArgs : EventArgs
+  {
+    /// <summary>
+    /// Gets the current object the error event is being raised against.
+    /// </summary>
+    /// <value>The current object the error event is being raised against.</value>
+    public object CurrentObject { get; private set; }
+    /// <summary>
+    /// Gets the error context.
+    /// </summary>
+    /// <value>The error context.</value>
+    public ErrorContext ErrorContext { get; private set; }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="ErrorEventArgs"/> class.
+    /// </summary>
+    /// <param name="currentObject">The current object.</param>
+    /// <param name="errorContext">The error context.</param>
+    public ErrorEventArgs(object currentObject, ErrorContext errorContext)
+    {
+      CurrentObject = currentObject;
+      ErrorContext = errorContext;
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/IContractResolver.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/IContractResolver.cs
index 7545922..a5c5c59 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/IContractResolver.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/IContractResolver.cs
@@ -1,45 +1,46 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Newtonsoft.Json.Serialization
-{
-  /// <summary>
-  /// Used by <see cref="JsonSerializer"/> to resolves a <see cref="JsonContract"/> for a given <see cref="Type"/>.
-  /// </summary>
-  public interface IContractResolver
-  {
-    /// <summary>
-    /// Resolves the contract for a given type.
-    /// </summary>
-    /// <param name="type">The type to resolve a contract for.</param>
-    /// <returns>The contract for a given type.</returns>
-    JsonContract ResolveContract(Type type);
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Used by <see cref="JsonSerializer"/> to resolves a <see cref="JsonContract"/> for a given <see cref="Type"/>.
+  /// </summary>
+  /// <example>
+  ///   <code lang="cs" source="..\Src\Newtonsoft.Json.Tests\Documentation\SerializationTests.cs" region="ReducingSerializedJsonSizeContractResolverObject" title="IContractResolver Class" />
+  ///   <code lang="cs" source="..\Src\Newtonsoft.Json.Tests\Documentation\SerializationTests.cs" region="ReducingSerializedJsonSizeContractResolverExample" title="IContractResolver Example" />
+  /// </example>
+  public interface IContractResolver
+  {
+    /// <summary>
+    /// Resolves the contract for a given type.
+    /// </summary>
+    /// <param name="type">The type to resolve a contract for.</param>
+    /// <returns>The contract for a given type.</returns>
+    JsonContract ResolveContract(Type type);
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/IReferenceResolver.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/IReferenceResolver.cs
index c482de2..bd96b19 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/IReferenceResolver.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/IReferenceResolver.cs
@@ -1,60 +1,64 @@
-#region License
-// 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.
-#endregion
-
-namespace Newtonsoft.Json.Serialization
-{
-  /// <summary>
-  /// Used to resolve references when serializing and deserializing JSON by the <see cref="JsonSerializer"/>.
-  /// </summary>
-  public interface IReferenceResolver
-  {
-    /// <summary>
-    /// Resolves a reference to its object.
-    /// </summary>
-    /// <param name="reference">The reference to resolve.</param>
-    /// <returns>The object that</returns>
-    object ResolveReference(string reference);
-    /// <summary>
-    /// Gets the reference for the sepecified object.
-    /// </summary>
-    /// <param name="value">The object to get a reference for.</param>
-    /// <returns>The reference to the object.</returns>
-    string GetReference(object value);
-    /// <summary>
-    /// Determines whether the specified object is referenced.
-    /// </summary>
-    /// <param name="value">The object to test for a reference.</param>
-    /// <returns>
-    /// 	<c>true</c> if the specified object is referenced; otherwise, <c>false</c>.
-    /// </returns>
-    bool IsReferenced(object value);
-    /// <summary>
-    /// Adds a reference to the specified object.
-    /// </summary>
-    /// <param name="reference">The reference.</param>
-    /// <param name="value">The object to reference.</param>
-    void AddReference(string reference, object value);
-  }
+#region License
+// 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.
+#endregion
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Used to resolve references when serializing and deserializing JSON by the <see cref="JsonSerializer"/>.
+  /// </summary>
+  public interface IReferenceResolver
+  {
+    /// <summary>
+    /// Resolves a reference to its object.
+    /// </summary>
+    /// <param name="context">The serialization context.</param>
+    /// <param name="reference">The reference to resolve.</param>
+    /// <returns>The object that</returns>
+    object ResolveReference(object context, string reference);
+    /// <summary>
+    /// Gets the reference for the sepecified object.
+    /// </summary>
+    /// <param name="context">The serialization context.</param>
+    /// <param name="value">The object to get a reference for.</param>
+    /// <returns>The reference to the object.</returns>
+    string GetReference(object context, object value);
+    /// <summary>
+    /// Determines whether the specified object is referenced.
+    /// </summary>
+    /// <param name="context">The serialization context.</param>
+    /// <param name="value">The object to test for a reference.</param>
+    /// <returns>
+    /// 	<c>true</c> if the specified object is referenced; otherwise, <c>false</c>.
+    /// </returns>
+    bool IsReferenced(object context, object value);
+    /// <summary>
+    /// Adds a reference to the specified object.
+    /// </summary>
+    /// <param name="context">The serialization context.</param>
+    /// <param name="reference">The reference.</param>
+    /// <param name="value">The object to reference.</param>
+    void AddReference(object context, string reference, object value);
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/IValueProvider.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/IValueProvider.cs
index 78fbe51..9f75f7f 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/IValueProvider.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/IValueProvider.cs
@@ -1,47 +1,47 @@
-#region License
-// 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.
-#endregion
-
-namespace Newtonsoft.Json.Serialization
-{
-  /// <summary>
-  /// Provides methods to get and set values.
-  /// </summary>
-  public interface IValueProvider
-  {
-    /// <summary>
-    /// Sets the value.
-    /// </summary>
-    /// <param name="target">The target to set the value on.</param>
-    /// <param name="value">The value to set on the target.</param>
-    void SetValue(object target, object value);
-
-    /// <summary>
-    /// Gets the value.
-    /// </summary>
-    /// <param name="target">The target to get the value from.</param>
-    /// <returns>The value.</returns>
-    object GetValue(object target);
-  }
+#region License
+// 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.
+#endregion
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Provides methods to get and set values.
+  /// </summary>
+  public interface IValueProvider
+  {
+    /// <summary>
+    /// Sets the value.
+    /// </summary>
+    /// <param name="target">The target to set the value on.</param>
+    /// <param name="value">The value to set on the target.</param>
+    void SetValue(object target, object value);
+
+    /// <summary>
+    /// Gets the value.
+    /// </summary>
+    /// <param name="target">The target to get the value from.</param>
+    /// <returns>The value.</returns>
+    object GetValue(object target);
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs
index 1c9849c..b5952e9 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs
@@ -1,100 +1,156 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Reflection;
-using Newtonsoft.Json.Utilities;
-using System.Collections;
-
-namespace Newtonsoft.Json.Serialization
-{
-  /// <summary>
-  /// Contract details for a <see cref="Type"/> used by the <see cref="JsonSerializer"/>.
-  /// </summary>
-  public class JsonArrayContract : JsonContract
-  {
-    internal Type CollectionItemType { get; private set; }
-
-    private readonly bool _isCollectionItemTypeNullableType;
-    private readonly Type _genericCollectionDefinitionType;
-    private Type _genericWrapperType;
-    private MethodCall<object, object> _genericWrapperCreator;
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonArrayContract"/> class.
-    /// </summary>
-    /// <param name="underlyingType">The underlying type for the contract.</param>
-    public JsonArrayContract(Type underlyingType)
-      : base(underlyingType)
-    {
-      if (ReflectionUtils.ImplementsGenericDefinition(underlyingType, typeof(ICollection<>), out _genericCollectionDefinitionType))
-      {
-        CollectionItemType = _genericCollectionDefinitionType.GetGenericArguments()[0];
-      }
-      else
-      {
-        CollectionItemType = ReflectionUtils.GetCollectionItemType(UnderlyingType);
-      }
-
-      if (CollectionItemType != null)
-        _isCollectionItemTypeNullableType = ReflectionUtils.IsNullableType(CollectionItemType);
-
-      if (IsTypeGenericCollectionInterface(UnderlyingType))
-      {
-        CreatedType = ReflectionUtils.MakeGenericType(typeof(List<>), CollectionItemType);
-      }
-    }
-
-    internal IWrappedCollection CreateWrapper(object list)
-    {
-      if ((list is IList && (CollectionItemType == null || !_isCollectionItemTypeNullableType))
-        || UnderlyingType.IsArray)
-        return new CollectionWrapper<object>((IList)list);
-
-      if (_genericWrapperType == null)
-      {
-        _genericWrapperType = ReflectionUtils.MakeGenericType(typeof(CollectionWrapper<>), CollectionItemType);
-
-        ConstructorInfo genericWrapperConstructor = _genericWrapperType.GetConstructor(new[] { _genericCollectionDefinitionType });
-        _genericWrapperCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall<object>(genericWrapperConstructor);
-      }
-
-      return (IWrappedCollection)_genericWrapperCreator(null, list);
-    }
-
-    private bool IsTypeGenericCollectionInterface(Type type)
-    {
-      if (!type.IsGenericType)
-        return false;
-
-      Type genericDefinition = type.GetGenericTypeDefinition();
-
-      return (genericDefinition == typeof(IList<>)
-              || genericDefinition == typeof(ICollection<>)
-              || genericDefinition == typeof(IEnumerable<>));
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using Newtonsoft.Json.Utilities;
+using System.Collections;
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#else
+using System.Linq;
+#endif
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Contract details for a <see cref="Type"/> used by the <see cref="JsonSerializer"/>.
+  /// </summary>
+  public class JsonArrayContract : JsonContainerContract
+  {
+    /// <summary>
+    /// Gets the <see cref="Type"/> of the collection items.
+    /// </summary>
+    /// <value>The <see cref="Type"/> of the collection items.</value>
+    public Type CollectionItemType { get; private set; }
+
+    /// <summary>
+    /// Gets a value indicating whether the collection type is a multidimensional array.
+    /// </summary>
+    /// <value><c>true</c> if the collection type is a multidimensional array; otherwise, <c>false</c>.</value>
+    public bool IsMultidimensionalArray { get; private set; }
+
+    private readonly bool _isCollectionItemTypeNullableType;
+    private readonly Type _genericCollectionDefinitionType;
+    private Type _genericWrapperType;
+    private MethodCall<object, object> _genericWrapperCreator;
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonArrayContract"/> class.
+    /// </summary>
+    /// <param name="underlyingType">The underlying type for the contract.</param>
+    public JsonArrayContract(Type underlyingType)
+      : base(underlyingType)
+    {
+      ContractType = JsonContractType.Array;
+      
+      if (ReflectionUtils.ImplementsGenericDefinition(underlyingType, typeof(ICollection<>), out _genericCollectionDefinitionType))
+      {
+        CollectionItemType = _genericCollectionDefinitionType.GetGenericArguments()[0];
+      }
+      else if (underlyingType.IsGenericType() && underlyingType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
+      {
+        _genericCollectionDefinitionType =  typeof (IEnumerable<>);
+        CollectionItemType = underlyingType.GetGenericArguments()[0];
+      }
+      else
+      {
+        CollectionItemType = ReflectionUtils.GetCollectionItemType(UnderlyingType);
+      }
+
+      if (CollectionItemType != null)
+        _isCollectionItemTypeNullableType = ReflectionUtils.IsNullableType(CollectionItemType);
+
+      if (IsTypeGenericCollectionInterface(UnderlyingType))
+      {
+        CreatedType = ReflectionUtils.MakeGenericType(typeof(List<>), CollectionItemType);
+      }
+
+      IsMultidimensionalArray = (UnderlyingType.IsArray && UnderlyingType.GetArrayRank() > 1);
+    }
+
+    internal IWrappedCollection CreateWrapper(object list)
+    {
+      if ((list is IList && (CollectionItemType == null || !_isCollectionItemTypeNullableType))
+        || UnderlyingType.IsArray)
+        return new CollectionWrapper<object>((IList)list);
+
+      if (_genericCollectionDefinitionType != null)
+      {
+        EnsureGenericWrapperCreator();
+        return (IWrappedCollection) _genericWrapperCreator(null, list);
+      }
+      else
+      {
+        IList values = ((IEnumerable) list).Cast<object>().ToList();
+
+        if (CollectionItemType != null)
+        {
+          Array array = Array.CreateInstance(CollectionItemType, values.Count);
+          for (int i = 0; i < values.Count; i++)
+          {
+            array.SetValue(values[i], i);
+          }
+
+          values = array;
+        }
+
+        return new CollectionWrapper<object>(values);
+      }
+    }
+
+    private void EnsureGenericWrapperCreator()
+    {
+      if (_genericWrapperCreator == null)
+      {
+        _genericWrapperType = ReflectionUtils.MakeGenericType(typeof (CollectionWrapper<>), CollectionItemType);
+
+        Type constructorArgument;
+
+        if (ReflectionUtils.InheritsGenericDefinition(_genericCollectionDefinitionType, typeof(List<>))
+          || _genericCollectionDefinitionType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
+          constructorArgument = ReflectionUtils.MakeGenericType(typeof(ICollection<>), CollectionItemType);
+        else
+          constructorArgument = _genericCollectionDefinitionType;
+
+        ConstructorInfo genericWrapperConstructor = _genericWrapperType.GetConstructor(new[] { constructorArgument });
+        _genericWrapperCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall<object>(genericWrapperConstructor);
+      }
+    }
+
+    private bool IsTypeGenericCollectionInterface(Type type)
+    {
+      if (!type.IsGenericType())
+        return false;
+
+      Type genericDefinition = type.GetGenericTypeDefinition();
+
+      return (genericDefinition == typeof(IList<>)
+              || genericDefinition == typeof(ICollection<>)
+              || genericDefinition == typeof(IEnumerable<>));
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonContainerContract.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonContainerContract.cs
new file mode 100644
index 0000000..98783b0
--- /dev/null
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonContainerContract.cs
@@ -0,0 +1,115 @@
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using Newtonsoft.Json.Utilities;
+using System.Collections;
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#else
+using System.Linq;
+#endif
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Contract details for a <see cref="Type"/> used by the <see cref="JsonSerializer"/>.
+  /// </summary>
+  public class JsonContainerContract : JsonContract
+  {
+    private JsonContract _itemContract;
+    private JsonContract _finalItemContract;
+
+    // will be null for containers that don't have an item type (e.g. IList) or for complex objects
+    internal JsonContract ItemContract
+    {
+      get { return _itemContract; }
+      set
+      {
+        _itemContract = value;
+        if (_itemContract != null)
+        {
+          _finalItemContract = (_itemContract.UnderlyingType.IsSealed()) ? _itemContract : null;
+        }
+        else
+        {
+          _finalItemContract = null;
+        }
+      }
+    }
+
+    // the final (i.e. can't be inherited from like a sealed class or valuetype) item contract
+    internal JsonContract FinalItemContract
+    {
+      get { return _finalItemContract; }
+    }
+
+    /// <summary>
+    /// Gets or sets the default collection items <see cref="JsonConverter" />.
+    /// </summary>
+    /// <value>The converter.</value>
+    public JsonConverter ItemConverter { get; set; }
+
+    /// <summary>
+    /// Gets or sets a value indicating whether the collection items preserve object references.
+    /// </summary>
+    /// <value><c>true</c> if collection items preserve object references; otherwise, <c>false</c>.</value>
+    public bool? ItemIsReference { get; set; }
+
+    /// <summary>
+    /// Gets or sets the collection item reference loop handling.
+    /// </summary>
+    /// <value>The reference loop handling.</value>
+    public ReferenceLoopHandling? ItemReferenceLoopHandling { get; set; }
+
+    /// <summary>
+    /// Gets or sets the collection item type name handling.
+    /// </summary>
+    /// <value>The type name handling.</value>
+    public TypeNameHandling? ItemTypeNameHandling { get; set; }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonContainerContract"/> class.
+    /// </summary>
+    /// <param name="underlyingType">The underlying type for the contract.</param>
+    internal JsonContainerContract(Type underlyingType)
+      : base(underlyingType)
+    {
+      JsonContainerAttribute jsonContainerAttribute = JsonTypeReflector.GetJsonContainerAttribute(underlyingType);
+
+      if (jsonContainerAttribute != null)
+      {
+        if (jsonContainerAttribute.ItemConverterType != null)
+          ItemConverter = JsonConverterAttribute.CreateJsonConverterInstance(jsonContainerAttribute.ItemConverterType);
+
+        ItemIsReference = jsonContainerAttribute._itemIsReference;
+        ItemReferenceLoopHandling = jsonContainerAttribute._itemReferenceLoopHandling;
+        ItemTypeNameHandling = jsonContainerAttribute._itemTypeNameHandling;
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonContract.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonContract.cs
index 857e535..568da9c 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonContract.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonContract.cs
@@ -1,153 +1,219 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Reflection;
-using System.Runtime.Serialization;
-using Newtonsoft.Json.Utilities;
-
-namespace Newtonsoft.Json.Serialization
-{
-  /// <summary>
-  /// Contract details for a <see cref="Type"/> used by the <see cref="JsonSerializer"/>.
-  /// </summary>
-  public abstract class JsonContract
-  {
-    /// <summary>
-    /// Gets the underlying type for the contract.
-    /// </summary>
-    /// <value>The underlying type for the contract.</value>
-    public Type UnderlyingType { get; private set; }
-
-    /// <summary>
-    /// Gets or sets the type created during deserialization.
-    /// </summary>
-    /// <value>The type created during deserialization.</value>
-    public Type CreatedType { get; set; }
-
-    /// <summary>
-    /// Gets or sets whether this type contract is serialized as a reference.
-    /// </summary>
-    /// <value>Whether this type contract is serialized as a reference.</value>
-    public bool? IsReference { get; set; }
-
-    /// <summary>
-    /// Gets or sets the default <see cref="JsonConverter" /> for this contract.
-    /// </summary>
-    /// <value>The converter.</value>
-    public JsonConverter Converter { get; set; }
-
-    // internally specified JsonConverter's to override default behavour
-    // checked for after passed in converters and attribute specified converters
-    internal JsonConverter InternalConverter { get; set; }
-
-#if !PocketPC
-    /// <summary>
-    /// Gets or sets the method called immediately after deserialization of the object.
-    /// </summary>
-    /// <value>The method called immediately after deserialization of the object.</value>
-    public MethodInfo OnDeserialized { get; set; }
-    /// <summary>
-    /// Gets or sets the method called during deserialization of the object.
-    /// </summary>
-    /// <value>The method called during deserialization of the object.</value>
-    public MethodInfo OnDeserializing { get; set; }
-    /// <summary>
-    /// Gets or sets the method called after serialization of the object graph.
-    /// </summary>
-    /// <value>The method called after serialization of the object graph.</value>
-    public MethodInfo OnSerialized { get; set; }
-    /// <summary>
-    /// Gets or sets the method called before serialization of the object.
-    /// </summary>
-    /// <value>The method called before serialization of the object.</value>
-    public MethodInfo OnSerializing { get; set; }
-#endif
-
-    /// <summary>
-    /// Gets or sets the default creator method used to create the object.
-    /// </summary>
-    /// <value>The default creator method used to create the object.</value>
-    public Func<object> DefaultCreator { get; set; }
-
-    /// <summary>
-    /// Gets or sets a value indicating whether [default creator non public].
-    /// </summary>
-    /// <value><c>true</c> if the default object creator is non-public; otherwise, <c>false</c>.</value>
-    public bool DefaultCreatorNonPublic { get; set; }
-
-    /// <summary>
-    /// Gets or sets the method called when an error is thrown during the serialization of the object.
-    /// </summary>
-    /// <value>The method called when an error is thrown during the serialization of the object.</value>
-    public MethodInfo OnError { get; set; }
-
-    internal void InvokeOnSerializing(object o, StreamingContext context)
-    {
-#if !PocketPC
-      if (OnSerializing != null)
-        OnSerializing.Invoke(o, new object[] { context });
-#endif
-    }
-
-    internal void InvokeOnSerialized(object o, StreamingContext context)
-    {
-#if !PocketPC
-      if (OnSerialized != null)
-        OnSerialized.Invoke(o, new object[] { context });
-#endif
-    }
-
-    internal void InvokeOnDeserializing(object o, StreamingContext context)
-    {
-#if !PocketPC
-      if (OnDeserializing != null)
-        OnDeserializing.Invoke(o, new object[] { context });
-#endif
-    }
-
-    internal void InvokeOnDeserialized(object o, StreamingContext context)
-    {
-#if !PocketPC
-      if (OnDeserialized != null)
-        OnDeserialized.Invoke(o, new object[] { context });
-#endif
-    }
-
-    internal void InvokeOnError(object o, StreamingContext context, ErrorContext errorContext)
-    {
-      if (OnError != null)
-        OnError.Invoke(o, new object[] { context, errorContext });
-    }
-
-    internal JsonContract(Type underlyingType)
-    {
-      ValidationUtils.ArgumentNotNull(underlyingType, "underlyingType");
-
-      UnderlyingType = underlyingType;
-      CreatedType = underlyingType;
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Reflection;
+using System.Runtime.Serialization;
+using Newtonsoft.Json.Utilities;
+#if NETFX_CORE
+using IConvertible = Newtonsoft.Json.Utilities.Convertible;
+#endif
+
+namespace Newtonsoft.Json.Serialization
+{
+  internal enum JsonContractType
+  {
+    None,
+    Object,
+    Array,
+    Primitive,
+    String,
+    Dictionary,
+#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
+    Dynamic,
+#endif
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+    Serializable,
+#endif
+    Linq
+  }
+
+  /// <summary>
+  /// Contract details for a <see cref="Type"/> used by the <see cref="JsonSerializer"/>.
+  /// </summary>
+  public abstract class JsonContract
+  {
+    internal bool IsNullable;
+    internal bool IsConvertable;
+    internal Type NonNullableUnderlyingType;
+    internal ReadType InternalReadType;
+    internal JsonContractType ContractType;
+
+    /// <summary>
+    /// Gets the underlying type for the contract.
+    /// </summary>
+    /// <value>The underlying type for the contract.</value>
+    public Type UnderlyingType { get; private set; }
+
+    /// <summary>
+    /// Gets or sets the type created during deserialization.
+    /// </summary>
+    /// <value>The type created during deserialization.</value>
+    public Type CreatedType { get; set; }
+
+    /// <summary>
+    /// Gets or sets whether this type contract is serialized as a reference.
+    /// </summary>
+    /// <value>Whether this type contract is serialized as a reference.</value>
+    public bool? IsReference { get; set; }
+
+    /// <summary>
+    /// Gets or sets the default <see cref="JsonConverter" /> for this contract.
+    /// </summary>
+    /// <value>The converter.</value>
+    public JsonConverter Converter { get; set; }
+
+    // internally specified JsonConverter's to override default behavour
+    // checked for after passed in converters and attribute specified converters
+    internal JsonConverter InternalConverter { get; set; }
+
+#if !PocketPC
+    /// <summary>
+    /// Gets or sets the method called immediately after deserialization of the object.
+    /// </summary>
+    /// <value>The method called immediately after deserialization of the object.</value>
+    public MethodInfo OnDeserialized { get; set; }
+
+    /// <summary>
+    /// Gets or sets the method called during deserialization of the object.
+    /// </summary>
+    /// <value>The method called during deserialization of the object.</value>
+    public MethodInfo OnDeserializing { get; set; }
+
+    /// <summary>
+    /// Gets or sets the method called after serialization of the object graph.
+    /// </summary>
+    /// <value>The method called after serialization of the object graph.</value>
+    public MethodInfo OnSerialized { get; set; }
+
+    /// <summary>
+    /// Gets or sets the method called before serialization of the object.
+    /// </summary>
+    /// <value>The method called before serialization of the object.</value>
+    public MethodInfo OnSerializing { get; set; }
+#endif
+
+    /// <summary>
+    /// Gets or sets the default creator method used to create the object.
+    /// </summary>
+    /// <value>The default creator method used to create the object.</value>
+    public Func<object> DefaultCreator { get; set; }
+
+    /// <summary>
+    /// Gets or sets a value indicating whether the default creator is non public.
+    /// </summary>
+    /// <value><c>true</c> if the default object creator is non-public; otherwise, <c>false</c>.</value>
+    public bool DefaultCreatorNonPublic { get; set; }
+
+    /// <summary>
+    /// Gets or sets the method called when an error is thrown during the serialization of the object.
+    /// </summary>
+    /// <value>The method called when an error is thrown during the serialization of the object.</value>
+    public MethodInfo OnError { get; set; }
+
+    internal void InvokeOnSerializing(object o, StreamingContext context)
+    {
+#if !PocketPC
+      if (OnSerializing != null)
+        OnSerializing.Invoke(o, new object[] {context});
+#endif
+    }
+
+    internal void InvokeOnSerialized(object o, StreamingContext context)
+    {
+#if !PocketPC
+      if (OnSerialized != null)
+        OnSerialized.Invoke(o, new object[] {context});
+#endif
+    }
+
+    internal void InvokeOnDeserializing(object o, StreamingContext context)
+    {
+#if !PocketPC
+      if (OnDeserializing != null)
+        OnDeserializing.Invoke(o, new object[] {context});
+#endif
+    }
+
+    internal void InvokeOnDeserialized(object o, StreamingContext context)
+    {
+#if !PocketPC
+      if (OnDeserialized != null)
+        OnDeserialized.Invoke(o, new object[] {context});
+#endif
+    }
+
+    internal void InvokeOnError(object o, StreamingContext context, ErrorContext errorContext)
+    {
+      if (OnError != null)
+        OnError.Invoke(o, new object[] {context, errorContext});
+    }
+
+    internal JsonContract(Type underlyingType)
+    {
+      ValidationUtils.ArgumentNotNull(underlyingType, "underlyingType");
+
+      UnderlyingType = underlyingType;
+
+      IsNullable = ReflectionUtils.IsNullable(underlyingType);
+      NonNullableUnderlyingType = (IsNullable && ReflectionUtils.IsNullableType(underlyingType)) ? Nullable.GetUnderlyingType(underlyingType) : underlyingType;
+
+      CreatedType = NonNullableUnderlyingType;
+
+      IsConvertable = ConvertUtils.IsConvertible(NonNullableUnderlyingType);
+
+      if (NonNullableUnderlyingType == typeof(byte[]))
+      {
+        InternalReadType = ReadType.ReadAsBytes;
+      }
+      else if (NonNullableUnderlyingType == typeof(int))
+      {
+        InternalReadType = ReadType.ReadAsInt32;
+      }
+      else if (NonNullableUnderlyingType == typeof(decimal))
+      {
+        InternalReadType = ReadType.ReadAsDecimal;
+      }
+      else if (NonNullableUnderlyingType == typeof(string))
+      {
+        InternalReadType = ReadType.ReadAsString;
+      }
+      else if (NonNullableUnderlyingType == typeof(DateTime))
+      {
+        InternalReadType = ReadType.ReadAsDateTime;
+      }
+#if !NET20
+      else if (NonNullableUnderlyingType == typeof(DateTimeOffset))
+      {
+        InternalReadType = ReadType.ReadAsDateTimeOffset;
+      }
+#endif
+      else
+      {
+        InternalReadType = ReadType.Read;
+      }
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs
index 4913b8c..03e3e6b 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs
@@ -1,100 +1,129 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Reflection;
-using Newtonsoft.Json.Utilities;
-using System.Collections;
-
-namespace Newtonsoft.Json.Serialization
-{
-  /// <summary>
-  /// Contract details for a <see cref="Type"/> used by the <see cref="JsonSerializer"/>.
-  /// </summary>
-  public class JsonDictionaryContract : JsonContract
-  {
-    internal Type DictionaryKeyType { get; private set; }
-    internal Type DictionaryValueType { get; private set; }
-
-    private readonly Type _genericCollectionDefinitionType;
-    private Type _genericWrapperType;
-    private MethodCall<object, object> _genericWrapperCreator;
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonDictionaryContract"/> class.
-    /// </summary>
-    /// <param name="underlyingType">The underlying type for the contract.</param>
-    public JsonDictionaryContract(Type underlyingType)
-      : base(underlyingType)
-    {
-      Type keyType;
-      Type valueType;
-      if (ReflectionUtils.ImplementsGenericDefinition(underlyingType, typeof(IDictionary<,>), out _genericCollectionDefinitionType))
-      {
-        keyType = _genericCollectionDefinitionType.GetGenericArguments()[0];
-        valueType = _genericCollectionDefinitionType.GetGenericArguments()[1];
-      }
-      else
-      {
-        ReflectionUtils.GetDictionaryKeyValueTypes(UnderlyingType, out keyType, out valueType);
-      }
-
-      DictionaryKeyType = keyType;
-      DictionaryValueType = valueType;
-
-      if (IsTypeGenericDictionaryInterface(UnderlyingType))
-      {
-        CreatedType = ReflectionUtils.MakeGenericType(typeof(Dictionary<,>), keyType, valueType);
-      }
-    }
-
-    internal IWrappedDictionary CreateWrapper(object dictionary)
-    {
-      if (dictionary is IDictionary)
-        return new DictionaryWrapper<object, object>((IDictionary)dictionary);
-
-      if (_genericWrapperType == null)
-      {
-        _genericWrapperType = ReflectionUtils.MakeGenericType(typeof(DictionaryWrapper<,>), DictionaryKeyType, DictionaryValueType);
-
-        ConstructorInfo genericWrapperConstructor = _genericWrapperType.GetConstructor(new[] { _genericCollectionDefinitionType });
-        _genericWrapperCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall<object>(genericWrapperConstructor);
-      }
-
-      return (IWrappedDictionary)_genericWrapperCreator(null, dictionary);
-    }
-
-    private bool IsTypeGenericDictionaryInterface(Type type)
-    {
-      if (!type.IsGenericType)
-        return false;
-
-      Type genericDefinition = type.GetGenericTypeDefinition();
-
-      return (genericDefinition == typeof(IDictionary<,>));
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using Newtonsoft.Json.Utilities;
+using System.Collections;
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#endif
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Contract details for a <see cref="Type"/> used by the <see cref="JsonSerializer"/>.
+  /// </summary>
+  public class JsonDictionaryContract : JsonContainerContract
+  {
+    /// <summary>
+    /// Gets or sets the property name resolver.
+    /// </summary>
+    /// <value>The property name resolver.</value>
+    public Func<string, string> PropertyNameResolver { get; set; }
+
+    /// <summary>
+    /// Gets the <see cref="Type"/> of the dictionary keys.
+    /// </summary>
+    /// <value>The <see cref="Type"/> of the dictionary keys.</value>
+    public Type DictionaryKeyType { get; private set; }
+    /// <summary>
+    /// Gets the <see cref="Type"/> of the dictionary values.
+    /// </summary>
+    /// <value>The <see cref="Type"/> of the dictionary values.</value>
+    public Type DictionaryValueType { get; private set; }
+
+    internal JsonContract KeyContract { get; set; }
+
+    private readonly bool _isDictionaryValueTypeNullableType;
+    private readonly Type _genericCollectionDefinitionType;
+    private Type _genericWrapperType;
+    private MethodCall<object, object> _genericWrapperCreator;
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonDictionaryContract"/> class.
+    /// </summary>
+    /// <param name="underlyingType">The underlying type for the contract.</param>
+    public JsonDictionaryContract(Type underlyingType)
+      : base(underlyingType)
+    {
+      ContractType = JsonContractType.Dictionary;
+
+      Type keyType;
+      Type valueType;
+      if (ReflectionUtils.ImplementsGenericDefinition(underlyingType, typeof(IDictionary<,>), out _genericCollectionDefinitionType))
+      {
+        keyType = _genericCollectionDefinitionType.GetGenericArguments()[0];
+        valueType = _genericCollectionDefinitionType.GetGenericArguments()[1];
+      }
+      else
+      {
+        ReflectionUtils.GetDictionaryKeyValueTypes(UnderlyingType, out keyType, out valueType);
+      }
+
+      DictionaryKeyType = keyType;
+      DictionaryValueType = valueType;
+
+      if (DictionaryValueType != null)
+        _isDictionaryValueTypeNullableType = ReflectionUtils.IsNullableType(DictionaryValueType);
+      
+      if (IsTypeGenericDictionaryInterface(UnderlyingType))
+      {
+        CreatedType = ReflectionUtils.MakeGenericType(typeof(Dictionary<,>), keyType, valueType);
+      }
+      else if (UnderlyingType == typeof(IDictionary))
+      {
+        CreatedType = typeof (Dictionary<object, object>);
+      }
+    }
+
+    internal IWrappedDictionary CreateWrapper(object dictionary)
+    {
+      if (dictionary is IDictionary && (DictionaryValueType == null || !_isDictionaryValueTypeNullableType))
+        return new DictionaryWrapper<object, object>((IDictionary)dictionary);
+
+      if (_genericWrapperCreator == null)
+      {
+        _genericWrapperType = ReflectionUtils.MakeGenericType(typeof(DictionaryWrapper<,>), DictionaryKeyType, DictionaryValueType);
+
+        ConstructorInfo genericWrapperConstructor = _genericWrapperType.GetConstructor(new[] { _genericCollectionDefinitionType });
+        _genericWrapperCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall<object>(genericWrapperConstructor);
+      }
+
+      return (IWrappedDictionary)_genericWrapperCreator(null, dictionary);
+    }
+
+    private bool IsTypeGenericDictionaryInterface(Type type)
+    {
+      if (!type.IsGenericType())
+        return false;
+
+      Type genericDefinition = type.GetGenericTypeDefinition();
+
+      return (genericDefinition == typeof(IDictionary<,>));
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonDynamicContract.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonDynamicContract.cs
new file mode 100644
index 0000000..6b5b898
--- /dev/null
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonDynamicContract.cs
@@ -0,0 +1,65 @@
+#region License
+// 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.
+#endregion
+
+#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using Newtonsoft.Json.Utilities;
+using System.Collections;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Contract details for a <see cref="Type"/> used by the <see cref="JsonSerializer"/>.
+  /// </summary>
+  public class JsonDynamicContract : JsonContainerContract
+  {
+    /// <summary>
+    /// Gets the object's properties.
+    /// </summary>
+    /// <value>The object's properties.</value>
+    public JsonPropertyCollection Properties { get; private set; }
+
+    /// <summary>
+    /// Gets or sets the property name resolver.
+    /// </summary>
+    /// <value>The property name resolver.</value>
+    public Func<string, string> PropertyNameResolver { get; set; }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonDynamicContract"/> class.
+    /// </summary>
+    /// <param name="underlyingType">The underlying type for the contract.</param>
+    public JsonDynamicContract(Type underlyingType)
+      : base(underlyingType)
+    {
+      ContractType = JsonContractType.Dynamic;
+
+      Properties = new JsonPropertyCollection(UnderlyingType);
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonFormatterConverter.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonFormatterConverter.cs
index 36b2563..4ecbdb2 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonFormatterConverter.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonFormatterConverter.cs
@@ -1,154 +1,151 @@
-#region License
-// 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.
-#endregion
-
-#if !SILVERLIGHT && !PocketPC
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Runtime.Serialization;
-using System.Text;
-using Newtonsoft.Json.Utilities;
-using Newtonsoft.Json.Linq;
-
-namespace Newtonsoft.Json.Serialization
-{
-  internal class JsonFormatterConverter : IFormatterConverter
-  {
-    private readonly JsonSerializer _serializer;
-
-    public JsonFormatterConverter(JsonSerializer serializer)
-    {
-      ValidationUtils.ArgumentNotNull(serializer, "serializer");
-
-      _serializer = serializer;
-    }
-
-    private T GetTokenValue<T>(object value)
-    {
-      ValidationUtils.ArgumentNotNull(value, "value");
-      
-      JValue v = (JValue)value;
-      return (T)System.Convert.ChangeType(v.Value, typeof(T), CultureInfo.InvariantCulture);
-    }
-
-    public object Convert(object value, Type type)
-    {
-      ValidationUtils.ArgumentNotNull(value, "value");
-
-      JToken token = value as JToken;
-      if (token == null)
-        throw new ArgumentException("Value is not a JToken.", "value");
-
-      return _serializer.Deserialize(token.CreateReader(), type);
-    }
-
-    public object Convert(object value, TypeCode typeCode)
-    {
-      ValidationUtils.ArgumentNotNull(value, "value");
-
-      if (value is JValue)
-        value = ((JValue) value).Value;
-
-      return System.Convert.ChangeType(value, typeCode, CultureInfo.InvariantCulture);
-    }
-
-    public bool ToBoolean(object value)
-    {
-      return GetTokenValue<bool>(value);
-    }
-
-    public byte ToByte(object value)
-    {
-      return GetTokenValue<byte>(value);
-    }
-
-    public char ToChar(object value)
-    {
-      return GetTokenValue<char>(value);
-    }
-
-    public DateTime ToDateTime(object value)
-    {
-      return GetTokenValue<DateTime>(value);
-    }
-
-    public decimal ToDecimal(object value)
-    {
-      return GetTokenValue<decimal>(value);
-    }
-
-    public double ToDouble(object value)
-    {
-      return GetTokenValue<double>(value);
-    }
-
-    public short ToInt16(object value)
-    {
-      return GetTokenValue<short>(value);
-    }
-
-    public int ToInt32(object value)
-    {
-      return GetTokenValue<int>(value);
-    }
-
-    public long ToInt64(object value)
-    {
-      return GetTokenValue<long>(value);
-    }
-
-    public sbyte ToSByte(object value)
-    {
-      return GetTokenValue<sbyte>(value);
-    }
-
-    public float ToSingle(object value)
-    {
-      return GetTokenValue<float>(value);
-    }
-
-    public string ToString(object value)
-    {
-      return GetTokenValue<string>(value);
-    }
-
-    public ushort ToUInt16(object value)
-    {
-      return GetTokenValue<ushort>(value);
-    }
-
-    public uint ToUInt32(object value)
-    {
-      return GetTokenValue<uint>(value);
-    }
-
-    public ulong ToUInt64(object value)
-    {
-      return GetTokenValue<ulong>(value);
-    }
-  }
-}
+#region License
+// 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.
+#endregion
+
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+using System;
+using System.Globalization;
+using System.Runtime.Serialization;
+using Newtonsoft.Json.Utilities;
+using Newtonsoft.Json.Linq;
+
+namespace Newtonsoft.Json.Serialization
+{
+  internal class JsonFormatterConverter : IFormatterConverter
+  {
+    private readonly JsonSerializer _serializer;
+
+    public JsonFormatterConverter(JsonSerializer serializer)
+    {
+      ValidationUtils.ArgumentNotNull(serializer, "serializer");
+
+      _serializer = serializer;
+    }
+
+    private T GetTokenValue<T>(object value)
+    {
+      ValidationUtils.ArgumentNotNull(value, "value");
+      
+      JValue v = (JValue)value;
+      return (T)System.Convert.ChangeType(v.Value, typeof(T), CultureInfo.InvariantCulture);
+    }
+
+    public object Convert(object value, Type type)
+    {
+      ValidationUtils.ArgumentNotNull(value, "value");
+
+      JToken token = value as JToken;
+      if (token == null)
+        throw new ArgumentException("Value is not a JToken.", "value");
+
+      return _serializer.Deserialize(token.CreateReader(), type);
+    }
+
+    public object Convert(object value, TypeCode typeCode)
+    {
+      ValidationUtils.ArgumentNotNull(value, "value");
+
+      if (value is JValue)
+        value = ((JValue) value).Value;
+
+      return System.Convert.ChangeType(value, typeCode, CultureInfo.InvariantCulture);
+    }
+
+    public bool ToBoolean(object value)
+    {
+      return GetTokenValue<bool>(value);
+    }
+
+    public byte ToByte(object value)
+    {
+      return GetTokenValue<byte>(value);
+    }
+
+    public char ToChar(object value)
+    {
+      return GetTokenValue<char>(value);
+    }
+
+    public DateTime ToDateTime(object value)
+    {
+      return GetTokenValue<DateTime>(value);
+    }
+
+    public decimal ToDecimal(object value)
+    {
+      return GetTokenValue<decimal>(value);
+    }
+
+    public double ToDouble(object value)
+    {
+      return GetTokenValue<double>(value);
+    }
+
+    public short ToInt16(object value)
+    {
+      return GetTokenValue<short>(value);
+    }
+
+    public int ToInt32(object value)
+    {
+      return GetTokenValue<int>(value);
+    }
+
+    public long ToInt64(object value)
+    {
+      return GetTokenValue<long>(value);
+    }
+
+    public sbyte ToSByte(object value)
+    {
+      return GetTokenValue<sbyte>(value);
+    }
+
+    public float ToSingle(object value)
+    {
+      return GetTokenValue<float>(value);
+    }
+
+    public string ToString(object value)
+    {
+      return GetTokenValue<string>(value);
+    }
+
+    public ushort ToUInt16(object value)
+    {
+      return GetTokenValue<ushort>(value);
+    }
+
+    public uint ToUInt32(object value)
+    {
+      return GetTokenValue<uint>(value);
+    }
+
+    public ulong ToUInt64(object value)
+    {
+      return GetTokenValue<ulong>(value);
+    }
+  }
+}
 #endif
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonISerializableContract.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonISerializableContract.cs
index ee1eadb..560ef74 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonISerializableContract.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonISerializableContract.cs
@@ -1,56 +1,53 @@
-#region License
-// 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.
-#endregion
-
-#if !SILVERLIGHT && !PocketPC
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Newtonsoft.Json.Utilities;
-
-namespace Newtonsoft.Json.Serialization
-{
-  /// <summary>
-  /// Contract details for a <see cref="Type"/> used by the <see cref="JsonSerializer"/>.
-  /// </summary>
-  public class JsonISerializableContract : JsonContract
-  {
-    /// <summary>
-    /// Gets or sets the ISerializable object constructor.
-    /// </summary>
-    /// <value>The ISerializable object constructor.</value>
-    public ObjectConstructor<object> ISerializableCreator { get; set; }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonISerializableContract"/> class.
-    /// </summary>
-    /// <param name="underlyingType">The underlying type for the contract.</param>
-    public JsonISerializableContract(Type underlyingType)
-      : base(underlyingType)
-    {
-    }
-  }
-}
+#region License
+// 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.
+#endregion
+
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+using System;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Contract details for a <see cref="Type"/> used by the <see cref="JsonSerializer"/>.
+  /// </summary>
+  public class JsonISerializableContract : JsonContract
+  {
+    /// <summary>
+    /// Gets or sets the ISerializable object constructor.
+    /// </summary>
+    /// <value>The ISerializable object constructor.</value>
+    public ObjectConstructor<object> ISerializableCreator { get; set; }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonISerializableContract"/> class.
+    /// </summary>
+    /// <param name="underlyingType">The underlying type for the contract.</param>
+    public JsonISerializableContract(Type underlyingType)
+      : base(underlyingType)
+    {
+      ContractType = JsonContractType.Serializable;
+    }
+  }
+}
 #endif
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonLinqContract.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonLinqContract.cs
index bc3526f..c107014 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonLinqContract.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonLinqContract.cs
@@ -1,22 +1,45 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Newtonsoft.Json.Serialization
-{
-  /// <summary>
-  /// Contract details for a <see cref="Type"/> used by the <see cref="JsonSerializer"/>.
-  /// </summary>
-  public class JsonLinqContract : JsonContract
-  {
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonLinqContract"/> class.
-    /// </summary>
-    /// <param name="underlyingType">The underlying type for the contract.</param>
-    public JsonLinqContract(Type underlyingType)
-      : base(underlyingType)
-    {
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Contract details for a <see cref="Type"/> used by the <see cref="JsonSerializer"/>.
+  /// </summary>
+  public class JsonLinqContract : JsonContract
+  {
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonLinqContract"/> class.
+    /// </summary>
+    /// <param name="underlyingType">The underlying type for the contract.</param>
+    public JsonLinqContract(Type underlyingType)
+      : base(underlyingType)
+    {
+      ContractType = JsonContractType.Linq;
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonObjectContract.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonObjectContract.cs
index bb07896..0a4806d 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonObjectContract.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonObjectContract.cs
@@ -1,64 +1,136 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Reflection;
-
-namespace Newtonsoft.Json.Serialization
-{
-  /// <summary>
-  /// Contract details for a <see cref="Type"/> used by the <see cref="JsonSerializer"/>.
-  /// </summary>
-  public class JsonObjectContract : JsonContract
-  {
-    /// <summary>
-    /// Gets or sets the object member serialization.
-    /// </summary>
-    /// <value>The member object serialization.</value>
-    public MemberSerialization MemberSerialization { get; set; }
-
-    /// <summary>
-    /// Gets the object's properties.
-    /// </summary>
-    /// <value>The object's properties.</value>
-    public JsonPropertyCollection Properties { get; private set; }
-
-    /// <summary>
-    /// Gets or sets the parametrized constructor used to create the object.
-    /// </summary>
-    /// <value>The parametrized constructor.</value>
-    public ConstructorInfo ParametrizedConstructor { get; set; }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonObjectContract"/> class.
-    /// </summary>
-    /// <param name="underlyingType">The underlying type for the contract.</param>
-    public JsonObjectContract(Type underlyingType)
-      : base(underlyingType)
-    {
-      Properties = new JsonPropertyCollection(this);
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Globalization;
+using System.Reflection;
+using System.Runtime.Serialization;
+using System.Security;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Contract details for a <see cref="Type"/> used by the <see cref="JsonSerializer"/>.
+  /// </summary>
+  public class JsonObjectContract : JsonContainerContract
+  {
+    /// <summary>
+    /// Gets or sets the object member serialization.
+    /// </summary>
+    /// <value>The member object serialization.</value>
+    public MemberSerialization MemberSerialization { get; set; }
+
+    /// <summary>
+    /// Gets or sets a value that indicates whether the object's properties are required.
+    /// </summary>
+    /// <value>
+    /// 	A value indicating whether the object's properties are required.
+    /// </value>
+    public Required? ItemRequired { get; set; }
+
+    /// <summary>
+    /// Gets the object's properties.
+    /// </summary>
+    /// <value>The object's properties.</value>
+    public JsonPropertyCollection Properties { get; private set; }
+
+    /// <summary>
+    /// Gets the constructor parameters required for any non-default constructor
+    /// </summary>
+    public JsonPropertyCollection ConstructorParameters { get; private set; }
+
+    /// <summary>
+    /// Gets or sets the override constructor used to create the object.
+    /// This is set when a constructor is marked up using the
+    /// JsonConstructor attribute.
+    /// </summary>
+    /// <value>The override constructor.</value>
+    public ConstructorInfo OverrideConstructor { get; set; }
+
+    /// <summary>
+    /// Gets or sets the parametrized constructor used to create the object.
+    /// </summary>
+    /// <value>The parametrized constructor.</value>
+    public ConstructorInfo ParametrizedConstructor { get; set; }
+
+    private bool? _hasRequiredOrDefaultValueProperties;
+    internal bool HasRequiredOrDefaultValueProperties
+    {
+      get
+      {
+        if (_hasRequiredOrDefaultValueProperties == null)
+        {
+          _hasRequiredOrDefaultValueProperties = false;
+
+          if (ItemRequired.GetValueOrDefault(Required.Default) != Required.Default)
+          {
+            _hasRequiredOrDefaultValueProperties = true;
+          }
+          else
+          {
+            foreach (JsonProperty property in Properties)
+            {
+              if (property.Required != Required.Default || ((property.DefaultValueHandling & DefaultValueHandling.Populate) == DefaultValueHandling.Populate) && property.Writable)
+              {
+                _hasRequiredOrDefaultValueProperties = true;
+                break;
+              }
+            }
+          }
+        }
+
+        return _hasRequiredOrDefaultValueProperties.Value;
+      }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonObjectContract"/> class.
+    /// </summary>
+    /// <param name="underlyingType">The underlying type for the contract.</param>
+    public JsonObjectContract(Type underlyingType)
+      : base(underlyingType)
+    {
+      ContractType = JsonContractType.Object;
+
+      Properties = new JsonPropertyCollection(UnderlyingType);
+      ConstructorParameters = new JsonPropertyCollection(UnderlyingType);
+    }
+
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+#if !(NET20 || NET35)
+    [SecuritySafeCritical]
+#endif
+    internal object GetUninitializedObject()
+    {
+      // we should never get here if the environment is not fully trusted, check just in case
+      if (!JsonTypeReflector.FullyTrusted)
+        throw new JsonException("Insufficient permissions. Creating an uninitialized '{0}' type requires full trust.".FormatWith(CultureInfo.InvariantCulture, NonNullableUnderlyingType));
+
+      return FormatterServices.GetUninitializedObject(NonNullableUnderlyingType);
+    }
+#endif
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonPrimitiveContract.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonPrimitiveContract.cs
index 60bc83a..ddd1629 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonPrimitiveContract.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonPrimitiveContract.cs
@@ -1,44 +1,45 @@
-#region License
-// 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.
-#endregion
-
-using System;
-
-namespace Newtonsoft.Json.Serialization
-{
-  /// <summary>
-  /// Contract details for a <see cref="Type"/> used by the <see cref="JsonSerializer"/>.
-  /// </summary>
-  public class JsonPrimitiveContract : JsonContract
-  {
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonPrimitiveContract"/> class.
-    /// </summary>
-    /// <param name="underlyingType">The underlying type for the contract.</param>
-    public JsonPrimitiveContract(Type underlyingType)
-      : base(underlyingType)
-    {
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Contract details for a <see cref="Type"/> used by the <see cref="JsonSerializer"/>.
+  /// </summary>
+  public class JsonPrimitiveContract : JsonContract
+  {
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonPrimitiveContract"/> class.
+    /// </summary>
+    /// <param name="underlyingType">The underlying type for the contract.</param>
+    public JsonPrimitiveContract(Type underlyingType)
+      : base(underlyingType)
+    {
+      ContractType = JsonContractType.Primitive;
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonProperty.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonProperty.cs
index 13d721c..5c39cbe 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonProperty.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonProperty.cs
@@ -1,151 +1,223 @@
-#region License
-// 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.
-#endregion
-
-using System;
-
-namespace Newtonsoft.Json.Serialization
-{
-  /// <summary>
-  /// Maps a JSON property to a .NET member.
-  /// </summary>
-  public class JsonProperty
-  {
-    /// <summary>
-    /// Gets the name of the property.
-    /// </summary>
-    /// <value>The name of the property.</value>
-    public string PropertyName { get; set; }
-
-    /// <summary>
-    /// Gets the <see cref="IValueProvider"/> that will get and set the <see cref="JsonProperty"/> during serialization.
-    /// </summary>
-    /// <value>The <see cref="IValueProvider"/> that will get and set the <see cref="JsonProperty"/> during serialization.</value>
-    public IValueProvider ValueProvider { get; set; }
-
-    /// <summary>
-    /// Gets or sets the type of the property.
-    /// </summary>
-    /// <value>The type of the property.</value>
-    public Type PropertyType { get; set; }
-
-    /// <summary>
-    /// Gets or sets the <see cref="JsonConverter" /> for the property.
-    /// If set this converter takes presidence over the contract converter for the property type.
-    /// </summary>
-    /// <value>The converter.</value>
-    public JsonConverter Converter { get; set; }
-
-    /// <summary>
-    /// Gets a value indicating whether this <see cref="JsonProperty"/> is ignored.
-    /// </summary>
-    /// <value><c>true</c> if ignored; otherwise, <c>false</c>.</value>
-    public bool Ignored { get; set; }
-
-    /// <summary>
-    /// Gets a value indicating whether this <see cref="JsonProperty"/> is readable.
-    /// </summary>
-    /// <value><c>true</c> if readable; otherwise, <c>false</c>.</value>
-    public bool Readable { get; set; }
-
-    /// <summary>
-    /// Gets a value indicating whether this <see cref="JsonProperty"/> is writable.
-    /// </summary>
-    /// <value><c>true</c> if writable; otherwise, <c>false</c>.</value>
-    public bool Writable { get; set; }
-
-    /// <summary>
-    /// Gets the member converter.
-    /// </summary>
-    /// <value>The member converter.</value>
-    public JsonConverter MemberConverter { get; set; }
-
-    /// <summary>
-    /// Gets the default value.
-    /// </summary>
-    /// <value>The default value.</value>
-    public object DefaultValue { get; set; }
-
-    /// <summary>
-    /// Gets a value indicating whether this <see cref="JsonProperty"/> is required.
-    /// </summary>
-    /// <value>A value indicating whether this <see cref="JsonProperty"/> is required.</value>
-    public Required Required { get; set; }
-
-    /// <summary>
-    /// Gets a value indicating whether this property preserves object references.
-    /// </summary>
-    /// <value>
-    /// 	<c>true</c> if this instance is reference; otherwise, <c>false</c>.
-    /// </value>
-    public bool? IsReference { get; set; }
-
-    /// <summary>
-    /// Gets the property null value handling.
-    /// </summary>
-    /// <value>The null value handling.</value>
-    public NullValueHandling? NullValueHandling { get; set; }
-
-    /// <summary>
-    /// Gets the property default value handling.
-    /// </summary>
-    /// <value>The default value handling.</value>
-    public DefaultValueHandling? DefaultValueHandling { get; set; }
-
-    /// <summary>
-    /// Gets the property reference loop handling.
-    /// </summary>
-    /// <value>The reference loop handling.</value>
-    public ReferenceLoopHandling? ReferenceLoopHandling { get; set; }
-
-    /// <summary>
-    /// Gets the property object creation handling.
-    /// </summary>
-    /// <value>The object creation handling.</value>
-    public ObjectCreationHandling? ObjectCreationHandling { get; set; }
-
-    /// <summary>
-    /// Gets or sets the type name handling.
-    /// </summary>
-    /// <value>The type name handling.</value>
-    public TypeNameHandling? TypeNameHandling { get; set; }
-
-    /// <summary>
-    /// Gets or sets a predicate used to determine whether the property should be serialize.
-    /// </summary>
-    /// <value>A predicate used to determine whether the property should be serialize.</value>
-    public Predicate<object> ShouldSerialize { get; set; }
-
-    /// <summary>
-    /// Returns a <see cref="String"/> that represents this instance.
-    /// </summary>
-    /// <returns>
-    /// A <see cref="String"/> that represents this instance.
-    /// </returns>
-    public override string ToString()
-    {
-      return PropertyName;
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#endif
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Maps a JSON property to a .NET member or constructor parameter.
+  /// </summary>
+  public class JsonProperty
+  {
+    internal Required? _required;
+
+    // use to cache contract during deserialization
+    internal JsonContract PropertyContract { get; set; }
+    
+    /// <summary>
+    /// Gets or sets the name of the property.
+    /// </summary>
+    /// <value>The name of the property.</value>
+    public string PropertyName { get; set; }
+
+    /// <summary>
+    /// Gets or sets the type that declared this property.
+    /// </summary>
+    /// <value>The type that declared this property.</value>
+    public Type DeclaringType { get; set; }
+
+    /// <summary>
+    /// Gets or sets the order of serialization and deserialization of a member.
+    /// </summary>
+    /// <value>The numeric order of serialization or deserialization.</value>
+    public int? Order { get; set; }
+
+    /// <summary>
+    /// Gets or sets the name of the underlying member or parameter.
+    /// </summary>
+    /// <value>The name of the underlying member or parameter.</value>
+    public string UnderlyingName { get; set; }
+
+    /// <summary>
+    /// Gets the <see cref="IValueProvider"/> that will get and set the <see cref="JsonProperty"/> during serialization.
+    /// </summary>
+    /// <value>The <see cref="IValueProvider"/> that will get and set the <see cref="JsonProperty"/> during serialization.</value>
+    public IValueProvider ValueProvider { get; set; }
+
+    /// <summary>
+    /// Gets or sets the type of the property.
+    /// </summary>
+    /// <value>The type of the property.</value>
+    public Type PropertyType { get; set; }
+
+    /// <summary>
+    /// Gets or sets the <see cref="JsonConverter" /> for the property.
+    /// If set this converter takes presidence over the contract converter for the property type.
+    /// </summary>
+    /// <value>The converter.</value>
+    public JsonConverter Converter { get; set; }
+
+    /// <summary>
+    /// Gets the member converter.
+    /// </summary>
+    /// <value>The member converter.</value>
+    public JsonConverter MemberConverter { get; set; }
+
+    /// <summary>
+    /// Gets a value indicating whether this <see cref="JsonProperty"/> is ignored.
+    /// </summary>
+    /// <value><c>true</c> if ignored; otherwise, <c>false</c>.</value>
+    public bool Ignored { get; set; }
+
+    /// <summary>
+    /// Gets a value indicating whether this <see cref="JsonProperty"/> is readable.
+    /// </summary>
+    /// <value><c>true</c> if readable; otherwise, <c>false</c>.</value>
+    public bool Readable { get; set; }
+
+    /// <summary>
+    /// Gets a value indicating whether this <see cref="JsonProperty"/> is writable.
+    /// </summary>
+    /// <value><c>true</c> if writable; otherwise, <c>false</c>.</value>
+    public bool Writable { get; set; }
+
+    /// <summary>
+    /// Gets a value indicating whether this <see cref="JsonProperty"/> has a member attribute.
+    /// </summary>
+    /// <value><c>true</c> if has a member attribute; otherwise, <c>false</c>.</value>
+    public bool HasMemberAttribute { get; set; }
+
+    /// <summary>
+    /// Gets the default value.
+    /// </summary>
+    /// <value>The default value.</value>
+    public object DefaultValue { get; set; }
+
+    /// <summary>
+    /// Gets a value indicating whether this <see cref="JsonProperty"/> is required.
+    /// </summary>
+    /// <value>A value indicating whether this <see cref="JsonProperty"/> is required.</value>
+    public Required Required
+    {
+      get { return _required ?? Required.Default; }
+      set { _required = value; }
+    }
+
+    /// <summary>
+    /// Gets a value indicating whether this property preserves object references.
+    /// </summary>
+    /// <value>
+    /// 	<c>true</c> if this instance is reference; otherwise, <c>false</c>.
+    /// </value>
+    public bool? IsReference { get; set; }
+
+    /// <summary>
+    /// Gets the property null value handling.
+    /// </summary>
+    /// <value>The null value handling.</value>
+    public NullValueHandling? NullValueHandling { get; set; }
+
+    /// <summary>
+    /// Gets the property default value handling.
+    /// </summary>
+    /// <value>The default value handling.</value>
+    public DefaultValueHandling? DefaultValueHandling { get; set; }
+
+    /// <summary>
+    /// Gets the property reference loop handling.
+    /// </summary>
+    /// <value>The reference loop handling.</value>
+    public ReferenceLoopHandling? ReferenceLoopHandling { get; set; }
+
+    /// <summary>
+    /// Gets the property object creation handling.
+    /// </summary>
+    /// <value>The object creation handling.</value>
+    public ObjectCreationHandling? ObjectCreationHandling { get; set; }
+
+    /// <summary>
+    /// Gets or sets the type name handling.
+    /// </summary>
+    /// <value>The type name handling.</value>
+    public TypeNameHandling? TypeNameHandling { get; set; }
+
+    /// <summary>
+    /// Gets or sets a predicate used to determine whether the property should be serialize.
+    /// </summary>
+    /// <value>A predicate used to determine whether the property should be serialize.</value>
+    public Predicate<object> ShouldSerialize { get; set; }
+
+    /// <summary>
+    /// Gets or sets a predicate used to determine whether the property should be serialized.
+    /// </summary>
+    /// <value>A predicate used to determine whether the property should be serialized.</value>
+    public Predicate<object> GetIsSpecified { get; set; }
+
+    /// <summary>
+    /// Gets or sets an action used to set whether the property has been deserialized.
+    /// </summary>
+    /// <value>An action used to set whether the property has been deserialized.</value>
+    public Action<object, object> SetIsSpecified { get; set; }
+
+    /// <summary>
+    /// Returns a <see cref="String"/> that represents this instance.
+    /// </summary>
+    /// <returns>
+    /// A <see cref="String"/> that represents this instance.
+    /// </returns>
+    public override string ToString()
+    {
+      return PropertyName;
+    }
+
+    /// <summary>
+    /// Gets or sets the converter used when serializing the property's collection items.
+    /// </summary>
+    /// <value>The collection's items converter.</value>
+    public JsonConverter ItemConverter { get; set; }
+
+    /// <summary>
+    /// Gets or sets whether this property's collection items are serialized as a reference.
+    /// </summary>
+    /// <value>Whether this property's collection items are serialized as a reference.</value>
+    public bool? ItemIsReference { get; set; }
+
+    /// <summary>
+    /// Gets or sets the the type name handling used when serializing the property's collection items.
+    /// </summary>
+    /// <value>The collection's items type name handling.</value>
+    public TypeNameHandling? ItemTypeNameHandling { get; set; }
+
+    /// <summary>
+    /// Gets or sets the the reference loop handling used when serializing the property's collection items.
+    /// </summary>
+    /// <value>The collection's items reference loop handling.</value>
+    public ReferenceLoopHandling? ItemReferenceLoopHandling { get; set; }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonPropertyCollection.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonPropertyCollection.cs
index 8bf17c9..41b953b 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonPropertyCollection.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonPropertyCollection.cs
@@ -1,122 +1,164 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Collections.ObjectModel;
-using Newtonsoft.Json.Utilities;
-using System.Globalization;
-
-namespace Newtonsoft.Json.Serialization
-{
-  /// <summary>
-  /// A collection of <see cref="JsonProperty"/> objects.
-  /// </summary>
-  public class JsonPropertyCollection : KeyedCollection<string, JsonProperty>
-  {
-    private readonly JsonObjectContract _contract;
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonPropertyCollection"/> class.
-    /// </summary>
-    /// <param name="contract">The contract.</param>
-    public JsonPropertyCollection(JsonObjectContract contract)
-    {
-      ValidationUtils.ArgumentNotNull(contract, "contract");
-      _contract = contract;
-    }
-
-    /// <summary>
-    /// When implemented in a derived class, extracts the key from the specified element.
-    /// </summary>
-    /// <param name="item">The element from which to extract the key.</param>
-    /// <returns>The key for the specified element.</returns>
-    protected override string GetKeyForItem(JsonProperty item)
-    {
-      return item.PropertyName;
-    }
-
-    /// <summary>
-    /// Adds a <see cref="JsonProperty"/> object.
-    /// </summary>
-    /// <param name="property">The property to add to the collection.</param>
-    public void AddProperty(JsonProperty property)
-    {
-      if (Contains(property.PropertyName))
-      {
-        // don't overwrite existing property with ignored property
-        if (property.Ignored)
-          return;
-
-        JsonProperty existingProperty = this[property.PropertyName];
-
-        if (!existingProperty.Ignored)
-          throw new JsonSerializationException(
-            "A member with the name '{0}' already exists on '{1}'. Use the JsonPropertyAttribute to specify another name.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName, _contract.UnderlyingType));
-
-        // remove ignored property so it can be replaced in collection
-        Remove(existingProperty);
-      }
-
-      Add(property);
-    }
-
-    /// <summary>
-    /// Gets the closest matching <see cref="JsonProperty"/> object.
-    /// First attempts to get an exact case match of propertyName and then
-    /// a case insensitive match.
-    /// </summary>
-    /// <param name="propertyName">Name of the property.</param>
-    /// <returns>A matching property if found.</returns>
-    public JsonProperty GetClosestMatchProperty(string propertyName)
-    {
-      JsonProperty property = GetProperty(propertyName, StringComparison.Ordinal);
-      if (property == null)
-        property = GetProperty(propertyName, StringComparison.OrdinalIgnoreCase);
-
-      return property;
-    }
-
-    /// <summary>
-    /// Gets a property by property name.
-    /// </summary>
-    /// <param name="propertyName">The name of the property to get.</param>
-    /// <param name="comparisonType">Type property name string comparison.</param>
-    /// <returns>A matching property if found.</returns>
-    public JsonProperty GetProperty(string propertyName, StringComparison comparisonType)
-    {
-      foreach (JsonProperty property in this)
-      {
-        if (string.Equals(propertyName, property.PropertyName, comparisonType))
-        {
-          return property;
-        }
-      }
-
-      return null;
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Collections.ObjectModel;
+using Newtonsoft.Json.Utilities;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// A collection of <see cref="JsonProperty"/> objects.
+  /// </summary>
+  public class JsonPropertyCollection : KeyedCollection<string, JsonProperty>
+  {
+    private readonly Type _type;
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonPropertyCollection"/> class.
+    /// </summary>
+    /// <param name="type">The type.</param>
+    public JsonPropertyCollection(Type type)
+      : base(StringComparer.Ordinal)
+    {
+      ValidationUtils.ArgumentNotNull(type, "type");
+      _type = type;
+    }
+
+    /// <summary>
+    /// When implemented in a derived class, extracts the key from the specified element.
+    /// </summary>
+    /// <param name="item">The element from which to extract the key.</param>
+    /// <returns>The key for the specified element.</returns>
+    protected override string GetKeyForItem(JsonProperty item)
+    {
+      return item.PropertyName;
+    }
+
+    /// <summary>
+    /// Adds a <see cref="JsonProperty"/> object.
+    /// </summary>
+    /// <param name="property">The property to add to the collection.</param>
+    public void AddProperty(JsonProperty property)
+    {
+      if (Contains(property.PropertyName))
+      {
+        // don't overwrite existing property with ignored property
+        if (property.Ignored)
+          return;
+
+        JsonProperty existingProperty = this[property.PropertyName];
+        bool duplicateProperty = true;
+
+        if (existingProperty.Ignored)
+        {
+          // remove ignored property so it can be replaced in collection
+          Remove(existingProperty);
+          duplicateProperty = false;
+        }
+
+        if (property.DeclaringType != null && existingProperty.DeclaringType != null)
+        {
+          if (property.DeclaringType.IsSubclassOf(existingProperty.DeclaringType))
+          {
+            // current property is on a derived class and hides the existing
+            Remove(existingProperty);
+            duplicateProperty = false;
+          }
+          if (existingProperty.DeclaringType.IsSubclassOf(property.DeclaringType))
+          {
+            // current property is hidden by the existing so don't add it
+            return;
+          }
+        }
+
+        if (duplicateProperty)
+          throw new JsonSerializationException("A member with the name '{0}' already exists on '{1}'. Use the JsonPropertyAttribute to specify another name.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName, _type));
+      }
+
+      Add(property);
+    }
+
+    /// <summary>
+    /// Gets the closest matching <see cref="JsonProperty"/> object.
+    /// First attempts to get an exact case match of propertyName and then
+    /// a case insensitive match.
+    /// </summary>
+    /// <param name="propertyName">Name of the property.</param>
+    /// <returns>A matching property if found.</returns>
+    public JsonProperty GetClosestMatchProperty(string propertyName)
+    {
+      JsonProperty property = GetProperty(propertyName, StringComparison.Ordinal);
+      if (property == null)
+        property = GetProperty(propertyName, StringComparison.OrdinalIgnoreCase);
+
+      return property;
+    }
+
+    private bool TryGetValue(string key, out JsonProperty item)
+    {
+      if (Dictionary == null)
+      {
+        item = default(JsonProperty);
+        return false;
+      }
+
+      return Dictionary.TryGetValue(key, out item);
+    }
+
+
+    /// <summary>
+    /// Gets a property by property name.
+    /// </summary>
+    /// <param name="propertyName">The name of the property to get.</param>
+    /// <param name="comparisonType">Type property name string comparison.</param>
+    /// <returns>A matching property if found.</returns>
+    public JsonProperty GetProperty(string propertyName, StringComparison comparisonType)
+    {
+      // KeyedCollection has an ordinal comparer
+      if (comparisonType == StringComparison.Ordinal)
+      {
+        JsonProperty property;
+        if (TryGetValue(propertyName, out property))
+          return property;
+
+        return null;
+      }
+
+      foreach (JsonProperty property in this)
+      {
+        if (string.Equals(propertyName, property.PropertyName, comparisonType))
+        {
+          return property;
+        }
+      }
+
+      return null;
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalBase.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalBase.cs
index 2a61f53..145ac85 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalBase.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalBase.cs
@@ -1,75 +1,113 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Net;
-using Newtonsoft.Json.Utilities;
-
-namespace Newtonsoft.Json.Serialization
-{
-  internal abstract class JsonSerializerInternalBase
-  {
-    private ErrorContext _currentErrorContext;
-
-    internal JsonSerializer Serializer { get; private set; }
-
-    protected JsonSerializerInternalBase(JsonSerializer serializer)
-    {
-      ValidationUtils.ArgumentNotNull(serializer, "serializer");
-
-      Serializer = serializer;
-    }
-
-    protected ErrorContext GetErrorContext(object currentObject, object member, Exception error)
-    {
-      if (_currentErrorContext == null)
-        _currentErrorContext = new ErrorContext(currentObject, member, error);
-
-      if (_currentErrorContext.Error != error)
-        throw new InvalidOperationException("Current error context error is different to requested error.");
-
-      return _currentErrorContext;
-    }
-
-    protected void ClearErrorContext()
-    {
-      if (_currentErrorContext == null)
-        throw new InvalidOperationException("Could not clear error context. Error context is already null.");
-
-      _currentErrorContext = null;
-    }
-
-    protected bool IsErrorHandled(object currentObject, JsonContract contract, object keyValue, Exception ex)
-    {
-      ErrorContext errorContext = GetErrorContext(currentObject, keyValue, ex);
-      contract.InvokeOnError(currentObject, Serializer.Context, errorContext);
-
-      if (!errorContext.Handled)
-        Serializer.OnError(new ErrorEventArgs(currentObject, errorContext));
-
-      return errorContext.Handled;
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Runtime.CompilerServices;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Serialization
+{
+  internal abstract class JsonSerializerInternalBase
+  {
+    private class ReferenceEqualsEqualityComparer : IEqualityComparer<object>
+    {
+      bool IEqualityComparer<object>.Equals(object x, object y)
+      {
+        return ReferenceEquals(x, y);
+      }
+
+      int IEqualityComparer<object>.GetHashCode(object obj)
+      {
+#if !(NETFX_CORE || PORTABLE)
+        // put objects in a bucket based on their reference
+        return RuntimeHelpers.GetHashCode(obj);
+#else
+        // put all objects in the same bucket so ReferenceEquals is called on all
+        return -1;
+#endif
+      }
+    }
+
+    private ErrorContext _currentErrorContext;
+    private BidirectionalDictionary<string, object> _mappings;
+
+    internal readonly JsonSerializer Serializer;
+
+    protected JsonSerializerInternalBase(JsonSerializer serializer)
+    {
+      ValidationUtils.ArgumentNotNull(serializer, "serializer");
+
+      Serializer = serializer;
+    }
+
+    internal BidirectionalDictionary<string, object> DefaultReferenceMappings
+    {
+      get
+      {
+        // override equality comparer for object key dictionary
+        // object will be modified as it deserializes and might have mutable hashcode
+        if (_mappings == null)
+          _mappings = new BidirectionalDictionary<string, object>(
+            EqualityComparer<string>.Default,
+            new ReferenceEqualsEqualityComparer());
+
+        return _mappings;
+      }
+    }
+
+    protected ErrorContext GetErrorContext(object currentObject, object member, string path, Exception error)
+    {
+      if (_currentErrorContext == null)
+        _currentErrorContext = new ErrorContext(currentObject, member, path, error);
+
+      if (_currentErrorContext.Error != error)
+        throw new InvalidOperationException("Current error context error is different to requested error.");
+
+      return _currentErrorContext;
+    }
+
+    protected void ClearErrorContext()
+    {
+      if (_currentErrorContext == null)
+        throw new InvalidOperationException("Could not clear error context. Error context is already null.");
+
+      _currentErrorContext = null;
+    }
+
+    protected bool IsErrorHandled(object currentObject, JsonContract contract, object keyValue, string path, Exception ex)
+    {
+      ErrorContext errorContext = GetErrorContext(currentObject, keyValue, path, ex);
+      if (contract != null)
+        contract.InvokeOnError(currentObject, Serializer.Context, errorContext);
+
+      if (!errorContext.Handled)
+        Serializer.OnError(new ErrorEventArgs(currentObject, errorContext));
+
+      return errorContext.Handled;
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs
index c140241..819cd6f 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs
@@ -1,936 +1,1628 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Globalization;
-using System.Linq;
-using System.Reflection;
-using System.Runtime.Serialization;
-using Newtonsoft.Json.Linq;
-using Newtonsoft.Json.Utilities;
-
-namespace Newtonsoft.Json.Serialization
-{
-  internal class JsonSerializerInternalReader : JsonSerializerInternalBase
-  {
-    private JsonSerializerProxy _internalSerializer;
-#if !SILVERLIGHT && !PocketPC
-   private JsonFormatterConverter _formatterConverter;
-#endif
-
-    public JsonSerializerInternalReader(JsonSerializer serializer) : base(serializer)
-    {
-    }
-
-    public void Populate(JsonReader reader, object target)
-    {
-      ValidationUtils.ArgumentNotNull(target, "target");
-
-      Type objectType = target.GetType();
-
-      JsonContract contract = Serializer.ContractResolver.ResolveContract(objectType);
-
-      if (reader.TokenType == JsonToken.None)
-        reader.Read();
-
-      if (reader.TokenType == JsonToken.StartArray)
-      {
-        if (contract is JsonArrayContract)
-          PopulateList(CollectionUtils.CreateCollectionWrapper(target), reader, null, (JsonArrayContract)contract);
-        else
-          throw new JsonSerializationException("Cannot populate JSON array onto type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType));
-      }
-      else if (reader.TokenType == JsonToken.StartObject)
-      {
-        CheckedRead(reader);
-
-        string id = null;
-        if (reader.TokenType == JsonToken.PropertyName && string.Equals(reader.Value.ToString(), JsonTypeReflector.IdPropertyName, StringComparison.Ordinal))
-        {
-          CheckedRead(reader);
-          id = reader.Value.ToString();
-          CheckedRead(reader);
-        }
-
-        if (contract is JsonDictionaryContract)
-          PopulateDictionary(CollectionUtils.CreateDictionaryWrapper(target), reader, (JsonDictionaryContract) contract, id);
-        else if (contract is JsonObjectContract)
-          PopulateObject(target, reader, (JsonObjectContract) contract, id);
-        else
-          throw new JsonSerializationException("Cannot populate JSON object onto type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType));
-      }
-      else
-      {
-        throw new JsonSerializationException("Unexpected initial token '{0}' when populating object. Expected JSON object or array.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
-      }
-    }
-
-    private JsonContract GetContractSafe(Type type)
-    {
-      if (type == null)
-        return null;
-
-      return Serializer.ContractResolver.ResolveContract(type);
-    }
-
-    private JsonContract GetContractSafe(Type type, object value)
-    {
-      if (value == null)
-        return GetContractSafe(type);
-
-      return Serializer.ContractResolver.ResolveContract(value.GetType());
-    }
-
-    public object Deserialize(JsonReader reader, Type objectType)
-    {
-      if (reader == null)
-        throw new ArgumentNullException("reader");
-
-      if (reader.TokenType == JsonToken.None && !reader.Read())
-        return null;
-
-      return CreateValueNonProperty(reader, objectType, GetContractSafe(objectType));
-    }
-
-    private JsonSerializerProxy GetInternalSerializer()
-    {
-      if (_internalSerializer == null)
-        _internalSerializer = new JsonSerializerProxy(this);
-
-      return _internalSerializer;
-    }
-
-#if !SILVERLIGHT && !PocketPC
-    private JsonFormatterConverter GetFormatterConverter()
-    {
-      if (_formatterConverter == null)
-        _formatterConverter = new JsonFormatterConverter(GetInternalSerializer());
-
-      return _formatterConverter;
-    }
-#endif
-
-    private JToken CreateJToken(JsonReader reader, JsonContract contract)
-    {
-      ValidationUtils.ArgumentNotNull(reader, "reader");
-
-      if (contract != null && contract.UnderlyingType == typeof(JRaw))
-      {
-        return JRaw.Create(reader);
-      }
-      else
-      {
-        JToken token;
-        using (JTokenWriter writer = new JTokenWriter())
-        {
-          writer.WriteToken(reader);
-          token = writer.Token;
-        }
-
-        return token;
-      }
-    }
-
-    private JToken CreateJObject(JsonReader reader)
-    {
-      ValidationUtils.ArgumentNotNull(reader, "reader");
-
-      // this is needed because we've already read inside the object, looking for special properties
-      JToken token;
-      using (JTokenWriter writer = new JTokenWriter())
-      {
-        writer.WriteStartObject();
-
-        if (reader.TokenType == JsonToken.PropertyName)
-          writer.WriteToken(reader, reader.Depth - 1);
-        else
-          writer.WriteEndObject();
-
-        token = writer.Token;
-      }
-
-      return token;
-    }
-
-    private object CreateValueProperty(JsonReader reader, JsonProperty property, object target, bool gottenCurrentValue, object currentValue)
-    {
-      JsonContract contract = GetContractSafe(property.PropertyType, currentValue);
-      Type objectType = property.PropertyType;
-
-      JsonConverter converter = GetConverter(contract, property.MemberConverter);
-
-      if (converter != null && converter.CanRead)
-      {
-        if (!gottenCurrentValue && target != null && property.Readable)
-          currentValue = property.ValueProvider.GetValue(target);
-
-        return converter.ReadJson(reader, objectType, currentValue, GetInternalSerializer());
-      }
-
-      return CreateValueInternal(reader, objectType, contract, property, currentValue);
-    }
-
-    private object CreateValueNonProperty(JsonReader reader, Type objectType, JsonContract contract)
-    {
-      JsonConverter converter = GetConverter(contract, null);
-
-      if (converter != null && converter.CanRead)
-        return converter.ReadJson(reader, objectType, null, GetInternalSerializer());
-
-      return CreateValueInternal(reader, objectType, contract, null, null);
-    }
-
-    private object CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, object existingValue)
-    {
-      if (contract is JsonLinqContract)
-        return CreateJToken(reader, contract);
-
-      do
-      {
-        switch (reader.TokenType)
-        {
-          // populate a typed object or generic dictionary/array
-          // depending upon whether an objectType was supplied
-          case JsonToken.StartObject:
-            return CreateObject(reader, objectType, contract, member, existingValue);
-          case JsonToken.StartArray:
-            return CreateList(reader, objectType, contract, member, existingValue, null);
-          case JsonToken.Integer:
-          case JsonToken.Float:
-          case JsonToken.Boolean:
-          case JsonToken.Date:
-          case JsonToken.Bytes:
-            return EnsureType(reader.Value, objectType);
-          case JsonToken.String:
-            // convert empty string to null automatically for nullable types
-            if (string.IsNullOrEmpty((string)reader.Value) &&
-              objectType != null &&
-              ReflectionUtils.IsNullableType(objectType))
-              return null;
-
-            // string that needs to be returned as a byte array should be base 64 decoded
-            if (objectType == typeof(byte[]))
-              return Convert.FromBase64String((string)reader.Value);
-
-            return EnsureType(reader.Value, objectType);
-          case JsonToken.StartConstructor:
-          case JsonToken.EndConstructor:
-            string constructorName = reader.Value.ToString();
-
-            return constructorName;
-          case JsonToken.Null:
-          case JsonToken.Undefined:
-            if (objectType == typeof (DBNull))
-              return DBNull.Value;
-
-            return EnsureType(reader.Value, objectType);
-          case JsonToken.Raw:
-            return new JRaw((string)reader.Value);
-          case JsonToken.Comment:
-            // ignore
-            break;
-          default:
-            throw new JsonSerializationException("Unexpected token while deserializing object: " + reader.TokenType);
-        }
-      } while (reader.Read());
-
-      throw new JsonSerializationException("Unexpected end when deserializing object.");
-    }
-
-    private JsonConverter GetConverter(JsonContract contract, JsonConverter memberConverter)
-    {
-      JsonConverter converter = null;
-      if (memberConverter != null)
-      {
-        // member attribute converter
-        converter = memberConverter;
-      }
-      else if (contract != null)
-      {
-        JsonConverter matchingConverter;
-        if (contract.Converter != null)
-          // class attribute converter
-          converter = contract.Converter;
-        else if ((matchingConverter = Serializer.GetMatchingConverter(contract.UnderlyingType)) != null)
-          // passed in converters
-          converter = matchingConverter;
-        else if (contract.InternalConverter != null)
-          // internally specified converter
-          converter = contract.InternalConverter;
-      }
-      return converter;
-    }
-
-    private object CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, object existingValue)
-    {
-      CheckedRead(reader);
-
-      string id = null;
-
-      if (reader.TokenType == JsonToken.PropertyName)
-      {
-        bool specialProperty;
-
-        do
-        {
-          string propertyName = reader.Value.ToString();
-
-          if (string.Equals(propertyName, JsonTypeReflector.RefPropertyName, StringComparison.Ordinal))
-          {
-            CheckedRead(reader);
-            if (reader.TokenType != JsonToken.String)
-              throw new JsonSerializationException("JSON reference {0} property must have a string value.".FormatWith(CultureInfo.InvariantCulture, JsonTypeReflector.RefPropertyName));
-
-            string reference = reader.Value.ToString();
-
-            CheckedRead(reader);
-            if (reader.TokenType == JsonToken.PropertyName)
-              throw new JsonSerializationException("Additional content found in JSON reference object. A JSON reference object should only have a {0} property.".FormatWith(CultureInfo.InvariantCulture, JsonTypeReflector.RefPropertyName));
-
-            return Serializer.ReferenceResolver.ResolveReference(reference);
-          }
-          else if (string.Equals(propertyName, JsonTypeReflector.TypePropertyName, StringComparison.Ordinal))
-          {
-            CheckedRead(reader);
-            string qualifiedTypeName = reader.Value.ToString();
-
-            CheckedRead(reader);
-
-            if ((((member != null) ? member.TypeNameHandling : null) ?? Serializer.TypeNameHandling) != TypeNameHandling.None)
-            {
-              string typeName;
-              string assemblyName;
-              ReflectionUtils.SplitFullyQualifiedTypeName(qualifiedTypeName, out typeName, out assemblyName);
-
-              Type specifiedType;
-              try
-              {
-                specifiedType = Serializer.Binder.BindToType(assemblyName, typeName);
-              }
-              catch (Exception ex)
-              {
-                throw new JsonSerializationException("Error resolving type specified in JSON '{0}'.".FormatWith(CultureInfo.InvariantCulture, qualifiedTypeName), ex);
-              }
-
-              if (specifiedType == null)
-                throw new JsonSerializationException("Type specified in JSON '{0}' was not resolved.".FormatWith(CultureInfo.InvariantCulture, qualifiedTypeName));
-
-              if (objectType != null && !objectType.IsAssignableFrom(specifiedType))
-                throw new JsonSerializationException("Type specified in JSON '{0}' is not compatible with '{1}'.".FormatWith(CultureInfo.InvariantCulture, specifiedType.AssemblyQualifiedName, objectType.AssemblyQualifiedName));
-
-              objectType = specifiedType;
-              contract = GetContractSafe(specifiedType);
-            }
-            specialProperty = true;
-          }
-          else if (string.Equals(propertyName, JsonTypeReflector.IdPropertyName, StringComparison.Ordinal))
-          {
-            CheckedRead(reader);
-
-            id = reader.Value.ToString();
-            CheckedRead(reader);
-            specialProperty = true;
-          }
-          else if (string.Equals(propertyName, JsonTypeReflector.ArrayValuesPropertyName, StringComparison.Ordinal))
-          {
-            CheckedRead(reader);
-            object list = CreateList(reader, objectType, contract, member, existingValue, id);
-            CheckedRead(reader);
-            return list;
-          }
-          else
-          {
-            specialProperty = false;
-          }
-        } while (specialProperty
-                 && reader.TokenType == JsonToken.PropertyName);
-      }
-
-      if (!HasDefinedType(objectType))
-        return CreateJObject(reader);
-
-      if (contract == null)
-        throw new JsonSerializationException("Could not resolve type '{0}' to a JsonContract.".FormatWith(CultureInfo.InvariantCulture, objectType));
-
-      JsonDictionaryContract dictionaryContract = contract as JsonDictionaryContract;
-      if (dictionaryContract != null)
-      {
-        if (existingValue == null)
-          return CreateAndPopulateDictionary(reader, dictionaryContract, id);
-
-        return PopulateDictionary(dictionaryContract.CreateWrapper(existingValue), reader, dictionaryContract, id);
-      }
-
-      JsonObjectContract objectContract = contract as JsonObjectContract;
-      if (objectContract != null)
-      {
-        if (existingValue == null)
-          return CreateAndPopulateObject(reader, objectContract, id);
-
-        return PopulateObject(existingValue, reader, objectContract, id);
-      }
-
-#if !SILVERLIGHT && !PocketPC
-      JsonISerializableContract serializableContract = contract as JsonISerializableContract;
-      if (serializableContract != null)
-      {
-        return CreateISerializable(reader, serializableContract, id);
-      }
-#endif
-      
-      throw new JsonSerializationException("Cannot deserialize JSON object into type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType));
-    }
-
-    private JsonArrayContract EnsureArrayContract(Type objectType, JsonContract contract)
-    {
-      if (contract == null)
-        throw new JsonSerializationException("Could not resolve type '{0}' to a JsonContract.".FormatWith(CultureInfo.InvariantCulture, objectType));
-
-      JsonArrayContract arrayContract = contract as JsonArrayContract;
-      if (arrayContract == null)
-        throw new JsonSerializationException("Cannot deserialize JSON array into type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType));
-
-      return arrayContract;
-    }
-
-    private void CheckedRead(JsonReader reader)
-    {
-      if (!reader.Read())
-        throw new JsonSerializationException("Unexpected end when deserializing object.");
-    }
-
-    private object CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, object existingValue, string reference)
-    {
-      object value;
-      if (HasDefinedType(objectType))
-      {
-        JsonArrayContract arrayContract = EnsureArrayContract(objectType, contract);
-
-        if (existingValue == null)
-          value = CreateAndPopulateList(reader, reference, arrayContract);
-        else
-          value = PopulateList(arrayContract.CreateWrapper(existingValue), reader, reference, arrayContract);
-      }
-      else
-      {
-        value = CreateJToken(reader, contract);
-      }
-      return value;
-    }
-
-    private bool HasDefinedType(Type type)
-    {
-      return (type != null && type != typeof (object) && !type.IsSubclassOf(typeof(JToken)));
-    }
-
-    private object EnsureType(object value, Type targetType)
-    {
-      if (targetType == null)
-        return value;
-
-      Type valueType = ReflectionUtils.GetObjectType(value);
-
-      // type of value and type of target don't match
-      // attempt to convert value's type to target's type
-      if (valueType != targetType)
-      {
-        try
-        {
-          return ConvertUtils.ConvertOrCast(value, CultureInfo.InvariantCulture, targetType);
-        }
-        catch (Exception ex)
-        {
-          throw new JsonSerializationException("Error converting value {0} to type '{1}'.".FormatWith(CultureInfo.InvariantCulture, FormatValueForPrint(value), targetType), ex);
-        }
-      }
-
-      return value;
-    }
-
-    private string FormatValueForPrint(object value)
-    {
-      if (value == null)
-        return "{null}";
-
-      if (value is string)
-        return @"""" + value + @"""";
-
-      return value.ToString();
-    }
-
-    private void SetPropertyValue(JsonProperty property, JsonReader reader, object target)
-    {
-      if (property.Ignored)
-      {
-        reader.Skip();
-        return;
-      }
-
-      object currentValue = null;
-      bool useExistingValue = false;
-      bool gottenCurrentValue = false;
-
-      ObjectCreationHandling objectCreationHandling =
-        property.ObjectCreationHandling.GetValueOrDefault(Serializer.ObjectCreationHandling);
-
-      if ((objectCreationHandling == ObjectCreationHandling.Auto || objectCreationHandling == ObjectCreationHandling.Reuse)
-        && (reader.TokenType == JsonToken.StartArray || reader.TokenType == JsonToken.StartObject)
-        && property.Readable)
-      {
-        currentValue = property.ValueProvider.GetValue(target);
-        gottenCurrentValue = true;
-
-        useExistingValue = (currentValue != null && !property.PropertyType.IsArray && !ReflectionUtils.InheritsGenericDefinition(property.PropertyType, typeof(ReadOnlyCollection<>)));
-      }
-
-      if (!property.Writable && !useExistingValue)
-      {
-        reader.Skip();
-        return;
-      }
-
-      // test tokentype here because null might not be convertable to some types, e.g. ignoring null when applied to DateTime
-      if (property.NullValueHandling.GetValueOrDefault(Serializer.NullValueHandling) == NullValueHandling.Ignore && reader.TokenType == JsonToken.Null)
-      {
-        reader.Skip();
-        return;
-      }
-
-      // test tokentype here because default value might not be convertable to actual type, e.g. default of "" for DateTime
-      if (property.DefaultValueHandling.GetValueOrDefault(Serializer.DefaultValueHandling) == DefaultValueHandling.Ignore
-        && JsonReader.IsPrimitiveToken(reader.TokenType)
-        && Equals(reader.Value, property.DefaultValue))
-      {
-        reader.Skip();
-        return;
-      }
-
-      object existingValue = (useExistingValue) ? currentValue : null;
-      object value = CreateValueProperty(reader, property, target, gottenCurrentValue, existingValue);
-
-      // always set the value if useExistingValue is false,
-      // otherwise also set it if CreateValue returns a new value compared to the currentValue
-      // this could happen because of a JsonConverter against the type
-      if ((!useExistingValue || value != currentValue)
-        && ShouldSetPropertyValue(property, value))
-        property.ValueProvider.SetValue(target, value);
-    }
-
-    private bool ShouldSetPropertyValue(JsonProperty property, object value)
-    {
-      if (property.NullValueHandling.GetValueOrDefault(Serializer.NullValueHandling) == NullValueHandling.Ignore && value == null)
-        return false;
-
-      if (property.DefaultValueHandling.GetValueOrDefault(Serializer.DefaultValueHandling) == DefaultValueHandling.Ignore && Equals(value, property.DefaultValue))
-        return false;
-
-      if (!property.Writable)
-        return false;
-
-      return true;
-    }
-
-    private object CreateAndPopulateDictionary(JsonReader reader, JsonDictionaryContract contract, string id)
-    {
-      object dictionary;
-
-      if (contract.DefaultCreator != null &&
-        (!contract.DefaultCreatorNonPublic || Serializer.ConstructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor))
-        dictionary = contract.DefaultCreator();
-      else
-        throw new JsonSerializationException("Unable to find a default constructor to use for type {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
-
-      IWrappedDictionary dictionaryWrapper = contract.CreateWrapper(dictionary);
-
-      PopulateDictionary(dictionaryWrapper, reader, contract, id);
-
-      return dictionaryWrapper.UnderlyingDictionary;
-    }
-
-    private object PopulateDictionary(IWrappedDictionary dictionary, JsonReader reader, JsonDictionaryContract contract, string id)
-    {
-      if (id != null)
-        Serializer.ReferenceResolver.AddReference(id, dictionary.UnderlyingDictionary);
-
-      contract.InvokeOnDeserializing(dictionary.UnderlyingDictionary, Serializer.Context);
-
-      int initialDepth = reader.Depth;
-
-      do
-      {
-        switch (reader.TokenType)
-        {
-          case JsonToken.PropertyName:
-            object keyValue;
-            try
-            {
-              keyValue = EnsureType(reader.Value, contract.DictionaryKeyType);
-            }
-            catch (Exception ex)
-            {
-              throw new JsonSerializationException("Could not convert string '{0}' to dictionary key type '{1}'. Create a TypeConverter to convert from the string to the key type object.".FormatWith(CultureInfo.InvariantCulture, reader.Value, contract.DictionaryKeyType), ex);
-            }
-
-            CheckedRead(reader);
-
-            try
-            {
-              dictionary[keyValue] = CreateValueNonProperty(reader, contract.DictionaryValueType, GetContractSafe(contract.DictionaryValueType));
-            }
-            catch (Exception ex)
-            {
-              if (IsErrorHandled(dictionary, contract, keyValue, ex))
-                HandleError(reader, initialDepth);
-              else
-                throw;
-            }
-            break;
-          case JsonToken.EndObject:
-            contract.InvokeOnDeserialized(dictionary.UnderlyingDictionary, Serializer.Context);
-            
-            return dictionary.UnderlyingDictionary;
-          default:
-            throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType);
-        }
-      } while (reader.Read());
-
-      throw new JsonSerializationException("Unexpected end when deserializing object.");
-    }
-
-    private object CreateAndPopulateList(JsonReader reader, string reference, JsonArrayContract contract)
-    {
-      return CollectionUtils.CreateAndPopulateList(contract.CreatedType, (l, isTemporaryListReference) =>
-        {
-          if (reference != null && isTemporaryListReference)
-            throw new JsonSerializationException("Cannot preserve reference to array or readonly list: {0}".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
-
-#if !PocketPC
-          if (contract.OnSerializing != null && isTemporaryListReference)
-            throw new JsonSerializationException("Cannot call OnSerializing on an array or readonly list: {0}".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
-#endif
-          if (contract.OnError != null && isTemporaryListReference)
-            throw new JsonSerializationException("Cannot call OnError on an array or readonly list: {0}".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
-
-          PopulateList(contract.CreateWrapper(l), reader, reference, contract);
-        });
-    }
-
-    private object PopulateList(IWrappedCollection wrappedList, JsonReader reader, string reference, JsonArrayContract contract)
-    {
-      object list = wrappedList.UnderlyingCollection;
-
-      if (reference != null)
-        Serializer.ReferenceResolver.AddReference(reference, list);
-
-      contract.InvokeOnDeserializing(list, Serializer.Context);
-
-      int initialDepth = reader.Depth;
-
-      while (reader.Read())
-      {
-        switch (reader.TokenType)
-        {
-          case JsonToken.EndArray:
-            contract.InvokeOnDeserialized(list, Serializer.Context);
-
-            return wrappedList.UnderlyingCollection;
-          case JsonToken.Comment:
-            break;
-          default:
-            try
-            {
-              object value = CreateValueNonProperty(reader, contract.CollectionItemType, GetContractSafe(contract.CollectionItemType));
-
-              wrappedList.Add(value);
-            }
-            catch (Exception ex)
-            {
-              if (IsErrorHandled(list, contract, wrappedList.Count, ex))
-                HandleError(reader, initialDepth);
-              else
-                throw;
-            }
-            break;
-        }
-      }
-
-      throw new JsonSerializationException("Unexpected end when deserializing array.");
-    }
-
-#if !SILVERLIGHT && !PocketPC
-    private object CreateISerializable(JsonReader reader, JsonISerializableContract contract, string id)
-    {
-      Type objectType = contract.UnderlyingType;
-
-      SerializationInfo serializationInfo = new SerializationInfo(contract.UnderlyingType, GetFormatterConverter());
-
-      bool exit = false;
-      do
-      {
-        switch (reader.TokenType)
-        {
-          case JsonToken.PropertyName:
-            string memberName = reader.Value.ToString();
-            if (!reader.Read())
-              throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));
-
-            serializationInfo.AddValue(memberName, JToken.ReadFrom(reader));
-            break;
-          case JsonToken.EndObject:
-            exit = true;
-            break;
-          default:
-            throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType);
-        }
-      } while (!exit && reader.Read());
-
-      if (contract.ISerializableCreator == null)
-        throw new JsonSerializationException("ISerializable type '{0}' does not have a valid constructor.".FormatWith(CultureInfo.InvariantCulture, objectType));
-
-      object createdObject = contract.ISerializableCreator(serializationInfo, Serializer.Context);
-
-      if (id != null)
-        Serializer.ReferenceResolver.AddReference(id, createdObject);
-
-      contract.InvokeOnDeserializing(createdObject, Serializer.Context);
-      contract.InvokeOnDeserialized(createdObject, Serializer.Context);
-
-      return createdObject;
-    }
-#endif
-
-    private object CreateAndPopulateObject(JsonReader reader, JsonObjectContract contract, string id)
-    {
-      object newObject = null;
-
-      if (contract.UnderlyingType.IsInterface || contract.UnderlyingType.IsAbstract)
-        throw new JsonSerializationException("Could not create an instance of type {0}. Type is an interface or abstract class and cannot be instantated.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
-
-      if (contract.DefaultCreator != null &&
-        (!contract.DefaultCreatorNonPublic || Serializer.ConstructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor))
-      {
-        newObject = contract.DefaultCreator();
-      }
-
-      if (newObject != null)
-      {
-        PopulateObject(newObject, reader, contract, id);
-        return newObject;
-      }
-
-      return CreateObjectFromNonDefaultConstructor(reader, contract, id);
-    }
-
-    private object CreateObjectFromNonDefaultConstructor(JsonReader reader, JsonObjectContract contract, string id)
-    {
-      Type objectType = contract.UnderlyingType;
-
-      if (contract.ParametrizedConstructor == null)
-        throw new JsonSerializationException("Unable to find a constructor to use for type {0}. A class should either have a default constructor or only one constructor with arguments.".FormatWith(CultureInfo.InvariantCulture, objectType));
-
-      // create a dictionary to put retrieved values into
-      IDictionary<JsonProperty, object> propertyValues = contract.Properties.Where(p => !p.Ignored).ToDictionary(kv => kv, kv => (object)null);
-
-      bool exit = false;
-      do
-      {
-        switch (reader.TokenType)
-        {
-          case JsonToken.PropertyName:
-            string memberName = reader.Value.ToString();
-            if (!reader.Read())
-              throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));
-
-            // attempt exact case match first
-            // then try match ignoring case
-            JsonProperty property = contract.Properties.GetClosestMatchProperty(memberName);
-
-            if (property != null)
-            {
-              if (!property.Ignored)
-                propertyValues[property] = CreateValueProperty(reader, property, null, true, null);
-              else
-                reader.Skip();
-            }
-            else
-            {
-              if (Serializer.MissingMemberHandling == MissingMemberHandling.Error)
-                throw new JsonSerializationException("Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, objectType.Name));
-
-              reader.Skip();
-            }
-            break;
-          case JsonToken.EndObject:
-            exit = true;
-            break;
-          default:
-            throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType);
-        }
-      } while (!exit && reader.Read());
-
-      IDictionary<ParameterInfo, object> constructorParameters = contract.ParametrizedConstructor.GetParameters().ToDictionary(p => p, p => (object)null);
-      IDictionary<JsonProperty, object> remainingPropertyValues = new Dictionary<JsonProperty, object>();
-
-      foreach (KeyValuePair<JsonProperty, object> propertyValue in propertyValues)
-      {
-        ParameterInfo matchingConstructorParameter = constructorParameters.ForgivingCaseSensitiveFind(kv => kv.Key.Name, propertyValue.Key.PropertyName).Key;
-        if (matchingConstructorParameter != null)
-          constructorParameters[matchingConstructorParameter] = propertyValue.Value;
-        else
-          remainingPropertyValues.Add(propertyValue);
-      }
-
-      object createdObject = contract.ParametrizedConstructor.Invoke(constructorParameters.Values.ToArray());
-
-      if (id != null)
-        Serializer.ReferenceResolver.AddReference(id, createdObject);
-
-      contract.InvokeOnDeserializing(createdObject, Serializer.Context);
-
-      // go through unused values and set the newly created object's properties
-      foreach (KeyValuePair<JsonProperty, object> remainingPropertyValue in remainingPropertyValues)
-      {
-        JsonProperty property = remainingPropertyValue.Key;
-        object value = remainingPropertyValue.Value;
-
-        if (ShouldSetPropertyValue(remainingPropertyValue.Key, remainingPropertyValue.Value))
-          property.ValueProvider.SetValue(createdObject, value);
-      }
-
-      contract.InvokeOnDeserialized(createdObject, Serializer.Context);
-      return createdObject;
-    }
-
-    private object PopulateObject(object newObject, JsonReader reader, JsonObjectContract contract, string id)
-    {
-      contract.InvokeOnDeserializing(newObject, Serializer.Context);
-
-      Dictionary<JsonProperty, RequiredValue> requiredProperties =
-        contract.Properties.Where(m => m.Required != Required.Default).ToDictionary(m => m, m => RequiredValue.None);
-
-      if (id != null)
-        Serializer.ReferenceResolver.AddReference(id, newObject);
-
-      int initialDepth = reader.Depth;
-
-      do
-      {
-        switch (reader.TokenType)
-        {
-          case JsonToken.PropertyName:
-            string memberName = reader.Value.ToString();
-
-            // attempt exact case match first
-            // then try match ignoring case
-            JsonProperty property = contract.Properties.GetClosestMatchProperty(memberName);
-
-            if (property == null)
-            {
-              if (Serializer.MissingMemberHandling == MissingMemberHandling.Error)
-                throw new JsonSerializationException("Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, contract.UnderlyingType.Name));
-
-              reader.Skip();
-              continue;
-            }
-
-            if (property.PropertyType == typeof(byte[]))
-            {
-              reader.ReadAsBytes();
-            }
-            else
-            {
-              if (!reader.Read())
-                throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));
-            }
-
-            SetRequiredProperty(reader, property, requiredProperties);
-
-            try
-            {
-              SetPropertyValue(property, reader, newObject);
-            }
-            catch (Exception ex)
-            {
-              if (IsErrorHandled(newObject, contract, memberName, ex))
-                HandleError(reader, initialDepth);
-              else
-                throw;
-            }
-            break;
-          case JsonToken.EndObject:
-            foreach (KeyValuePair<JsonProperty, RequiredValue> requiredProperty in requiredProperties)
-            {
-              if (requiredProperty.Value == RequiredValue.None)
-                throw new JsonSerializationException("Required property '{0}' not found in JSON.".FormatWith(CultureInfo.InvariantCulture, requiredProperty.Key.PropertyName));
-              if (requiredProperty.Key.Required == Required.Always && requiredProperty.Value == RequiredValue.Null)
-                throw new JsonSerializationException("Required property '{0}' expects a value but got null.".FormatWith(CultureInfo.InvariantCulture, requiredProperty.Key.PropertyName));
-            }
-
-            contract.InvokeOnDeserialized(newObject, Serializer.Context);
-            return newObject;
-          case JsonToken.Comment:
-            // ignore
-            break;
-          default:
-            throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType);
-        }
-      } while (reader.Read());
-
-      throw new JsonSerializationException("Unexpected end when deserializing object.");
-    }
-
-    private void SetRequiredProperty(JsonReader reader, JsonProperty property, Dictionary<JsonProperty, RequiredValue> requiredProperties)
-    {
-      if (property != null)
-      {
-        requiredProperties[property] = (reader.TokenType == JsonToken.Null || reader.TokenType == JsonToken.Undefined)
-          ? RequiredValue.Null
-          : RequiredValue.Value;
-      }
-    }
-
-    private void HandleError(JsonReader reader, int initialDepth)
-    {
-      ClearErrorContext();
-
-      reader.Skip();
-
-      while (reader.Depth > (initialDepth + 1))
-      {
-        reader.Read();
-      }
-    }
-
-    internal enum RequiredValue
-    {
-      None,
-      Null,
-      Value
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
+using System.ComponentModel;
+using System.Dynamic;
+#endif
+using System.Globalization;
+using System.Reflection;
+using System.Runtime.Serialization;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Utilities;
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#else
+using System.Linq;
+#endif
+
+namespace Newtonsoft.Json.Serialization
+{
+  internal class JsonSerializerInternalReader : JsonSerializerInternalBase
+  {
+    private JsonSerializerProxy _internalSerializer;
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+    private JsonFormatterConverter _formatterConverter;
+#endif
+
+    public JsonSerializerInternalReader(JsonSerializer serializer)
+      : base(serializer)
+    {
+    }
+
+    public void Populate(JsonReader reader, object target)
+    {
+      ValidationUtils.ArgumentNotNull(target, "target");
+
+      Type objectType = target.GetType();
+
+      JsonContract contract = Serializer.ContractResolver.ResolveContract(objectType);
+
+      if (reader.TokenType == JsonToken.None)
+        reader.Read();
+
+      if (reader.TokenType == JsonToken.StartArray)
+      {
+        if (contract.ContractType == JsonContractType.Array)
+          PopulateList(CollectionUtils.CreateCollectionWrapper(target), reader, (JsonArrayContract) contract, null, null);
+        else
+          throw JsonSerializationException.Create(reader, "Cannot populate JSON array onto type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType));
+      }
+      else if (reader.TokenType == JsonToken.StartObject)
+      {
+        CheckedRead(reader);
+
+        string id = null;
+        if (reader.TokenType == JsonToken.PropertyName && string.Equals(reader.Value.ToString(), JsonTypeReflector.IdPropertyName, StringComparison.Ordinal))
+        {
+          CheckedRead(reader);
+          id = (reader.Value != null) ? reader.Value.ToString() : null;
+          CheckedRead(reader);
+        }
+
+        if (contract.ContractType == JsonContractType.Dictionary)
+          PopulateDictionary(CollectionUtils.CreateDictionaryWrapper(target), reader, (JsonDictionaryContract) contract, null, id);
+        else if (contract.ContractType == JsonContractType.Object)
+          PopulateObject(target, reader, (JsonObjectContract) contract, null, id);
+        else
+          throw JsonSerializationException.Create(reader, "Cannot populate JSON object onto type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType));
+      }
+      else
+      {
+        throw JsonSerializationException.Create(reader, "Unexpected initial token '{0}' when populating object. Expected JSON object or array.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
+      }
+    }
+
+    private JsonContract GetContractSafe(Type type)
+    {
+      if (type == null)
+        return null;
+
+      return Serializer.ContractResolver.ResolveContract(type);
+    }
+
+    public object Deserialize(JsonReader reader, Type objectType, bool checkAdditionalContent)
+    {
+      if (reader == null)
+        throw new ArgumentNullException("reader");
+
+      JsonContract contract = GetContractSafe(objectType);
+
+      try
+      {
+        JsonConverter converter = GetConverter(contract, null, null, null);
+
+        if (reader.TokenType == JsonToken.None && !ReadForType(reader, contract, converter != null))
+        {
+          if (contract != null && !contract.IsNullable)
+            throw JsonSerializationException.Create(reader, "No JSON content found and type '{0}' is not nullable.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
+
+          return null;
+        }
+
+        object deserializedValue;
+
+        if (converter != null && converter.CanRead)
+          deserializedValue = converter.ReadJson(reader, objectType, null, GetInternalSerializer());
+        else
+          deserializedValue = CreateValueInternal(reader, objectType, contract, null, null, null, null);
+
+        if (checkAdditionalContent)
+        {
+          if (reader.Read() && reader.TokenType != JsonToken.Comment)
+            throw new JsonSerializationException("Additional text found in JSON string after finishing deserializing object.");
+        }
+
+        return deserializedValue;
+      }
+      catch (Exception ex)
+      {
+        if (IsErrorHandled(null, contract, null, reader.Path, ex))
+        {
+          HandleError(reader, false, 0);
+          return null;
+        }
+        else
+        {
+          throw;
+        }
+      }
+    }
+
+    private JsonSerializerProxy GetInternalSerializer()
+    {
+      if (_internalSerializer == null)
+        _internalSerializer = new JsonSerializerProxy(this);
+
+      return _internalSerializer;
+    }
+
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+    private JsonFormatterConverter GetFormatterConverter()
+    {
+      if (_formatterConverter == null)
+        _formatterConverter = new JsonFormatterConverter(GetInternalSerializer());
+
+      return _formatterConverter;
+    }
+#endif
+
+    private JToken CreateJToken(JsonReader reader, JsonContract contract)
+    {
+      ValidationUtils.ArgumentNotNull(reader, "reader");
+
+      if (contract != null && contract.UnderlyingType == typeof (JRaw))
+      {
+        return JRaw.Create(reader);
+      }
+      else
+      {
+        JToken token;
+        using (JTokenWriter writer = new JTokenWriter())
+        {
+          writer.WriteToken(reader);
+          token = writer.Token;
+        }
+
+        return token;
+      }
+    }
+
+    private JToken CreateJObject(JsonReader reader)
+    {
+      ValidationUtils.ArgumentNotNull(reader, "reader");
+
+      // this is needed because we've already read inside the object, looking for special properties
+      JToken token;
+      using (JTokenWriter writer = new JTokenWriter())
+      {
+        writer.WriteStartObject();
+
+        if (reader.TokenType == JsonToken.PropertyName)
+          writer.WriteToken(reader, reader.Depth - 1);
+        else
+          writer.WriteEndObject();
+
+        token = writer.Token;
+      }
+
+      return token;
+    }
+
+    private object CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, object existingValue)
+    {
+      if (contract != null && contract.ContractType == JsonContractType.Linq)
+        return CreateJToken(reader, contract);
+
+      do
+      {
+        switch (reader.TokenType)
+        {
+            // populate a typed object or generic dictionary/array
+            // depending upon whether an objectType was supplied
+          case JsonToken.StartObject:
+            return CreateObject(reader, objectType, contract, member, containerContract, containerMember, existingValue);
+          case JsonToken.StartArray:
+            return CreateList(reader, objectType, contract, member, existingValue, null);
+          case JsonToken.Integer:
+          case JsonToken.Float:
+          case JsonToken.Boolean:
+          case JsonToken.Date:
+          case JsonToken.Bytes:
+            return EnsureType(reader, reader.Value, CultureInfo.InvariantCulture, contract, objectType);
+          case JsonToken.String:
+            // convert empty string to null automatically for nullable types
+            if (string.IsNullOrEmpty((string)reader.Value) && objectType != typeof(string) && objectType != typeof(object) && contract != null && contract.IsNullable)
+              return null;
+
+            // string that needs to be returned as a byte array should be base 64 decoded
+            if (objectType == typeof (byte[]))
+              return Convert.FromBase64String((string) reader.Value);
+
+            return EnsureType(reader, reader.Value, CultureInfo.InvariantCulture, contract, objectType);
+          case JsonToken.StartConstructor:
+            string constructorName = reader.Value.ToString();
+
+            return EnsureType(reader, constructorName, CultureInfo.InvariantCulture, contract, objectType);
+          case JsonToken.Null:
+          case JsonToken.Undefined:
+#if !(NETFX_CORE || PORTABLE)
+            if (objectType == typeof (DBNull))
+              return DBNull.Value;
+#endif
+
+            return EnsureType(reader, reader.Value, CultureInfo.InvariantCulture, contract, objectType);
+          case JsonToken.Raw:
+            return new JRaw((string) reader.Value);
+          case JsonToken.Comment:
+            // ignore
+            break;
+          default:
+            throw JsonSerializationException.Create(reader, "Unexpected token while deserializing object: " + reader.TokenType);
+        }
+      } while (reader.Read());
+
+      throw JsonSerializationException.Create(reader, "Unexpected end when deserializing object.");
+    }
+
+    internal string GetExpectedDescription(JsonContract contract)
+    {
+      switch (contract.ContractType)
+      {
+        case JsonContractType.Object:
+        case JsonContractType.Dictionary:
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+        case JsonContractType.Serializable:
+#endif
+#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
+        case JsonContractType.Dynamic:
+#endif
+          return @"JSON object (e.g. {""name"":""value""})";
+        case JsonContractType.Array:
+          return @"JSON array (e.g. [1,2,3])";
+        case JsonContractType.Primitive:
+          return @"JSON primitive value (e.g. string, number, boolean, null)";
+        case JsonContractType.String:
+          return @"JSON string value";
+        default:
+          throw new ArgumentOutOfRangeException();
+      }
+    }
+
+    private JsonConverter GetConverter(JsonContract contract, JsonConverter memberConverter, JsonContainerContract containerContract, JsonProperty containerProperty)
+    {
+      JsonConverter converter = null;
+      if (memberConverter != null)
+      {
+        // member attribute converter
+        converter = memberConverter;
+      }
+      else if (containerProperty != null && containerProperty.ItemConverter != null)
+      {
+        converter = containerProperty.ItemConverter;
+      }
+      else if (containerContract != null && containerContract.ItemConverter != null)
+      {
+        converter = containerContract.ItemConverter;
+      }
+      else if (contract != null)
+      {
+        JsonConverter matchingConverter;
+        if (contract.Converter != null)
+          // class attribute converter
+          converter = contract.Converter;
+        else if ((matchingConverter = Serializer.GetMatchingConverter(contract.UnderlyingType)) != null)
+          // passed in converters
+          converter = matchingConverter;
+        else if (contract.InternalConverter != null)
+          // internally specified converter
+          converter = contract.InternalConverter;
+      }
+      return converter;
+    }
+
+    private object CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, object existingValue)
+    {
+      CheckedRead(reader);
+
+      string id;
+      object newValue;
+      if (ReadSpecialProperties(reader, ref objectType, ref contract, member, containerContract, containerMember, existingValue, out newValue, out id))
+        return newValue;
+
+      if (!HasDefinedType(objectType))
+        return CreateJObject(reader);
+
+      if (contract == null)
+        throw JsonSerializationException.Create(reader, "Could not resolve type '{0}' to a JsonContract.".FormatWith(CultureInfo.InvariantCulture, objectType));
+
+      switch (contract.ContractType)
+      {
+        case JsonContractType.Object:
+          bool createdFromNonDefaultConstructor = false;
+          JsonObjectContract objectContract = (JsonObjectContract) contract;
+          object targetObject;
+          if (existingValue != null)
+            targetObject = existingValue;
+          else
+            targetObject = CreateNewObject(reader, objectContract, member, containerMember, id, out createdFromNonDefaultConstructor);
+
+          // don't populate if read from non-default constructor because the object has already been read
+          if (createdFromNonDefaultConstructor)
+            return targetObject;
+
+          return PopulateObject(targetObject, reader, objectContract, member, id);
+        case JsonContractType.Primitive:
+          JsonPrimitiveContract primitiveContract = (JsonPrimitiveContract) contract;
+          // if the content is inside $value then read past it
+          if (reader.TokenType == JsonToken.PropertyName && string.Equals(reader.Value.ToString(), JsonTypeReflector.ValuePropertyName, StringComparison.Ordinal))
+          {
+            CheckedRead(reader);
+            object value = CreateValueInternal(reader, objectType, primitiveContract, member, null, null, existingValue);
+
+            CheckedRead(reader);
+            return value;
+          }
+          break;
+        case JsonContractType.Dictionary:
+          JsonDictionaryContract dictionaryContract = (JsonDictionaryContract) contract;
+          object targetDictionary;
+          if (existingValue != null)
+            targetDictionary = existingValue;
+          else
+            targetDictionary = CreateNewDictionary(reader, dictionaryContract);
+
+          return PopulateDictionary(dictionaryContract.CreateWrapper(targetDictionary), reader, dictionaryContract, member, id);
+#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
+        case JsonContractType.Dynamic:
+          JsonDynamicContract dynamicContract = (JsonDynamicContract) contract;
+          return CreateDynamic(reader, dynamicContract, member, id);
+#endif
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+        case JsonContractType.Serializable:
+          JsonISerializableContract serializableContract = (JsonISerializableContract) contract;
+          return CreateISerializable(reader, serializableContract, id);
+#endif
+      }
+
+      throw JsonSerializationException.Create(reader, @"Cannot deserialize the current JSON object (e.g. {{""name"":""value""}}) into type '{0}' because the type requires a {1} to deserialize correctly.
+To fix this error either change the JSON to a {1} or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
+".FormatWith(CultureInfo.InvariantCulture, objectType, GetExpectedDescription(contract)));
+    }
+
+    private bool ReadSpecialProperties(JsonReader reader, ref Type objectType, ref JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, object existingValue, out object newValue, out string id)
+    {
+      id = null;
+      newValue = null;
+
+      if (reader.TokenType == JsonToken.PropertyName)
+      {
+        string propertyName = reader.Value.ToString();
+
+        if (propertyName.Length > 0 && propertyName[0] == '$')
+        {
+          // read 'special' properties
+          // $type, $id, $ref, etc
+          bool specialProperty;
+
+          do
+          {
+            propertyName = reader.Value.ToString();
+
+            if (string.Equals(propertyName, JsonTypeReflector.RefPropertyName, StringComparison.Ordinal))
+            {
+              CheckedRead(reader);
+              if (reader.TokenType != JsonToken.String && reader.TokenType != JsonToken.Null)
+                throw JsonSerializationException.Create(reader, "JSON reference {0} property must have a string or null value.".FormatWith(CultureInfo.InvariantCulture, JsonTypeReflector.RefPropertyName));
+
+              string reference = (reader.Value != null) ? reader.Value.ToString() : null;
+
+              CheckedRead(reader);
+
+              if (reference != null)
+              {
+                if (reader.TokenType == JsonToken.PropertyName)
+                  throw JsonSerializationException.Create(reader, "Additional content found in JSON reference object. A JSON reference object should only have a {0} property.".FormatWith(CultureInfo.InvariantCulture, JsonTypeReflector.RefPropertyName));
+
+                {
+                  newValue = Serializer.ReferenceResolver.ResolveReference(this, reference);
+                  return true;
+                }
+              }
+              else
+              {
+                specialProperty = true;
+              }
+            }
+            else if (string.Equals(propertyName, JsonTypeReflector.TypePropertyName, StringComparison.Ordinal))
+            {
+              CheckedRead(reader);
+              string qualifiedTypeName = reader.Value.ToString();
+
+              TypeNameHandling resolvedTypeNameHandling =
+                ((member != null) ? member.TypeNameHandling : null)
+                ?? ((containerContract != null) ? containerContract.ItemTypeNameHandling : null)
+                ?? ((containerMember != null) ? containerMember.ItemTypeNameHandling : null)
+                ?? Serializer.TypeNameHandling;
+
+              if (resolvedTypeNameHandling != TypeNameHandling.None)
+              {
+                string typeName;
+                string assemblyName;
+                ReflectionUtils.SplitFullyQualifiedTypeName(qualifiedTypeName, out typeName, out assemblyName);
+
+                Type specifiedType;
+                try
+                {
+                  specifiedType = Serializer.Binder.BindToType(assemblyName, typeName);
+                }
+                catch (Exception ex)
+                {
+                  throw JsonSerializationException.Create(reader, "Error resolving type specified in JSON '{0}'.".FormatWith(CultureInfo.InvariantCulture, qualifiedTypeName), ex);
+                }
+
+                if (specifiedType == null)
+                  throw JsonSerializationException.Create(reader, "Type specified in JSON '{0}' was not resolved.".FormatWith(CultureInfo.InvariantCulture, qualifiedTypeName));
+
+                if (objectType != null
+#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
+                    && objectType != typeof (IDynamicMetaObjectProvider)
+#endif
+                    && !objectType.IsAssignableFrom(specifiedType))
+                  throw JsonSerializationException.Create(reader, "Type specified in JSON '{0}' is not compatible with '{1}'.".FormatWith(CultureInfo.InvariantCulture, specifiedType.AssemblyQualifiedName, objectType.AssemblyQualifiedName));
+
+                objectType = specifiedType;
+                contract = GetContractSafe(specifiedType);
+              }
+
+              CheckedRead(reader);
+
+              specialProperty = true;
+            }
+            else if (string.Equals(propertyName, JsonTypeReflector.IdPropertyName, StringComparison.Ordinal))
+            {
+              CheckedRead(reader);
+
+              id = (reader.Value != null) ? reader.Value.ToString() : null;
+
+              CheckedRead(reader);
+              specialProperty = true;
+            }
+            else if (string.Equals(propertyName, JsonTypeReflector.ArrayValuesPropertyName, StringComparison.Ordinal))
+            {
+              CheckedRead(reader);
+              object list = CreateList(reader, objectType, contract, member, existingValue, id);
+              CheckedRead(reader);
+              newValue = list;
+              return true;
+            }
+            else
+            {
+              specialProperty = false;
+            }
+          } while (specialProperty
+                   && reader.TokenType == JsonToken.PropertyName);
+        }
+      }
+      return false;
+    }
+
+    private JsonArrayContract EnsureArrayContract(JsonReader reader, Type objectType, JsonContract contract)
+    {
+      if (contract == null)
+        throw JsonSerializationException.Create(reader, "Could not resolve type '{0}' to a JsonContract.".FormatWith(CultureInfo.InvariantCulture, objectType));
+
+      JsonArrayContract arrayContract = contract as JsonArrayContract;
+      if (arrayContract == null)
+        throw JsonSerializationException.Create(reader, @"Cannot deserialize the current JSON array (e.g. [1,2,3]) into type '{0}' because the type requires a {1} to deserialize correctly.
+To fix this error either change the JSON to a {1} or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
+".FormatWith(CultureInfo.InvariantCulture, objectType, GetExpectedDescription(contract)));
+
+      return arrayContract;
+    }
+
+    private void CheckedRead(JsonReader reader)
+    {
+      if (!reader.Read())
+        throw JsonSerializationException.Create(reader, "Unexpected end when deserializing object.");
+    }
+
+    private object CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, object existingValue, string id)
+    {
+      object value;
+      if (HasDefinedType(objectType))
+      {
+        JsonArrayContract arrayContract = EnsureArrayContract(reader, objectType, contract);
+
+        if (existingValue == null)
+        {
+          bool isTemporaryListReference;
+          IList list = CollectionUtils.CreateList(contract.CreatedType, out isTemporaryListReference);
+
+          if (id != null && isTemporaryListReference)
+            throw JsonSerializationException.Create(reader, "Cannot preserve reference to array or readonly list: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
+
+#if !PocketPC
+          if (contract.OnSerializing != null && isTemporaryListReference)
+            throw JsonSerializationException.Create(reader, "Cannot call OnSerializing on an array or readonly list: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
+#endif
+          if (contract.OnError != null && isTemporaryListReference)
+            throw JsonSerializationException.Create(reader, "Cannot call OnError on an array or readonly list: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
+
+          if (!arrayContract.IsMultidimensionalArray)
+            PopulateList(arrayContract.CreateWrapper(list), reader, arrayContract, member, id);
+          else
+            PopulateMultidimensionalArray(list, reader, arrayContract, member, id);
+
+          // create readonly and fixed sized collections using the temporary list
+          if (isTemporaryListReference)
+          {
+            if (arrayContract.IsMultidimensionalArray)
+            {
+              list = CollectionUtils.ToMultidimensionalArray(list, ReflectionUtils.GetCollectionItemType(contract.CreatedType), contract.CreatedType.GetArrayRank());
+            }
+            else if (contract.CreatedType.IsArray)
+            {
+              list = CollectionUtils.ToArray(((List<object>) list).ToArray(), ReflectionUtils.GetCollectionItemType(contract.CreatedType));
+            }
+            else if (ReflectionUtils.InheritsGenericDefinition(contract.CreatedType, typeof(ReadOnlyCollection<>)))
+            {
+              list = (IList) ReflectionUtils.CreateInstance(contract.CreatedType, list);
+            }
+          }
+          else if (list is IWrappedCollection)
+          {
+            return ((IWrappedCollection)list).UnderlyingCollection;
+          }
+
+          value = list;
+        }
+        else
+        {
+          value = PopulateList(arrayContract.CreateWrapper(existingValue), reader, arrayContract, member, id);
+        }
+      }
+      else
+      {
+        value = CreateJToken(reader, contract);
+      }
+      return value;
+    }
+
+    private bool HasDefinedType(Type type)
+    {
+      return (type != null && type != typeof (object) && !typeof (JToken).IsSubclassOf(type)
+#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
+        && type != typeof (IDynamicMetaObjectProvider)
+#endif
+        );
+    }
+
+    private object EnsureType(JsonReader reader, object value, CultureInfo culture, JsonContract contract, Type targetType)
+    {
+      if (targetType == null)
+        return value;
+
+      Type valueType = ReflectionUtils.GetObjectType(value);
+
+      // type of value and type of target don't match
+      // attempt to convert value's type to target's type
+      if (valueType != targetType)
+      {
+        try
+        {
+          if (value == null && contract.IsNullable)
+            return null;
+
+          if (contract.IsConvertable)
+          {
+            if (contract.NonNullableUnderlyingType.IsEnum())
+              {
+                if (value is string)
+                  return Enum.Parse(contract.NonNullableUnderlyingType, value.ToString(), true);
+                else if (ConvertUtils.IsInteger(value))
+                  return Enum.ToObject(contract.NonNullableUnderlyingType, value);
+              }
+
+              return Convert.ChangeType(value, contract.NonNullableUnderlyingType, culture);
+          }
+
+          return ConvertUtils.ConvertOrCast(value, culture, contract.NonNullableUnderlyingType);
+        }
+        catch (Exception ex)
+        {
+          throw JsonSerializationException.Create(reader, "Error converting value {0} to type '{1}'.".FormatWith(CultureInfo.InvariantCulture, FormatValueForPrint(value), targetType), ex);
+        }
+      }
+
+      return value;
+    }
+
+    private string FormatValueForPrint(object value)
+    {
+      if (value == null)
+        return "{null}";
+
+      if (value is string)
+        return @"""" + value + @"""";
+
+      return value.ToString();
+    }
+
+    private void SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, object target)
+    {
+      object currentValue;
+      bool useExistingValue;
+      JsonContract propertyContract;
+      bool gottenCurrentValue;
+
+      if (CalculatePropertyDetails(property, ref propertyConverter, containerContract, containerProperty, reader, target, out useExistingValue, out currentValue, out propertyContract, out gottenCurrentValue))
+        return;
+
+      object value;
+
+      if (propertyConverter != null && propertyConverter.CanRead)
+      {
+        if (!gottenCurrentValue && target != null && property.Readable)
+          currentValue = property.ValueProvider.GetValue(target);
+
+        value = propertyConverter.ReadJson(reader, property.PropertyType, currentValue, GetInternalSerializer());
+      }
+      else
+      {
+        value = CreateValueInternal(reader, property.PropertyType, propertyContract, property, containerContract, containerProperty, (useExistingValue) ? currentValue : null);
+      }
+
+      // always set the value if useExistingValue is false,
+      // otherwise also set it if CreateValue returns a new value compared to the currentValue
+      // this could happen because of a JsonConverter against the type
+      if ((!useExistingValue || value != currentValue)
+        && ShouldSetPropertyValue(property, value))
+      {
+        property.ValueProvider.SetValue(target, value);
+
+        if (property.SetIsSpecified != null)
+          property.SetIsSpecified(target, true);
+      }
+    }
+
+    private bool CalculatePropertyDetails(JsonProperty property, ref JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, object target, out bool useExistingValue, out object currentValue, out JsonContract propertyContract, out bool gottenCurrentValue)
+    {
+      currentValue = null;
+      useExistingValue = false;
+      propertyContract = null;
+      gottenCurrentValue = false;
+
+      if (property.Ignored)
+      {
+        reader.Skip();
+        return true;
+      }
+
+      ObjectCreationHandling objectCreationHandling =
+        property.ObjectCreationHandling.GetValueOrDefault(Serializer.ObjectCreationHandling);
+
+      if ((objectCreationHandling == ObjectCreationHandling.Auto || objectCreationHandling == ObjectCreationHandling.Reuse)
+          && (reader.TokenType == JsonToken.StartArray || reader.TokenType == JsonToken.StartObject)
+          && property.Readable)
+      {
+        currentValue = property.ValueProvider.GetValue(target);
+        gottenCurrentValue = true;
+
+        useExistingValue = (currentValue != null
+                            && !property.PropertyType.IsArray
+                            && !ReflectionUtils.InheritsGenericDefinition(property.PropertyType, typeof (ReadOnlyCollection<>))
+                            && !property.PropertyType.IsValueType());
+      }
+
+      if (!property.Writable && !useExistingValue)
+      {
+        reader.Skip();
+        return true;
+      }
+
+      // test tokentype here because null might not be convertable to some types, e.g. ignoring null when applied to DateTime
+      if (property.NullValueHandling.GetValueOrDefault(Serializer.NullValueHandling) == NullValueHandling.Ignore && reader.TokenType == JsonToken.Null)
+      {
+        reader.Skip();
+        return true;
+      }
+
+      // test tokentype here because default value might not be convertable to actual type, e.g. default of "" for DateTime
+      if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer.DefaultValueHandling), DefaultValueHandling.Ignore)
+          && JsonReader.IsPrimitiveToken(reader.TokenType)
+          && MiscellaneousUtils.ValueEquals(reader.Value, property.DefaultValue))
+      {
+        reader.Skip();
+        return true;
+      }
+
+      if (property.PropertyContract == null)
+        property.PropertyContract = GetContractSafe(property.PropertyType);
+
+      if (currentValue == null)
+      {
+        propertyContract = property.PropertyContract;
+      }
+      else
+      {
+        propertyContract = GetContractSafe(currentValue.GetType());
+
+        if (propertyContract != property.PropertyContract)
+          propertyConverter = GetConverter(propertyContract, property.MemberConverter, containerContract, containerProperty);
+      }
+
+      return false;
+    }
+
+    private bool HasFlag(DefaultValueHandling value, DefaultValueHandling flag)
+    {
+      return ((value & flag) == flag);
+    }
+
+    private bool ShouldSetPropertyValue(JsonProperty property, object value)
+    {
+      if (property.NullValueHandling.GetValueOrDefault(Serializer.NullValueHandling) == NullValueHandling.Ignore && value == null)
+        return false;
+
+      if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer.DefaultValueHandling), DefaultValueHandling.Ignore)
+        && MiscellaneousUtils.ValueEquals(value, property.DefaultValue))
+        return false;
+
+      if (!property.Writable)
+        return false;
+
+      return true;
+    }
+
+    public object CreateNewDictionary(JsonReader reader, JsonDictionaryContract contract)
+    {
+      object dictionary;
+
+      if (contract.DefaultCreator != null &&
+        (!contract.DefaultCreatorNonPublic || Serializer.ConstructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor))
+        dictionary = contract.DefaultCreator();
+      else
+        throw JsonSerializationException.Create(reader, "Unable to find a default constructor to use for type {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
+
+      return dictionary;
+    }
+
+    private object PopulateDictionary(IWrappedDictionary wrappedDictionary, JsonReader reader, JsonDictionaryContract contract, JsonProperty containerProperty, string id)
+    {
+      object dictionary = wrappedDictionary.UnderlyingDictionary;
+
+      if (id != null)
+        Serializer.ReferenceResolver.AddReference(this, id, dictionary);
+
+      contract.InvokeOnDeserializing(dictionary, Serializer.Context);
+
+      int initialDepth = reader.Depth;
+
+      if (contract.KeyContract == null)
+        contract.KeyContract = GetContractSafe(contract.DictionaryKeyType);
+
+      if (contract.ItemContract == null)
+        contract.ItemContract = GetContractSafe(contract.DictionaryValueType);
+
+      JsonConverter dictionaryValueConverter = contract.ItemConverter ?? GetConverter(contract.ItemContract, null, contract, containerProperty);
+
+      bool finished = false;
+      do
+      {
+        switch (reader.TokenType)
+        {
+          case JsonToken.PropertyName:
+            object keyValue = reader.Value;
+            try
+            {
+              try
+              {
+                keyValue = EnsureType(reader, keyValue, CultureInfo.InvariantCulture, contract.KeyContract, contract.DictionaryKeyType);
+              }
+              catch (Exception ex)
+              {
+                throw JsonSerializationException.Create(reader, "Could not convert string '{0}' to dictionary key type '{1}'. Create a TypeConverter to convert from the string to the key type object.".FormatWith(CultureInfo.InvariantCulture, reader.Value, contract.DictionaryKeyType), ex);
+              }
+
+              if (!ReadForType(reader, contract.ItemContract, dictionaryValueConverter != null))
+                throw JsonSerializationException.Create(reader, "Unexpected end when deserializing object.");
+
+              object itemValue;
+              if (dictionaryValueConverter != null && dictionaryValueConverter.CanRead)
+                itemValue = dictionaryValueConverter.ReadJson(reader, contract.DictionaryValueType, null, GetInternalSerializer());
+              else
+                itemValue = CreateValueInternal(reader, contract.DictionaryValueType, contract.ItemContract, null, contract, containerProperty, null);
+
+              wrappedDictionary[keyValue] = itemValue;
+            }
+            catch (Exception ex)
+            {
+              if (IsErrorHandled(dictionary, contract, keyValue, reader.Path, ex))
+                HandleError(reader, true, initialDepth);
+              else
+                throw;
+            }
+            break;
+          case JsonToken.Comment:
+            break;
+          case JsonToken.EndObject:
+            finished = true;
+            break;
+          default:
+            throw JsonSerializationException.Create(reader, "Unexpected token when deserializing object: " + reader.TokenType);
+        }
+      } while (!finished && reader.Read());
+
+      if (!finished)
+        ThrowUnexpectedEndException(reader, contract, dictionary, "Unexpected end when deserializing object.");
+
+      contract.InvokeOnDeserialized(dictionary, Serializer.Context);
+      return dictionary;
+    }
+
+    private object PopulateMultidimensionalArray(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, string id)
+    {
+      int rank = contract.UnderlyingType.GetArrayRank();
+
+      if (id != null)
+        Serializer.ReferenceResolver.AddReference(this, id, list);
+
+      contract.InvokeOnDeserializing(list, Serializer.Context);
+
+      JsonContract collectionItemContract = GetContractSafe(contract.CollectionItemType);
+      JsonConverter collectionItemConverter = GetConverter(collectionItemContract, null, contract, containerProperty);
+
+      int? previousErrorIndex = null;
+      Stack<IList> listStack = new Stack<IList>();
+      listStack.Push(list);
+      IList currentList = list;
+
+      bool finished = false;
+      do
+      {
+        int initialDepth = reader.Depth;
+
+        if (listStack.Count == rank)
+        {
+          try
+          {
+            if (ReadForType(reader, collectionItemContract, collectionItemConverter != null))
+            {
+              switch (reader.TokenType)
+              {
+                case JsonToken.EndArray:
+                  listStack.Pop();
+                  currentList = listStack.Peek();
+                  previousErrorIndex = null;
+                  break;
+                case JsonToken.Comment:
+                  break;
+                default:
+                  object value;
+
+                  if (collectionItemConverter != null && collectionItemConverter.CanRead)
+                    value = collectionItemConverter.ReadJson(reader, contract.CollectionItemType, null, GetInternalSerializer());
+                  else
+                    value = CreateValueInternal(reader, contract.CollectionItemType, collectionItemContract, null, contract, containerProperty, null);
+
+                  currentList.Add(value);
+                  break;
+              }
+            }
+            else
+            {
+              break;
+            }
+          }
+          catch (Exception ex)
+          {
+            JsonPosition errorPosition = reader.GetPosition(initialDepth);
+
+            if (IsErrorHandled(list, contract, errorPosition.Position, reader.Path, ex))
+            {
+              HandleError(reader, true, initialDepth);
+
+              if (previousErrorIndex != null && previousErrorIndex == errorPosition.Position)
+              {
+                // reader index has not moved since previous error handling
+                // break out of reading array to prevent infinite loop
+                throw JsonSerializationException.Create(reader, "Infinite loop detected from error handling.", ex);
+              }
+              else
+              {
+                previousErrorIndex = errorPosition.Position;
+              }
+            }
+            else
+            {
+              throw;
+            }
+          }
+        }
+        else
+        {
+          if (reader.Read())
+          {
+            switch (reader.TokenType)
+            {
+              case JsonToken.StartArray:
+                IList newList = new List<object>();
+                currentList.Add(newList);
+                listStack.Push(newList);
+                currentList = newList;
+                break;
+              case JsonToken.EndArray:
+                listStack.Pop();
+
+                if (listStack.Count > 0)
+                {
+                  currentList = listStack.Peek();
+                }
+                else
+                {
+                  finished = true;
+                }
+                break;
+              case JsonToken.Comment:
+                break;
+              default:
+                throw JsonSerializationException.Create(reader, "Unexpected token when deserializing multidimensional array: " + reader.TokenType);
+            }
+          }
+          else
+          {
+            break;
+          }
+        }
+      } while (!finished);
+
+      if (!finished)
+        ThrowUnexpectedEndException(reader, contract, list, "Unexpected end when deserializing array.");
+
+      contract.InvokeOnDeserialized(list, Serializer.Context);
+      return list;
+    }
+
+    private void ThrowUnexpectedEndException(JsonReader reader, JsonContract contract, object currentObject, string message)
+    {
+      try
+      {
+        throw JsonSerializationException.Create(reader, message);
+      }
+      catch (Exception ex)
+      {
+        if (IsErrorHandled(currentObject, contract, null, reader.Path, ex))
+          HandleError(reader, false, 0);
+        else
+          throw;
+      }
+    }
+
+    private object PopulateList(IWrappedCollection wrappedList, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, string id)
+    {
+      object list = wrappedList.UnderlyingCollection;
+
+      if (id != null)
+        Serializer.ReferenceResolver.AddReference(this, id, list);
+
+      // can't populate an existing array
+      if (wrappedList.IsFixedSize)
+      {
+        reader.Skip();
+        return list;
+      }
+
+      contract.InvokeOnDeserializing(list, Serializer.Context);
+
+      int initialDepth = reader.Depth;
+
+      JsonContract collectionItemContract = GetContractSafe(contract.CollectionItemType);
+      JsonConverter collectionItemConverter = GetConverter(collectionItemContract, null, contract, containerProperty);
+
+      int? previousErrorIndex = null;
+
+      bool finished = false;
+      do
+      {
+        try
+        {
+          if (ReadForType(reader, collectionItemContract, collectionItemConverter != null))
+          {
+            switch (reader.TokenType)
+            {
+              case JsonToken.EndArray:
+                finished = true;
+                break;
+              case JsonToken.Comment:
+                break;
+              default:
+                object value;
+
+                if (collectionItemConverter != null && collectionItemConverter.CanRead)
+                  value = collectionItemConverter.ReadJson(reader, contract.CollectionItemType, null, GetInternalSerializer());
+                else
+                  value = CreateValueInternal(reader, contract.CollectionItemType, collectionItemContract, null, contract, containerProperty, null);
+
+                wrappedList.Add(value);
+                break;
+            }
+          }
+          else
+          {
+            break;
+          }
+        }
+        catch (Exception ex)
+        {
+          JsonPosition errorPosition = reader.GetPosition(initialDepth);
+
+          if (IsErrorHandled(list, contract, errorPosition.Position, reader.Path, ex))
+          {
+            HandleError(reader, true, initialDepth);
+
+            if (previousErrorIndex != null && previousErrorIndex == errorPosition.Position)
+            {
+              // reader index has not moved since previous error handling
+              // break out of reading array to prevent infinite loop
+              throw JsonSerializationException.Create(reader, "Infinite loop detected from error handling.", ex);
+            }
+            else
+            {
+              previousErrorIndex = errorPosition.Position;
+            }
+          }
+          else
+          {
+            throw;
+          }
+        }
+      } while (!finished);
+
+      if (!finished)
+        ThrowUnexpectedEndException(reader, contract, list, "Unexpected end when deserializing array.");
+
+      contract.InvokeOnDeserialized(list, Serializer.Context);
+      return list;
+    }
+
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+    private object CreateISerializable(JsonReader reader, JsonISerializableContract contract, string id)
+    {
+      Type objectType = contract.UnderlyingType;
+
+      if (!JsonTypeReflector.FullyTrusted)
+      {
+        throw JsonSerializationException.Create(reader, @"Type '{0}' implements ISerializable but cannot be deserialized using the ISerializable interface because the current application is not fully trusted and ISerializable can expose secure data.
+To fix this error either change the environment to be fully trusted, change the application to not deserialize the type, add JsonObjectAttribute to the type or change the JsonSerializer setting ContractResolver to use a new DefaultContractResolver with IgnoreSerializableInterface set to true.
+".FormatWith(CultureInfo.InvariantCulture, objectType));
+      }
+
+      SerializationInfo serializationInfo = new SerializationInfo(contract.UnderlyingType, GetFormatterConverter());
+
+      bool finished = false;
+      do
+      {
+        switch (reader.TokenType)
+        {
+          case JsonToken.PropertyName:
+            string memberName = reader.Value.ToString();
+            if (!reader.Read())
+              throw JsonSerializationException.Create(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));
+
+            serializationInfo.AddValue(memberName, JToken.ReadFrom(reader));
+            break;
+          case JsonToken.Comment:
+            break;
+          case JsonToken.EndObject:
+            finished = true;
+            break;
+          default:
+            throw JsonSerializationException.Create(reader, "Unexpected token when deserializing object: " + reader.TokenType);
+        }
+      } while (!finished && reader.Read());
+
+      if (!finished)
+        ThrowUnexpectedEndException(reader, contract, serializationInfo, "Unexpected end when deserializing object.");
+
+      if (contract.ISerializableCreator == null)
+        throw JsonSerializationException.Create(reader, "ISerializable type '{0}' does not have a valid constructor. To correctly implement ISerializable a constructor that takes SerializationInfo and StreamingContext parameters should be present.".FormatWith(CultureInfo.InvariantCulture, objectType));
+
+      object createdObject = contract.ISerializableCreator(serializationInfo, Serializer.Context);
+
+      if (id != null)
+        Serializer.ReferenceResolver.AddReference(this, id, createdObject);
+
+      // these are together because OnDeserializing takes an object but for an ISerializable the object is fully created in the constructor
+      contract.InvokeOnDeserializing(createdObject, Serializer.Context);
+      contract.InvokeOnDeserialized(createdObject, Serializer.Context);
+
+      return createdObject;
+    }
+#endif
+
+#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
+    private object CreateDynamic(JsonReader reader, JsonDynamicContract contract, JsonProperty member, string id)
+    {
+      IDynamicMetaObjectProvider newObject;
+
+      if (contract.UnderlyingType.IsInterface() || contract.UnderlyingType.IsAbstract())
+        throw JsonSerializationException.Create(reader, "Could not create an instance of type {0}. Type is an interface or abstract class and cannot be instantated.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
+
+      if (contract.DefaultCreator != null &&
+        (!contract.DefaultCreatorNonPublic || Serializer.ConstructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor))
+        newObject = (IDynamicMetaObjectProvider) contract.DefaultCreator();
+      else
+        throw JsonSerializationException.Create(reader, "Unable to find a default constructor to use for type {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
+
+      if (id != null)
+        Serializer.ReferenceResolver.AddReference(this, id, newObject);
+
+      contract.InvokeOnDeserializing(newObject, Serializer.Context);
+
+      int initialDepth = reader.Depth;
+
+      bool finished = false;
+      do
+      {
+        switch (reader.TokenType)
+        {
+          case JsonToken.PropertyName:
+            string memberName = reader.Value.ToString();
+
+            try
+            {
+              if (!reader.Read())
+                throw JsonSerializationException.Create(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));
+
+              // first attempt to find a settable property, otherwise fall back to a dynamic set without type
+              JsonProperty property = contract.Properties.GetClosestMatchProperty(memberName);
+
+              if (property != null && property.Writable && !property.Ignored)
+              {
+                if (property.PropertyContract == null)
+                  property.PropertyContract = GetContractSafe(property.PropertyType);
+
+                JsonConverter propertyConverter = GetConverter(property.PropertyContract, property.MemberConverter, null, null);
+
+                SetPropertyValue(property, propertyConverter, null, member, reader, newObject);
+              }
+              else
+              {
+                Type t = (JsonReader.IsPrimitiveToken(reader.TokenType)) ? reader.ValueType : typeof (IDynamicMetaObjectProvider);
+
+                JsonContract dynamicMemberContract = GetContractSafe(t);
+                JsonConverter dynamicMemberConverter = GetConverter(dynamicMemberContract, null, null, member);
+
+                object value;
+                if (dynamicMemberConverter != null && dynamicMemberConverter.CanRead)
+                  value = dynamicMemberConverter.ReadJson(reader, t, null, GetInternalSerializer());
+                else
+                  value = CreateValueInternal(reader, t, dynamicMemberContract, null, null, member, null);
+
+                newObject.TrySetMember(memberName, value);
+              }
+            }
+            catch (Exception ex)
+            {
+              if (IsErrorHandled(newObject, contract, memberName, reader.Path, ex))
+                HandleError(reader, true, initialDepth);
+              else
+                throw;
+            }
+            break;
+          case JsonToken.EndObject:
+            finished = true;
+            break;
+          default:
+            throw JsonSerializationException.Create(reader, "Unexpected token when deserializing object: " + reader.TokenType);
+        }
+      } while (!finished && reader.Read());
+
+      if (!finished)
+        ThrowUnexpectedEndException(reader, contract, newObject, "Unexpected end when deserializing object.");
+
+      contract.InvokeOnDeserialized(newObject, Serializer.Context);
+
+      return newObject;
+    }
+#endif
+
+    private object CreateObjectFromNonDefaultConstructor(JsonReader reader, JsonObjectContract contract, JsonProperty containerProperty, ConstructorInfo constructorInfo, string id)
+    {
+      ValidationUtils.ArgumentNotNull(constructorInfo, "constructorInfo");
+
+      Type objectType = contract.UnderlyingType;
+
+      IDictionary<JsonProperty, object> propertyValues = ResolvePropertyAndConstructorValues(contract, containerProperty, reader, objectType);
+
+      IDictionary<ParameterInfo, object> constructorParameters = constructorInfo.GetParameters().ToDictionary(p => p, p => (object) null);
+      IDictionary<JsonProperty, object> remainingPropertyValues = new Dictionary<JsonProperty, object>();
+
+      foreach (KeyValuePair<JsonProperty, object> propertyValue in propertyValues)
+      {
+        ParameterInfo matchingConstructorParameter = constructorParameters.ForgivingCaseSensitiveFind(kv => kv.Key.Name, propertyValue.Key.UnderlyingName).Key;
+        if (matchingConstructorParameter != null)
+          constructorParameters[matchingConstructorParameter] = propertyValue.Value;
+        else
+          remainingPropertyValues.Add(propertyValue);
+      }
+
+      object createdObject = constructorInfo.Invoke(constructorParameters.Values.ToArray());
+
+      if (id != null)
+        Serializer.ReferenceResolver.AddReference(this, id, createdObject);
+
+      contract.InvokeOnDeserializing(createdObject, Serializer.Context);
+
+      // go through unused values and set the newly created object's properties
+      foreach (KeyValuePair<JsonProperty, object> remainingPropertyValue in remainingPropertyValues)
+      {
+        JsonProperty property = remainingPropertyValue.Key;
+        object value = remainingPropertyValue.Value;
+
+        if (ShouldSetPropertyValue(remainingPropertyValue.Key, remainingPropertyValue.Value))
+        {
+          property.ValueProvider.SetValue(createdObject, value);
+        }
+        else if (!property.Writable && value != null)
+        {
+          // handle readonly collection/dictionary properties
+          JsonContract propertyContract = Serializer.ContractResolver.ResolveContract(property.PropertyType);
+
+          if (propertyContract.ContractType == JsonContractType.Array)
+          {
+            JsonArrayContract propertyArrayContract = (JsonArrayContract)propertyContract;
+
+            object createdObjectCollection = property.ValueProvider.GetValue(createdObject);
+            if (createdObjectCollection != null)
+            {
+              IWrappedCollection createdObjectCollectionWrapper = propertyArrayContract.CreateWrapper(createdObjectCollection);
+              IWrappedCollection newValues = propertyArrayContract.CreateWrapper(value);
+
+              foreach (object newValue in newValues)
+              {
+                createdObjectCollectionWrapper.Add(newValue);
+              }
+            }
+          }
+          else if (propertyContract.ContractType == JsonContractType.Dictionary)
+          {
+            JsonDictionaryContract jsonDictionaryContract = (JsonDictionaryContract)propertyContract;
+
+            object createdObjectDictionary = property.ValueProvider.GetValue(createdObject);
+            if (createdObjectDictionary != null)
+            {
+              IWrappedDictionary createdObjectDictionaryWrapper = jsonDictionaryContract.CreateWrapper(createdObjectDictionary);
+              IWrappedDictionary newValues = jsonDictionaryContract.CreateWrapper(value);
+
+              foreach (DictionaryEntry newValue in newValues)
+              {
+                createdObjectDictionaryWrapper.Add(newValue.Key, newValue.Value);
+              }
+            }
+          }
+        }
+      }
+
+      contract.InvokeOnDeserialized(createdObject, Serializer.Context);
+      return createdObject;
+    }
+
+    private IDictionary<JsonProperty, object> ResolvePropertyAndConstructorValues(JsonObjectContract contract, JsonProperty containerProperty, JsonReader reader, Type objectType)
+    {
+      IDictionary<JsonProperty, object> propertyValues = new Dictionary<JsonProperty, object>();
+      bool exit = false;
+      do
+      {
+        switch (reader.TokenType)
+        {
+          case JsonToken.PropertyName:
+            string memberName = reader.Value.ToString();
+
+            // attempt exact case match first
+            // then try match ignoring case
+            JsonProperty property = contract.ConstructorParameters.GetClosestMatchProperty(memberName) ??
+              contract.Properties.GetClosestMatchProperty(memberName);
+
+            if (property != null)
+            {
+              if (property.PropertyContract == null)
+                property.PropertyContract = GetContractSafe(property.PropertyType);
+
+              JsonConverter propertyConverter = GetConverter(property.PropertyContract, property.MemberConverter, contract, containerProperty);
+
+              if (!ReadForType(reader, property.PropertyContract, propertyConverter != null))
+                throw JsonSerializationException.Create(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));
+
+              if (!property.Ignored)
+              {
+                if (property.PropertyContract == null)
+                  property.PropertyContract = GetContractSafe(property.PropertyType);
+
+                object propertyValue;
+                if (propertyConverter != null && propertyConverter.CanRead)
+                  propertyValue = propertyConverter.ReadJson(reader, property.PropertyType, null, GetInternalSerializer());
+                else
+                  propertyValue = CreateValueInternal(reader, property.PropertyType, property.PropertyContract, property, contract, containerProperty, null);
+
+                propertyValues[property] = propertyValue;
+              }
+              else
+              {
+                reader.Skip();
+              }
+            }
+            else
+            {
+              if (!reader.Read())
+                throw JsonSerializationException.Create(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));
+
+              if (Serializer.MissingMemberHandling == MissingMemberHandling.Error)
+                throw JsonSerializationException.Create(reader, "Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, objectType.Name));
+
+              reader.Skip();
+            }
+            break;
+          case JsonToken.Comment:
+            break;
+          case JsonToken.EndObject:
+            exit = true;
+            break;
+          default:
+            throw JsonSerializationException.Create(reader, "Unexpected token when deserializing object: " + reader.TokenType);
+        }
+      } while (!exit && reader.Read());
+
+      return propertyValues;
+    }
+
+    private bool ReadForType(JsonReader reader, JsonContract contract, bool hasConverter)
+    {
+      // don't read properties with converters as a specific value
+      // the value might be a string which will then get converted which will error if read as date for example
+      if (hasConverter)
+        return reader.Read();
+
+      ReadType t = (contract != null) ? contract.InternalReadType : ReadType.Read;
+
+      switch (t)
+      {
+        case ReadType.Read:
+          do
+          {
+            if (!reader.Read())
+              return false;
+          } while (reader.TokenType == JsonToken.Comment);
+
+          return true;
+        case ReadType.ReadAsInt32:
+          reader.ReadAsInt32();
+          break;
+        case ReadType.ReadAsDecimal:
+          reader.ReadAsDecimal();
+          break;
+        case ReadType.ReadAsBytes:
+          reader.ReadAsBytes();
+          break;
+        case ReadType.ReadAsString:
+          reader.ReadAsString();
+          break;
+        case ReadType.ReadAsDateTime:
+          reader.ReadAsDateTime();
+          break;
+#if !NET20
+        case ReadType.ReadAsDateTimeOffset:
+          reader.ReadAsDateTimeOffset();
+          break;
+#endif
+        default:
+          throw new ArgumentOutOfRangeException();
+      }
+
+      return (reader.TokenType != JsonToken.None);
+    }
+
+    public object CreateNewObject(JsonReader reader, JsonObjectContract objectContract, JsonProperty containerMember, JsonProperty containerProperty, string id, out bool createdFromNonDefaultConstructor)
+    {
+      object newObject = null;
+
+      if (objectContract.UnderlyingType.IsInterface() || objectContract.UnderlyingType.IsAbstract())
+        throw JsonSerializationException.Create(reader, "Could not create an instance of type {0}. Type is an interface or abstract class and cannot be instantated.".FormatWith(CultureInfo.InvariantCulture, objectContract.UnderlyingType));
+
+      if (objectContract.OverrideConstructor != null)
+      {
+        if (objectContract.OverrideConstructor.GetParameters().Length > 0)
+        {
+          createdFromNonDefaultConstructor = true;
+          return CreateObjectFromNonDefaultConstructor(reader, objectContract, containerMember, objectContract.OverrideConstructor, id);
+        }
+
+        newObject = objectContract.OverrideConstructor.Invoke(null);
+      }
+      else if (objectContract.DefaultCreator != null &&
+        (!objectContract.DefaultCreatorNonPublic || Serializer.ConstructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor || objectContract.ParametrizedConstructor == null))
+      {
+        // use the default constructor if it is...
+        // public
+        // non-public and the user has change constructor handling settings
+        // non-public and there is no other constructor
+        newObject = objectContract.DefaultCreator();
+      }
+      else if (objectContract.ParametrizedConstructor != null)
+      {
+        createdFromNonDefaultConstructor = true;
+        return CreateObjectFromNonDefaultConstructor(reader, objectContract, containerMember, objectContract.ParametrizedConstructor, id);
+      }
+
+      if (newObject == null)
+        throw JsonSerializationException.Create(reader, "Unable to find a constructor to use for type {0}. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute.".FormatWith(CultureInfo.InvariantCulture, objectContract.UnderlyingType));
+
+      createdFromNonDefaultConstructor = false;
+      return newObject;
+    }
+
+    private object PopulateObject(object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, string id)
+    {
+      contract.InvokeOnDeserializing(newObject, Serializer.Context);
+
+      // only need to keep a track of properies presence if they are required or a value should be defaulted if missing
+      Dictionary<JsonProperty, PropertyPresence> propertiesPresence = (contract.HasRequiredOrDefaultValueProperties || HasFlag(Serializer.DefaultValueHandling, DefaultValueHandling.Populate))
+        ? contract.Properties.ToDictionary(m => m, m => PropertyPresence.None)
+        : null;
+
+      if (id != null)
+        Serializer.ReferenceResolver.AddReference(this, id, newObject);
+
+      int initialDepth = reader.Depth;
+
+      bool finished = false;
+      do
+      {
+        switch (reader.TokenType)
+        {
+          case JsonToken.PropertyName:
+            {
+              string memberName = reader.Value.ToString();
+
+              try
+              {
+                // attempt exact case match first
+                // then try match ignoring case
+                JsonProperty property = contract.Properties.GetClosestMatchProperty(memberName);
+
+                if (property == null)
+                {
+                  if (Serializer.MissingMemberHandling == MissingMemberHandling.Error)
+                    throw JsonSerializationException.Create(reader, "Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, contract.UnderlyingType.Name));
+
+                  reader.Skip();
+                  continue;
+                }
+
+                if (property.PropertyContract == null)
+                  property.PropertyContract = GetContractSafe(property.PropertyType);
+
+                JsonConverter propertyConverter = GetConverter(property.PropertyContract, property.MemberConverter, contract, member);
+
+                if (!ReadForType(reader, property.PropertyContract, propertyConverter != null))
+                  throw JsonSerializationException.Create(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));
+
+                SetPropertyPresence(reader, property, propertiesPresence);
+
+                SetPropertyValue(property, propertyConverter, contract, member, reader, newObject);
+              }
+              catch (Exception ex)
+              {
+                if (IsErrorHandled(newObject, contract, memberName, reader.Path, ex))
+                  HandleError(reader, true, initialDepth);
+                else
+                  throw;
+              }
+            }
+            break;
+          case JsonToken.EndObject:
+            finished = true;
+            break;
+          case JsonToken.Comment:
+            // ignore
+            break;
+          default:
+            throw JsonSerializationException.Create(reader, "Unexpected token when deserializing object: " + reader.TokenType);
+        }
+      } while (!finished && reader.Read());
+
+      if (!finished)
+        ThrowUnexpectedEndException(reader, contract, newObject, "Unexpected end when deserializing object.");
+
+      EndObject(newObject, reader, contract, initialDepth, propertiesPresence);
+
+      contract.InvokeOnDeserialized(newObject, Serializer.Context);
+      return newObject;
+    }
+
+    private void EndObject(object newObject, JsonReader reader, JsonObjectContract contract, int initialDepth, Dictionary<JsonProperty, PropertyPresence> propertiesPresence)
+    {
+      if (propertiesPresence != null)
+      {
+        foreach (KeyValuePair<JsonProperty, PropertyPresence> propertyPresence in propertiesPresence)
+        {
+          JsonProperty property = propertyPresence.Key;
+          PropertyPresence presence = propertyPresence.Value;
+
+          if (presence == PropertyPresence.None || presence == PropertyPresence.Null)
+          {
+            try
+            {
+              Required resolvedRequired = property._required ?? contract.ItemRequired ?? Required.Default;
+
+              switch (presence)
+              {
+                case PropertyPresence.None:
+                  if (resolvedRequired == Required.AllowNull || resolvedRequired == Required.Always)
+                    throw JsonSerializationException.Create(reader, "Required property '{0}' not found in JSON.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName));
+
+                  if (property.PropertyContract == null)
+                    property.PropertyContract = GetContractSafe(property.PropertyType);
+
+                  if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer.DefaultValueHandling), DefaultValueHandling.Populate) && property.Writable)
+                    property.ValueProvider.SetValue(newObject, EnsureType(reader, property.DefaultValue, CultureInfo.InvariantCulture, property.PropertyContract, property.PropertyType));
+                  break;
+                case PropertyPresence.Null:
+                  if (resolvedRequired == Required.Always)
+                    throw JsonSerializationException.Create(reader, "Required property '{0}' expects a value but got null.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName));
+                  break;
+              }
+            }
+            catch (Exception ex)
+            {
+              if (IsErrorHandled(newObject, contract, property.PropertyName, reader.Path, ex))
+                HandleError(reader, true, initialDepth);
+              else
+                throw;
+            }
+          }
+        }
+      }
+    }
+
+    private void SetPropertyPresence(JsonReader reader, JsonProperty property, Dictionary<JsonProperty, PropertyPresence> requiredProperties)
+    {
+      if (property != null && requiredProperties != null)
+      {
+        requiredProperties[property] = (reader.TokenType == JsonToken.Null || reader.TokenType == JsonToken.Undefined)
+          ? PropertyPresence.Null
+          : PropertyPresence.Value;
+      }
+    }
+
+    private void HandleError(JsonReader reader, bool readPastError, int initialDepth)
+    {
+      ClearErrorContext();
+
+      if (readPastError)
+      {
+        reader.Skip();
+
+        while (reader.Depth > (initialDepth + 1))
+        {
+          if (!reader.Read())
+            break;
+        }
+      }
+    }
+
+    internal enum PropertyPresence
+    {
+      None,
+      Null,
+      Value
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs
index 33e364f..e502cb6 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs
@@ -1,595 +1,832 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Globalization;
-using System.Linq;
-using System.Reflection;
-using System.Runtime.Serialization.Formatters;
-using Newtonsoft.Json.Linq;
-using Newtonsoft.Json.Utilities;
-using System.Runtime.Serialization;
-
-namespace Newtonsoft.Json.Serialization
-{
-  internal class JsonSerializerInternalWriter : JsonSerializerInternalBase
-  {
-    private JsonSerializerProxy _internalSerializer;
-    private List<object> _serializeStack;
-
-    private List<object> SerializeStack
-    {
-      get
-      {
-        if (_serializeStack == null)
-          _serializeStack = new List<object>();
-
-        return _serializeStack;
-      }
-    }
-
-    public JsonSerializerInternalWriter(JsonSerializer serializer) : base(serializer)
-    {
-    }
-
-    public void Serialize(JsonWriter jsonWriter, object value)
-    {
-      if (jsonWriter == null)
-        throw new ArgumentNullException("jsonWriter");
-
-      SerializeValue(jsonWriter, value, GetContractSafe(value), null, null);
-    }
-
-    private JsonSerializerProxy GetInternalSerializer()
-    {
-      if (_internalSerializer == null)
-        _internalSerializer = new JsonSerializerProxy(this);
-
-      return _internalSerializer;
-    }
-
-    private JsonContract GetContractSafe(object value)
-    {
-      if (value == null)
-        return null;
-
-      return Serializer.ContractResolver.ResolveContract(value.GetType());
-    }
-
-    private void SerializeValue(JsonWriter writer, object value, JsonContract valueContract, JsonProperty member, JsonContract collectionValueContract)
-    {
-      JsonConverter converter = (member != null) ? member.Converter : null;
-
-      if (value == null)
-      {
-        writer.WriteNull();
-        return;
-      }
-
-      if ((converter != null
-          || ((converter = valueContract.Converter) != null)
-          || ((converter = Serializer.GetMatchingConverter(valueContract.UnderlyingType)) != null)
-          || ((converter = valueContract.InternalConverter) != null))
-        && converter.CanWrite)
-      {
-        SerializeConvertable(writer, converter, value, valueContract);
-      }
-      else if (valueContract is JsonPrimitiveContract)
-      {
-        writer.WriteValue(value);
-      }
-      else if (valueContract is JsonStringContract)
-      {
-        SerializeString(writer, value, (JsonStringContract) valueContract);
-      }
-      else if (valueContract is JsonObjectContract)
-      {
-        SerializeObject(writer, value, (JsonObjectContract)valueContract, member, collectionValueContract);
-      }
-      else if (valueContract is JsonDictionaryContract)
-      {
-        JsonDictionaryContract dictionaryContract = (JsonDictionaryContract) valueContract;
-        SerializeDictionary(writer, dictionaryContract.CreateWrapper(value), dictionaryContract, member, collectionValueContract);
-      }
-      else if (valueContract is JsonArrayContract)
-      {
-        if (value is IList)
-        {
-          SerializeList(writer, (IList)value, (JsonArrayContract)valueContract, member, collectionValueContract);
-        }
-        else if (value is IEnumerable)
-        {
-          SerializeList(writer, ((IEnumerable)value).Cast<object>().ToList(), (JsonArrayContract)valueContract, member, collectionValueContract);
-        }
-        else
-        {
-          throw new Exception(
-            "Cannot serialize '{0}' into a JSON array. Type does not implement IEnumerable.".FormatWith(
-              CultureInfo.InvariantCulture, value.GetType()));
-        }
-      }
-      else if (valueContract is JsonLinqContract)
-      {
-        ((JToken)value).WriteTo(writer, (Serializer.Converters != null) ? Serializer.Converters.ToArray() : null);
-      }
-#if !SILVERLIGHT && !PocketPC
-      else if (valueContract is JsonISerializableContract)
-      {
-        SerializeISerializable(writer, (ISerializable) value, (JsonISerializableContract) valueContract);
-      }
-#endif
-    }
-
-    private bool ShouldWriteReference(object value, JsonProperty property, JsonContract contract)
-    {
-      if (value == null)
-        return false;
-      if (contract is JsonPrimitiveContract)
-        return false;
-
-      bool? isReference = null;
-
-      // value could be coming from a dictionary or array and not have a property
-      if (property != null)
-        isReference = property.IsReference;
-
-      if (isReference == null)
-        isReference = contract.IsReference;
-
-      if (isReference == null)
-      {
-        if (contract is JsonArrayContract)
-          isReference = HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Arrays);
-        else
-          isReference = HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects);
-      }
-
-      if (!isReference.Value)
-        return false;
-
-      return Serializer.ReferenceResolver.IsReferenced(value);
-    }
-
-    private void WriteMemberInfoProperty(JsonWriter writer, object memberValue, JsonProperty property, JsonContract contract)
-    {
-      string propertyName = property.PropertyName;
-      object defaultValue = property.DefaultValue;
-
-      if (property.NullValueHandling.GetValueOrDefault(Serializer.NullValueHandling) == NullValueHandling.Ignore &&
-          memberValue == null)
-        return;
-
-      if (property.DefaultValueHandling.GetValueOrDefault(Serializer.DefaultValueHandling) ==
-          DefaultValueHandling.Ignore && Equals(memberValue, defaultValue))
-        return;
-
-      if (ShouldWriteReference(memberValue, property, contract))
-      {
-        writer.WritePropertyName(propertyName);
-        WriteReference(writer, memberValue);
-        return;
-      }
-
-      if (!CheckForCircularReference(memberValue, property.ReferenceLoopHandling, contract))
-        return;
-
-      if (memberValue == null && property.Required == Required.Always)
-        throw new JsonSerializationException("Cannot write a null value for property '{0}'. Property requires a value.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName));
-
-      writer.WritePropertyName(propertyName);
-      SerializeValue(writer, memberValue, contract, property, null);
-    }
-
-    private bool CheckForCircularReference(object value, ReferenceLoopHandling? referenceLoopHandling, JsonContract contract)
-    {
-      if (value == null || contract is JsonPrimitiveContract)
-        return true;
-
-      if (SerializeStack.IndexOf(value) != -1)
-      {
-        switch (referenceLoopHandling.GetValueOrDefault(Serializer.ReferenceLoopHandling))
-        {
-          case ReferenceLoopHandling.Error:
-            throw new JsonSerializationException("Self referencing loop");
-          case ReferenceLoopHandling.Ignore:
-            return false;
-          case ReferenceLoopHandling.Serialize:
-            return true;
-          default:
-            throw new InvalidOperationException("Unexpected ReferenceLoopHandling value: '{0}'".FormatWith(CultureInfo.InvariantCulture, Serializer.ReferenceLoopHandling));
-        }
-      }
-
-      return true;
-    }
-
-    private void WriteReference(JsonWriter writer, object value)
-    {
-      writer.WriteStartObject();
-      writer.WritePropertyName(JsonTypeReflector.RefPropertyName);
-      writer.WriteValue(Serializer.ReferenceResolver.GetReference(value));
-      writer.WriteEndObject();
-    }
-
-    internal static bool TryConvertToString(object value, Type type, out string s)
-    {
-#if !PocketPC
-      TypeConverter converter = ConvertUtils.GetConverter(type);
-
-      // use the objectType's TypeConverter if it has one and can convert to a string
-      if (converter != null
-#if !SILVERLIGHT
-        && !(converter is ComponentConverter)
-#endif
-        && converter.GetType() != typeof(TypeConverter))
-      {
-        if (converter.CanConvertTo(typeof(string)))
-        {
-#if !SILVERLIGHT
-          s = converter.ConvertToInvariantString(value);
-#else
-          s = converter.ConvertToString(value);
-#endif
-          return true;
-        }
-      }
-#endif
-
-#if SILVERLIGHT || PocketPC
-      if (value is Guid || value is Uri || value is TimeSpan)
-      {
-        s = value.ToString();
-        return true;
-      }
-#endif
-
-      if (value is Type)
-      {
-        s = ((Type)value).AssemblyQualifiedName;
-        return true;
-      }
-
-      s = null;
-      return false;
-    }
-
-    private void SerializeString(JsonWriter writer, object value, JsonStringContract contract)
-    {
-      contract.InvokeOnSerializing(value, Serializer.Context);
-
-      string s;
-      TryConvertToString(value, contract.UnderlyingType, out s);
-      writer.WriteValue(s);
-
-      contract.InvokeOnSerialized(value, Serializer.Context);
-    }
-
-    private void SerializeObject(JsonWriter writer, object value, JsonObjectContract contract, JsonProperty member, JsonContract collectionValueContract)
-    {
-      contract.InvokeOnSerializing(value, Serializer.Context);
-
-      SerializeStack.Add(value);
-      writer.WriteStartObject();
-
-      bool isReference = contract.IsReference ?? HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects);
-      if (isReference)
-      {
-        writer.WritePropertyName(JsonTypeReflector.IdPropertyName);
-        writer.WriteValue(Serializer.ReferenceResolver.GetReference(value));
-      }
-      if (ShouldWriteType(TypeNameHandling.Objects, contract, member, collectionValueContract))
-      {
-        WriteTypeProperty(writer, contract.UnderlyingType);
-      }
-
-      int initialDepth = writer.Top;
-
-      foreach (JsonProperty property in contract.Properties)
-      {
-        try
-        {
-          if (!property.Ignored && property.Readable && ShouldSerialize(property, value))
-          {
-            object memberValue = property.ValueProvider.GetValue(value);
-            JsonContract memberContract = GetContractSafe(memberValue);
-
-            WriteMemberInfoProperty(writer, memberValue, property, memberContract);
-          }
-        }
-        catch (Exception ex)
-        {
-          if (IsErrorHandled(value, contract, property.PropertyName, ex))
-            HandleError(writer, initialDepth);
-          else
-            throw;
-        }
-      }
-
-      writer.WriteEndObject();
-      SerializeStack.RemoveAt(SerializeStack.Count - 1);
-
-      contract.InvokeOnSerialized(value, Serializer.Context);
-    }
-
-    private void WriteTypeProperty(JsonWriter writer, Type type)
-    {
-      writer.WritePropertyName(JsonTypeReflector.TypePropertyName);
-      writer.WriteValue(ReflectionUtils.GetTypeName(type, Serializer.TypeNameAssemblyFormat));
-    }
-
-    private bool HasFlag(PreserveReferencesHandling value, PreserveReferencesHandling flag)
-    {
-      return ((value & flag) == flag);
-    }
-
-    private bool HasFlag(TypeNameHandling value, TypeNameHandling flag)
-    {
-      return ((value & flag) == flag);
-    }
-
-    private void SerializeConvertable(JsonWriter writer, JsonConverter converter, object value, JsonContract contract)
-    {
-      if (ShouldWriteReference(value, null, contract))
-      {
-        WriteReference(writer, value);
-      }
-      else
-      {
-        if (!CheckForCircularReference(value, null, contract))
-          return;
-
-        SerializeStack.Add(value);
-
-        converter.WriteJson(writer, value, GetInternalSerializer());
-
-        SerializeStack.RemoveAt(SerializeStack.Count - 1);
-      }
-    }
-
-    private void SerializeList(JsonWriter writer, IList values, JsonArrayContract contract, JsonProperty member, JsonContract collectionValueContract)
-    {
-      contract.InvokeOnSerializing(values, Serializer.Context);
-
-      SerializeStack.Add(values);
-
-      bool isReference = contract.IsReference ?? HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Arrays);
-      bool includeTypeDetails = ShouldWriteType(TypeNameHandling.Arrays, contract, member, collectionValueContract);
-
-      if (isReference || includeTypeDetails)
-      {
-        writer.WriteStartObject();
-
-        if (isReference)
-        {
-          writer.WritePropertyName(JsonTypeReflector.IdPropertyName);
-          writer.WriteValue(Serializer.ReferenceResolver.GetReference(values));
-        }
-        if (includeTypeDetails)
-        {
-          WriteTypeProperty(writer, values.GetType());
-        }
-        writer.WritePropertyName(JsonTypeReflector.ArrayValuesPropertyName);
-      }
-
-      JsonContract childValuesContract = Serializer.ContractResolver.ResolveContract(contract.CollectionItemType ?? typeof(object));
-
-      writer.WriteStartArray();
-
-      int initialDepth = writer.Top;
-
-      for (int i = 0; i < values.Count; i++)
-      {
-        try
-        {
-          object value = values[i];
-          JsonContract valueContract = GetContractSafe(value);
-
-          if (ShouldWriteReference(value, null, valueContract))
-          {
-            WriteReference(writer, value);
-          }
-          else
-          {
-            if (!CheckForCircularReference(value, null, contract))
-              continue;
-
-            SerializeValue(writer, value, valueContract, null, childValuesContract);
-          }
-        }
-        catch (Exception ex)
-        {
-          if (IsErrorHandled(values, contract, i, ex))
-            HandleError(writer, initialDepth);
-          else
-            throw;
-        }
-      }
-
-      writer.WriteEndArray();
-
-      if (isReference || includeTypeDetails)
-      {
-        writer.WriteEndObject();
-      }
-
-      SerializeStack.RemoveAt(SerializeStack.Count - 1);
-
-      contract.InvokeOnSerialized(values, Serializer.Context);
-    }
-
-#if !SILVERLIGHT && !PocketPC
-    private void SerializeISerializable(JsonWriter writer, ISerializable value, JsonISerializableContract contract)
-    {
-      contract.InvokeOnSerializing(value, Serializer.Context);
-      SerializeStack.Add(value);
-
-      writer.WriteStartObject();
-
-      SerializationInfo serializationInfo = new SerializationInfo(contract.UnderlyingType, new FormatterConverter());
-      value.GetObjectData(serializationInfo, Serializer.Context);
-
-      foreach (SerializationEntry serializationEntry in serializationInfo)
-      {
-        writer.WritePropertyName(serializationEntry.Name);
-        SerializeValue(writer, serializationEntry.Value, GetContractSafe(serializationEntry.Value), null, null);
-      }
-
-      writer.WriteEndObject();
-
-      SerializeStack.RemoveAt(SerializeStack.Count - 1);
-      contract.InvokeOnSerialized(value, Serializer.Context);
-    }
-#endif
-
-    //private bool ShouldWriteTypeProperty(JsonProperty member, JsonContract contract, TypeNameHandling typeFlag)
-    //{
-    //  if (HasFlag(((member != null) ? member.TypeNameHandling : null) ?? Serializer.TypeNameHandling, typeFlag))
-    //    return true;
-
-    //  if ((((member != null) ? member.TypeNameHandling : null) ?? Serializer.TypeNameHandling) == TypeNameHandling.Auto)
-
-    //      || (member != null
-    //          && (member.TypeNameHandling ?? Serializer.TypeNameHandling) == TypeNameHandling.Auto
-    //          && contract.UnderlyingType != member.PropertyType)
-    //      )
-    //}
-
-    private bool ShouldWriteType(TypeNameHandling typeNameHandlingFlag, JsonContract contract, JsonProperty member, JsonContract collectionValueContract)
-    {
-      if (HasFlag(((member != null) ? member.TypeNameHandling : null) ?? Serializer.TypeNameHandling, typeNameHandlingFlag))
-        return true;
-
-      if (member != null)
-      {
-        if ((member.TypeNameHandling ?? Serializer.TypeNameHandling) == TypeNameHandling.Auto && contract.UnderlyingType != member.PropertyType)
-          return true;
-      }
-      else if (collectionValueContract != null)
-      {
-        if (Serializer.TypeNameHandling == TypeNameHandling.Auto && contract.UnderlyingType != collectionValueContract.UnderlyingType)
-          return true;
-      }
-
-      return false;
-    }
-
-    private void SerializeDictionary(JsonWriter writer, IWrappedDictionary values, JsonDictionaryContract contract, JsonProperty member, JsonContract collectionValueContract)
-    {
-      contract.InvokeOnSerializing(values.UnderlyingDictionary, Serializer.Context);
-
-      SerializeStack.Add(values.UnderlyingDictionary);
-      writer.WriteStartObject();
-
-      bool isReference = contract.IsReference ?? HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects);
-      if (isReference)
-      {
-        writer.WritePropertyName(JsonTypeReflector.IdPropertyName);
-        writer.WriteValue(Serializer.ReferenceResolver.GetReference(values.UnderlyingDictionary));
-      }
-      if (ShouldWriteType(TypeNameHandling.Objects, contract, member, collectionValueContract))
-      {
-        WriteTypeProperty(writer, values.UnderlyingDictionary.GetType());
-      }
-
-      JsonContract childValuesContract = Serializer.ContractResolver.ResolveContract(contract.DictionaryValueType ?? typeof(object));
-
-      int initialDepth = writer.Top;
-
-      // Mono Unity 3.0 fix
-      IDictionary d = values;
-
-      foreach (DictionaryEntry entry in d)
-      {
-        string propertyName = GetPropertyName(entry);
-
-        try
-        {
-          object value = entry.Value;
-          JsonContract valueContract = GetContractSafe(value);
-
-          if (ShouldWriteReference(value, null, valueContract))
-          {
-            writer.WritePropertyName(propertyName);
-            WriteReference(writer, value);
-          }
-          else
-          {
-            if (!CheckForCircularReference(value, null, contract))
-              continue;
-
-            writer.WritePropertyName(propertyName);
-
-            SerializeValue(writer, value, valueContract, null, childValuesContract);
-          }
-        }
-        catch (Exception ex)
-        {
-          if (IsErrorHandled(values.UnderlyingDictionary, contract, propertyName, ex))
-            HandleError(writer, initialDepth);
-          else
-            throw;
-        }
-      }
-
-      writer.WriteEndObject();
-      SerializeStack.RemoveAt(SerializeStack.Count - 1);
-
-      contract.InvokeOnSerialized(values.UnderlyingDictionary, Serializer.Context);
-    }
-
-    private string GetPropertyName(DictionaryEntry entry)
-    {
-      string propertyName;
-
-      if (entry.Key is IConvertible)
-        return Convert.ToString(entry.Key, CultureInfo.InvariantCulture);
-      else if (TryConvertToString(entry.Key, entry.Key.GetType(), out propertyName))
-        return propertyName;
-      else
-        return entry.Key.ToString();
-    }
-
-    private void HandleError(JsonWriter writer, int initialDepth)
-    {
-      ClearErrorContext();
-
-      while (writer.Top > initialDepth)
-      {
-        writer.WriteEnd();
-      }
-    }
-
-    private bool ShouldSerialize(JsonProperty property, object target)
-    {
-      if (property.ShouldSerialize == null)
-        return true;
-
-      return property.ShouldSerialize(target);
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
+using System.Dynamic;
+#endif
+using System.Globalization;
+using System.Security;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Utilities;
+using System.Runtime.Serialization;
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#else
+using System.Linq;
+#endif
+
+namespace Newtonsoft.Json.Serialization
+{
+  internal class JsonSerializerInternalWriter : JsonSerializerInternalBase
+  {
+    private readonly List<object> _serializeStack = new List<object>();
+    private JsonSerializerProxy _internalSerializer;
+
+    public JsonSerializerInternalWriter(JsonSerializer serializer)
+      : base(serializer)
+    {
+    }
+
+    public void Serialize(JsonWriter jsonWriter, object value)
+    {
+      if (jsonWriter == null)
+        throw new ArgumentNullException("jsonWriter");
+
+      SerializeValue(jsonWriter, value, GetContractSafe(value), null, null, null);
+    }
+
+    private JsonSerializerProxy GetInternalSerializer()
+    {
+      if (_internalSerializer == null)
+        _internalSerializer = new JsonSerializerProxy(this);
+
+      return _internalSerializer;
+    }
+
+    private JsonContract GetContractSafe(object value)
+    {
+      if (value == null)
+        return null;
+
+      return Serializer.ContractResolver.ResolveContract(value.GetType());
+    }
+
+    private void SerializePrimitive(JsonWriter writer, object value, JsonPrimitiveContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
+    {
+      if (contract.UnderlyingType == typeof (byte[]))
+      {
+        bool includeTypeDetails = ShouldWriteType(TypeNameHandling.Objects, contract, member, containerContract, containerProperty);
+        if (includeTypeDetails)
+        {
+          writer.WriteStartObject();
+          WriteTypeProperty(writer, contract.CreatedType);
+          writer.WritePropertyName(JsonTypeReflector.ValuePropertyName);
+          writer.WriteValue(value);
+          writer.WriteEndObject();
+          return;
+        }
+      }
+
+      writer.WriteValue(value);
+    }
+
+    private void SerializeValue(JsonWriter writer, object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
+    {
+      if (value == null)
+      {
+        writer.WriteNull();
+        return;
+      }
+
+      JsonConverter converter;
+      if ((((converter = (member != null) ? member.Converter : null) != null)
+           || ((converter = (containerProperty != null) ? containerProperty.ItemConverter : null) != null)
+           || ((converter = (containerContract != null) ? containerContract.ItemConverter : null) != null)
+           || ((converter = valueContract.Converter) != null)
+           || ((converter = Serializer.GetMatchingConverter(valueContract.UnderlyingType)) != null)
+           || ((converter = valueContract.InternalConverter) != null))
+          && converter.CanWrite)
+      {
+        SerializeConvertable(writer, converter, value, valueContract, containerContract, containerProperty);
+        return;
+      }
+
+      switch (valueContract.ContractType)
+      {
+        case JsonContractType.Object:
+          SerializeObject(writer, value, (JsonObjectContract)valueContract, member, containerContract, containerProperty);
+          break;
+        case JsonContractType.Array:
+          JsonArrayContract arrayContract = (JsonArrayContract) valueContract;
+          if (!arrayContract.IsMultidimensionalArray)
+            SerializeList(writer, arrayContract.CreateWrapper(value), arrayContract, member, containerContract, containerProperty);
+          else
+            SerializeMultidimensionalArray(writer, (Array)value, arrayContract, member, containerContract, containerProperty);
+          break;
+        case JsonContractType.Primitive:
+          SerializePrimitive(writer, value, (JsonPrimitiveContract)valueContract, member, containerContract, containerProperty);
+          break;
+        case JsonContractType.String:
+          SerializeString(writer, value, (JsonStringContract)valueContract);
+          break;
+        case JsonContractType.Dictionary:
+          JsonDictionaryContract dictionaryContract = (JsonDictionaryContract) valueContract;
+          SerializeDictionary(writer, dictionaryContract.CreateWrapper(value), dictionaryContract, member, containerContract, containerProperty);
+          break;
+#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
+        case JsonContractType.Dynamic:
+          SerializeDynamic(writer, (IDynamicMetaObjectProvider)value, (JsonDynamicContract)valueContract, member, containerContract, containerProperty);
+          break;
+#endif
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+        case JsonContractType.Serializable:
+          SerializeISerializable(writer, (ISerializable)value, (JsonISerializableContract)valueContract, member, containerContract, containerProperty);
+          break;
+#endif
+        case JsonContractType.Linq:
+          ((JToken) value).WriteTo(writer, (Serializer.Converters != null) ? Serializer.Converters.ToArray() : null);
+          break;
+      }
+    }
+
+    private bool? ResolveIsReference(JsonContract contract, JsonProperty property, JsonContainerContract collectionContract, JsonProperty containerProperty)
+    {
+      bool? isReference = null;
+
+      // value could be coming from a dictionary or array and not have a property
+      if (property != null)
+        isReference = property.IsReference;
+
+      if (isReference == null && containerProperty != null)
+        isReference = containerProperty.ItemIsReference;
+
+      if (isReference == null && collectionContract != null)
+        isReference = collectionContract.ItemIsReference;
+
+      if (isReference == null)
+        isReference = contract.IsReference;
+
+      return isReference;
+    }
+
+    private bool ShouldWriteReference(object value, JsonProperty property, JsonContract valueContract, JsonContainerContract collectionContract, JsonProperty containerProperty)
+    {
+      if (value == null)
+        return false;
+      if (valueContract.ContractType == JsonContractType.Primitive || valueContract.ContractType == JsonContractType.String)
+        return false;
+
+      bool? isReference = ResolveIsReference(valueContract, property, collectionContract, containerProperty);
+
+      if (isReference == null)
+      {
+        if (valueContract.ContractType == JsonContractType.Array)
+          isReference = HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Arrays);
+        else
+          isReference = HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects);
+      }
+
+      if (!isReference.Value)
+        return false;
+
+      return Serializer.ReferenceResolver.IsReferenced(this, value);
+    }
+
+    private bool ShouldWriteProperty(object memberValue, JsonProperty property)
+    {
+      if (property.NullValueHandling.GetValueOrDefault(Serializer.NullValueHandling) == NullValueHandling.Ignore &&
+          memberValue == null)
+        return false;
+
+      if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer.DefaultValueHandling), DefaultValueHandling.Ignore)
+          && MiscellaneousUtils.ValueEquals(memberValue, property.DefaultValue))
+        return false;
+
+      return true;
+    }
+
+    private bool CheckForCircularReference(JsonWriter writer, object value, JsonProperty property, JsonContract contract, JsonContainerContract containerContract, JsonProperty containerProperty)
+    {
+      if (value == null || contract.ContractType == JsonContractType.Primitive || contract.ContractType == JsonContractType.String)
+        return true;
+
+      ReferenceLoopHandling? referenceLoopHandling = null;
+
+      if (property != null)
+        referenceLoopHandling = property.ReferenceLoopHandling;
+
+      if (referenceLoopHandling == null && containerProperty != null)
+        referenceLoopHandling = containerProperty.ItemReferenceLoopHandling;
+
+      if (referenceLoopHandling == null && containerContract != null)
+        referenceLoopHandling = containerContract.ItemReferenceLoopHandling;
+
+      if (_serializeStack.IndexOf(value) != -1)
+      {
+        switch (referenceLoopHandling.GetValueOrDefault(Serializer.ReferenceLoopHandling))
+        {
+          case ReferenceLoopHandling.Error:
+            string message = "Self referencing loop detected";
+            if (property != null)
+              message += " for property '{0}'".FormatWith(CultureInfo.InvariantCulture, property.PropertyName);
+            message += " with type '{0}'.".FormatWith(CultureInfo.InvariantCulture, value.GetType());
+
+            throw JsonSerializationException.Create(null, writer.ContainerPath, message, null);
+          case ReferenceLoopHandling.Ignore:
+            return false;
+          case ReferenceLoopHandling.Serialize:
+            return true;
+          default:
+            throw new InvalidOperationException("Unexpected ReferenceLoopHandling value: '{0}'".FormatWith(CultureInfo.InvariantCulture, Serializer.ReferenceLoopHandling));
+        }
+      }
+
+      return true;
+    }
+
+    private void WriteReference(JsonWriter writer, object value)
+    {
+      writer.WriteStartObject();
+      writer.WritePropertyName(JsonTypeReflector.RefPropertyName);
+      writer.WriteValue(Serializer.ReferenceResolver.GetReference(this, value));
+      writer.WriteEndObject();
+    }
+
+    internal static bool TryConvertToString(object value, Type type, out string s)
+    {
+#if !(PocketPC || NETFX_CORE || PORTABLE)
+      TypeConverter converter = ConvertUtils.GetConverter(type);
+
+      // use the objectType's TypeConverter if it has one and can convert to a string
+      if (converter != null
+#if !SILVERLIGHT
+ && !(converter is ComponentConverter)
+#endif
+ && converter.GetType() != typeof(TypeConverter))
+      {
+        if (converter.CanConvertTo(typeof(string)))
+        {
+#if !SILVERLIGHT
+          s = converter.ConvertToInvariantString(value);
+#else
+          s = converter.ConvertToString(value);
+#endif
+          return true;
+        }
+      }
+#endif
+
+#if SILVERLIGHT || PocketPC || NETFX_CORE
+      if (value is Guid || value is Uri || value is TimeSpan)
+      {
+        s = value.ToString();
+        return true;
+      }
+#endif
+
+      if (value is Type)
+      {
+        s = ((Type)value).AssemblyQualifiedName;
+        return true;
+      }
+
+      s = null;
+      return false;
+    }
+
+    private void SerializeString(JsonWriter writer, object value, JsonStringContract contract)
+    {
+      contract.InvokeOnSerializing(value, Serializer.Context);
+
+      string s;
+      TryConvertToString(value, contract.UnderlyingType, out s);
+      writer.WriteValue(s);
+
+      contract.InvokeOnSerialized(value, Serializer.Context);
+    }
+
+    private void SerializeObject(JsonWriter writer, object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
+    {
+      contract.InvokeOnSerializing(value, Serializer.Context);
+
+      _serializeStack.Add(value);
+
+      WriteObjectStart(writer, value, contract, member, collectionContract, containerProperty);
+
+      int initialDepth = writer.Top;
+
+      foreach (JsonProperty property in contract.Properties)
+      {
+        try
+        {
+          object memberValue;
+          JsonContract memberContract;
+
+          if (!CalculatePropertyValues(writer, value, contract, member, property, out memberContract, out memberValue))
+            continue;
+
+          writer.WritePropertyName(property.PropertyName);
+          SerializeValue(writer, memberValue, memberContract, property, contract, member);
+        }
+        catch (Exception ex)
+        {
+          if (IsErrorHandled(value, contract, property.PropertyName, writer.ContainerPath, ex))
+            HandleError(writer, initialDepth);
+          else
+            throw;
+        }
+      }
+
+      writer.WriteEndObject();
+
+      _serializeStack.RemoveAt(_serializeStack.Count - 1);
+
+      contract.InvokeOnSerialized(value, Serializer.Context);
+    }
+
+    private bool CalculatePropertyValues(JsonWriter writer, object value, JsonContainerContract contract, JsonProperty member, JsonProperty property, out JsonContract memberContract, out object memberValue)
+    {
+      if (!property.Ignored && property.Readable && ShouldSerialize(property, value) && IsSpecified(property, value))
+      {
+        if (property.PropertyContract == null)
+          property.PropertyContract = Serializer.ContractResolver.ResolveContract(property.PropertyType);
+
+        memberValue = property.ValueProvider.GetValue(value);
+        memberContract = (property.PropertyContract.UnderlyingType.IsSealed()) ? property.PropertyContract : GetContractSafe(memberValue);
+
+        if (ShouldWriteProperty(memberValue, property))
+        {
+          if (ShouldWriteReference(memberValue, property, memberContract, contract, member))
+          {
+            writer.WritePropertyName(property.PropertyName);
+            WriteReference(writer, memberValue);
+            return false;
+          }
+
+          if (!CheckForCircularReference(writer, memberValue, property, memberContract, contract, member))
+            return false;
+
+          if (memberValue == null)
+          {
+            JsonObjectContract objectContract = contract as JsonObjectContract;
+            Required resolvedRequired = property._required ?? ((objectContract != null) ? objectContract.ItemRequired : null) ?? Required.Default;
+            if (resolvedRequired == Required.Always)
+              throw JsonSerializationException.Create(null, writer.ContainerPath, "Cannot write a null value for property '{0}'. Property requires a value.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName), null);
+          }
+
+          return true;
+        }
+      }
+
+      memberContract = null;
+      memberValue = null;
+      return false;
+    }
+
+    private void WriteObjectStart(JsonWriter writer, object value, JsonContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
+    {
+      writer.WriteStartObject();
+
+      bool isReference = ResolveIsReference(contract, member, collectionContract, containerProperty) ?? HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects);
+      if (isReference)
+      {
+        writer.WritePropertyName(JsonTypeReflector.IdPropertyName);
+        writer.WriteValue(Serializer.ReferenceResolver.GetReference(this, value));
+      }
+      if (ShouldWriteType(TypeNameHandling.Objects, contract, member, collectionContract, containerProperty))
+      {
+        WriteTypeProperty(writer, contract.UnderlyingType);
+      }
+    }
+
+    private void WriteTypeProperty(JsonWriter writer, Type type)
+    {
+      writer.WritePropertyName(JsonTypeReflector.TypePropertyName);
+      writer.WriteValue(ReflectionUtils.GetTypeName(type, Serializer.TypeNameAssemblyFormat, Serializer.Binder));
+    }
+
+    private bool HasFlag(DefaultValueHandling value, DefaultValueHandling flag)
+    {
+      return ((value & flag) == flag);
+    }
+
+    private bool HasFlag(PreserveReferencesHandling value, PreserveReferencesHandling flag)
+    {
+      return ((value & flag) == flag);
+    }
+
+    private bool HasFlag(TypeNameHandling value, TypeNameHandling flag)
+    {
+      return ((value & flag) == flag);
+    }
+
+    private void SerializeConvertable(JsonWriter writer, JsonConverter converter, object value, JsonContract contract, JsonContainerContract collectionContract, JsonProperty containerProperty)
+    {
+      if (ShouldWriteReference(value, null, contract, collectionContract, containerProperty))
+      {
+        WriteReference(writer, value);
+      }
+      else
+      {
+        if (!CheckForCircularReference(writer, value, null, contract, collectionContract, containerProperty))
+          return;
+
+        _serializeStack.Add(value);
+
+        converter.WriteJson(writer, value, GetInternalSerializer());
+
+        _serializeStack.RemoveAt(_serializeStack.Count - 1);
+      }
+    }
+
+    private void SerializeList(JsonWriter writer, IWrappedCollection values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
+    {
+      contract.InvokeOnSerializing(values.UnderlyingCollection, Serializer.Context);
+
+      _serializeStack.Add(values.UnderlyingCollection);
+
+      bool hasWrittenMetadataObject = WriteStartArray(writer, values.UnderlyingCollection, contract, member, collectionContract, containerProperty);
+
+      writer.WriteStartArray();
+
+      int initialDepth = writer.Top;
+
+      int index = 0;
+      // note that an error in the IEnumerable won't be caught
+      foreach (object value in values)
+      {
+        try
+        {
+          JsonContract valueContract = contract.FinalItemContract ?? GetContractSafe(value);
+
+          if (ShouldWriteReference(value, null, valueContract, contract, member))
+          {
+            WriteReference(writer, value);
+          }
+          else
+          {
+            if (CheckForCircularReference(writer, value, null, valueContract, contract, member))
+            {
+              SerializeValue(writer, value, valueContract, null, contract, member);
+            }
+          }
+        }
+        catch (Exception ex)
+        {
+          if (IsErrorHandled(values.UnderlyingCollection, contract, index, writer.ContainerPath, ex))
+            HandleError(writer, initialDepth);
+          else
+            throw;
+        }
+        finally
+        {
+          index++;
+        }
+      }
+
+      writer.WriteEndArray();
+
+      if (hasWrittenMetadataObject)
+        writer.WriteEndObject();
+
+      _serializeStack.RemoveAt(_serializeStack.Count - 1);
+
+      contract.InvokeOnSerialized(values.UnderlyingCollection, Serializer.Context);
+    }
+
+    private void SerializeMultidimensionalArray(JsonWriter writer, Array values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
+    {
+      contract.InvokeOnSerializing(values, Serializer.Context);
+
+      _serializeStack.Add(values);
+
+      bool hasWrittenMetadataObject = WriteStartArray(writer, values, contract, member, collectionContract, containerProperty);
+
+      SerializeMultidimensionalArray(writer, values, contract, member, writer.Top, new int[0]);
+
+      if (hasWrittenMetadataObject)
+        writer.WriteEndObject();
+
+      _serializeStack.RemoveAt(_serializeStack.Count - 1);
+
+      contract.InvokeOnSerialized(values, Serializer.Context);
+    }
+
+    private void SerializeMultidimensionalArray(JsonWriter writer, Array values, JsonArrayContract contract, JsonProperty member, int initialDepth, int[] indices)
+    {
+      int dimension = indices.Length;
+      int[] newIndices = new int[dimension + 1];
+      for (int i = 0; i < dimension; i++)
+      {
+        newIndices[i] = indices[i];
+      }
+
+      writer.WriteStartArray();
+
+      for (int i = 0; i < values.GetLength(dimension); i++)
+      {
+        newIndices[dimension] = i;
+        bool isTopLevel = (newIndices.Length == values.Rank);
+
+        if (isTopLevel)
+        {
+          object value = values.GetValue(newIndices);
+
+          try
+          {
+            JsonContract valueContract = contract.FinalItemContract ?? GetContractSafe(value);
+
+            if (ShouldWriteReference(value, null, valueContract, contract, member))
+            {
+              WriteReference(writer, value);
+            }
+            else
+            {
+              if (CheckForCircularReference(writer, value, null, valueContract, contract, member))
+              {
+                SerializeValue(writer, value, valueContract, null, contract, member);
+              }
+            }
+          }
+          catch (Exception ex)
+          {
+            if (IsErrorHandled(values, contract, i, writer.ContainerPath, ex))
+              HandleError(writer, initialDepth + 1);
+            else
+              throw;
+          }
+        }
+        else
+        {
+          SerializeMultidimensionalArray(writer, values, contract, member, initialDepth + 1, newIndices);
+        }
+      }
+
+      writer.WriteEndArray();
+    }
+
+    private bool WriteStartArray(JsonWriter writer, object values, JsonArrayContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
+    {
+      bool isReference = ResolveIsReference(contract, member, containerContract, containerProperty) ?? HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Arrays);
+      bool includeTypeDetails = ShouldWriteType(TypeNameHandling.Arrays, contract, member, containerContract, containerProperty);
+      bool writeMetadataObject = isReference || includeTypeDetails;
+
+      if (writeMetadataObject)
+      {
+        writer.WriteStartObject();
+
+        if (isReference)
+        {
+          writer.WritePropertyName(JsonTypeReflector.IdPropertyName);
+          writer.WriteValue(Serializer.ReferenceResolver.GetReference(this, values));
+        }
+        if (includeTypeDetails)
+        {
+          WriteTypeProperty(writer, values.GetType());
+        }
+        writer.WritePropertyName(JsonTypeReflector.ArrayValuesPropertyName);
+      }
+
+      if (contract.ItemContract == null)
+        contract.ItemContract = Serializer.ContractResolver.ResolveContract(contract.CollectionItemType ?? typeof (object));
+
+      return writeMetadataObject;
+    }
+
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+#if !(NET20 || NET35)
+    [SecuritySafeCritical]
+#endif
+    private void SerializeISerializable(JsonWriter writer, ISerializable value, JsonISerializableContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
+    {
+      if (!JsonTypeReflector.FullyTrusted)
+      {
+        throw JsonSerializationException.Create(null, writer.ContainerPath, @"Type '{0}' implements ISerializable but cannot be serialized using the ISerializable interface because the current application is not fully trusted and ISerializable can expose secure data.
+To fix this error either change the environment to be fully trusted, change the application to not deserialize the type, add JsonObjectAttribute to the type or change the JsonSerializer setting ContractResolver to use a new DefaultContractResolver with IgnoreSerializableInterface set to true.".FormatWith(CultureInfo.InvariantCulture, value.GetType()), null);
+      }
+
+      contract.InvokeOnSerializing(value, Serializer.Context);
+      _serializeStack.Add(value);
+
+      WriteObjectStart(writer, value, contract, member, collectionContract, containerProperty);
+
+      SerializationInfo serializationInfo = new SerializationInfo(contract.UnderlyingType, new FormatterConverter());
+      value.GetObjectData(serializationInfo, Serializer.Context);
+
+      foreach (SerializationEntry serializationEntry in serializationInfo)
+      {
+        writer.WritePropertyName(serializationEntry.Name);
+        SerializeValue(writer, serializationEntry.Value, GetContractSafe(serializationEntry.Value), null, null, member);
+      }
+
+      writer.WriteEndObject();
+
+      _serializeStack.RemoveAt(_serializeStack.Count - 1);
+      contract.InvokeOnSerialized(value, Serializer.Context);
+    }
+#endif
+
+#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
+    private void SerializeDynamic(JsonWriter writer, IDynamicMetaObjectProvider value, JsonDynamicContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
+    {
+      contract.InvokeOnSerializing(value, Serializer.Context);
+      _serializeStack.Add(value);
+
+      WriteObjectStart(writer, value, contract, member, collectionContract, containerProperty);
+
+      int initialDepth = writer.Top;
+
+      foreach (JsonProperty property in contract.Properties)
+      {
+        // only write non-dynamic properties that have an explicit attribute
+        if (property.HasMemberAttribute)
+        {
+          try
+          {
+            object memberValue;
+            JsonContract memberContract;
+
+            if (!CalculatePropertyValues(writer, value, contract, member, property, out memberContract, out memberValue))
+              continue;
+
+            writer.WritePropertyName(property.PropertyName);
+            SerializeValue(writer, memberValue, memberContract, property, contract, member);
+          }
+          catch (Exception ex)
+          {
+            if (IsErrorHandled(value, contract, property.PropertyName, writer.ContainerPath, ex))
+              HandleError(writer, initialDepth);
+            else
+              throw;
+          }
+        }
+      }
+
+      foreach (string memberName in value.GetDynamicMemberNames())
+      {
+        object memberValue;
+        if (value.TryGetMember(memberName, out memberValue))
+        {
+          try
+          {
+            string resolvedPropertyName = (contract.PropertyNameResolver != null)
+                                            ? contract.PropertyNameResolver(memberName)
+                                            : memberName;
+
+            writer.WritePropertyName(resolvedPropertyName);
+            SerializeValue(writer, memberValue, GetContractSafe(memberValue), null, null, member);
+          }
+          catch (Exception ex)
+          {
+            if (IsErrorHandled(value, contract, memberName, writer.ContainerPath, ex))
+              HandleError(writer, initialDepth);
+            else
+              throw;
+          }
+        }
+      }
+
+      writer.WriteEndObject();
+
+      _serializeStack.RemoveAt(_serializeStack.Count - 1);
+      contract.InvokeOnSerialized(value, Serializer.Context);
+    }
+#endif
+
+    private bool ShouldWriteType(TypeNameHandling typeNameHandlingFlag, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
+    {
+      TypeNameHandling resolvedTypeNameHandling =
+        ((member != null) ? member.TypeNameHandling : null)
+        ?? ((containerProperty != null) ? containerProperty.ItemTypeNameHandling : null)
+        ?? ((containerContract != null) ? containerContract.ItemTypeNameHandling : null)
+        ?? Serializer.TypeNameHandling;
+
+      if (HasFlag(resolvedTypeNameHandling, typeNameHandlingFlag))
+        return true;
+
+      // instance type and the property's type's contract default type are different (no need to put the type in JSON because the type will be created by default)
+      if (HasFlag(resolvedTypeNameHandling, TypeNameHandling.Auto))
+      {
+        if (member != null)
+        {
+          if (contract.UnderlyingType != member.PropertyContract.CreatedType)
+            return true;
+        }
+        else if (containerContract != null && containerContract.ItemContract != null)
+        {
+          if (contract.UnderlyingType != containerContract.ItemContract.CreatedType)
+            return true;
+        }
+      }
+
+      return false;
+    }
+
+    private void SerializeDictionary(JsonWriter writer, IWrappedDictionary values, JsonDictionaryContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
+    {
+      contract.InvokeOnSerializing(values.UnderlyingDictionary, Serializer.Context);
+
+      _serializeStack.Add(values.UnderlyingDictionary);
+
+      WriteObjectStart(writer, values.UnderlyingDictionary, contract, member, collectionContract, containerProperty);
+
+      if (contract.ItemContract == null)
+        contract.ItemContract = Serializer.ContractResolver.ResolveContract(contract.DictionaryValueType ?? typeof(object));
+
+      int initialDepth = writer.Top;
+
+      // Mono Unity 3.0 fix
+      IWrappedDictionary d = values;
+
+      foreach (DictionaryEntry entry in d)
+      {
+        string propertyName = GetPropertyName(entry);
+
+        propertyName = (contract.PropertyNameResolver != null)
+                         ? contract.PropertyNameResolver(propertyName)
+                         : propertyName;
+
+        try
+        {
+          object value = entry.Value;
+          JsonContract valueContract = contract.FinalItemContract ?? GetContractSafe(value);
+
+          if (ShouldWriteReference(value, null, valueContract, contract, member))
+          {
+            writer.WritePropertyName(propertyName);
+            WriteReference(writer, value);
+          }
+          else
+          {
+            if (!CheckForCircularReference(writer, value, null, valueContract, contract, member))
+              continue;
+
+            writer.WritePropertyName(propertyName);
+
+            SerializeValue(writer, value, valueContract, null, contract, member);
+          }
+        }
+        catch (Exception ex)
+        {
+          if (IsErrorHandled(values.UnderlyingDictionary, contract, propertyName, writer.ContainerPath, ex))
+            HandleError(writer, initialDepth);
+          else
+            throw;
+        }
+      }
+
+      writer.WriteEndObject();
+
+      _serializeStack.RemoveAt(_serializeStack.Count - 1);
+
+      contract.InvokeOnSerialized(values.UnderlyingDictionary, Serializer.Context);
+    }
+
+    private string GetPropertyName(DictionaryEntry entry)
+    {
+      string propertyName;
+
+      if (ConvertUtils.IsConvertible(entry.Key))
+        return Convert.ToString(entry.Key, CultureInfo.InvariantCulture);
+      else if (TryConvertToString(entry.Key, entry.Key.GetType(), out propertyName))
+        return propertyName;
+      else
+        return entry.Key.ToString();
+    }
+
+    private void HandleError(JsonWriter writer, int initialDepth)
+    {
+      ClearErrorContext();
+
+      if (writer.WriteState == WriteState.Property)
+        writer.WriteNull();
+
+      while (writer.Top > initialDepth)
+      {
+        writer.WriteEnd();
+      }
+    }
+
+    private bool ShouldSerialize(JsonProperty property, object target)
+    {
+      if (property.ShouldSerialize == null)
+        return true;
+
+      return property.ShouldSerialize(target);
+    }
+
+    private bool IsSpecified(JsonProperty property, object target)
+    {
+      if (property.GetIsSpecified == null)
+        return true;
+
+      return property.GetIsSpecified(target);
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonSerializerProxy.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonSerializerProxy.cs
index 4463682..779f80a 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonSerializerProxy.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonSerializerProxy.cs
@@ -1,168 +1,219 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Runtime.Serialization.Formatters;
-using Newtonsoft.Json.Utilities;
-using System.Runtime.Serialization;
-
-namespace Newtonsoft.Json.Serialization
-{
-  internal class JsonSerializerProxy : JsonSerializer
-  {
-    private readonly JsonSerializerInternalReader _serializerReader;
-    private readonly JsonSerializerInternalWriter _serializerWriter;
-    private readonly JsonSerializer _serializer;
-
-    public override event EventHandler<ErrorEventArgs> Error
-    {
-      add { _serializer.Error += value; }
-      remove { _serializer.Error -= value; }
-    }
-
-    public override IReferenceResolver ReferenceResolver
-    {
-      get { return _serializer.ReferenceResolver; }
-      set { _serializer.ReferenceResolver = value; }
-    }
-
-    public override JsonConverterCollection Converters
-    {
-      get { return _serializer.Converters; }
-    }
-
-    public override DefaultValueHandling DefaultValueHandling
-    {
-      get { return _serializer.DefaultValueHandling; }
-      set { _serializer.DefaultValueHandling = value; }
-    }
-
-    public override IContractResolver ContractResolver
-    {
-      get { return _serializer.ContractResolver; }
-      set { _serializer.ContractResolver = value; }
-    }
-
-    public override MissingMemberHandling MissingMemberHandling
-    {
-      get { return _serializer.MissingMemberHandling; }
-      set { _serializer.MissingMemberHandling = value; }
-    }
-
-    public override NullValueHandling NullValueHandling
-    {
-      get { return _serializer.NullValueHandling; }
-      set { _serializer.NullValueHandling = value; }
-    }
-
-    public override ObjectCreationHandling ObjectCreationHandling
-    {
-      get { return _serializer.ObjectCreationHandling; }
-      set { _serializer.ObjectCreationHandling = value; }
-    }
-
-    public override ReferenceLoopHandling ReferenceLoopHandling
-    {
-      get { return _serializer.ReferenceLoopHandling; }
-      set { _serializer.ReferenceLoopHandling = value; }
-    }
-
-    public override PreserveReferencesHandling PreserveReferencesHandling
-    {
-      get { return _serializer.PreserveReferencesHandling; }
-      set { _serializer.PreserveReferencesHandling = value; }
-    }
-
-    public override TypeNameHandling TypeNameHandling
-    {
-      get { return _serializer.TypeNameHandling; }
-      set { _serializer.TypeNameHandling = value; }
-    }
-
-    public override FormatterAssemblyStyle TypeNameAssemblyFormat
-    {
-      get { return _serializer.TypeNameAssemblyFormat; }
-      set { _serializer.TypeNameAssemblyFormat = value; }
-    }
-
-    public override ConstructorHandling ConstructorHandling
-    {
-      get { return _serializer.ConstructorHandling; }
-      set { _serializer.ConstructorHandling = value; }
-    }
-
-    public override SerializationBinder Binder
-    {
-      get { return _serializer.Binder; }
-      set { _serializer.Binder = value; }
-    }
-
-    public override StreamingContext Context
-    {
-      get { return _serializer.Context; }
-      set { _serializer.Context = value; }
-    }
-
-    public JsonSerializerProxy(JsonSerializerInternalReader serializerReader)
-    {
-      ValidationUtils.ArgumentNotNull(serializerReader, "serializerReader");
-
-      _serializerReader = serializerReader;
-      _serializer = serializerReader.Serializer;
-    }
-
-    public JsonSerializerProxy(JsonSerializerInternalWriter serializerWriter)
-    {
-      ValidationUtils.ArgumentNotNull(serializerWriter, "serializerWriter");
-
-      _serializerWriter = serializerWriter;
-      _serializer = serializerWriter.Serializer;
-    }
-
-    internal override object DeserializeInternal(JsonReader reader, Type objectType)
-    {
-      if (_serializerReader != null)
-        return _serializerReader.Deserialize(reader, objectType);
-      else
-        return _serializer.Deserialize(reader, objectType);
-    }
-
-    internal override void PopulateInternal(JsonReader reader, object target)
-    {
-      if (_serializerReader != null)
-        _serializerReader.Populate(reader, target);
-      else
-        _serializer.Populate(reader, target);
-    }
-
-    internal override void SerializeInternal(JsonWriter jsonWriter, object value)
-    {
-      if (_serializerWriter != null)
-        _serializerWriter.Serialize(jsonWriter, value);
-      else
-        _serializer.Serialize(jsonWriter, value);
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Globalization;
+using System.Runtime.Serialization.Formatters;
+using Newtonsoft.Json.Utilities;
+using System.Runtime.Serialization;
+
+namespace Newtonsoft.Json.Serialization
+{
+  internal class JsonSerializerProxy : JsonSerializer
+  {
+    private readonly JsonSerializerInternalReader _serializerReader;
+    private readonly JsonSerializerInternalWriter _serializerWriter;
+    private readonly JsonSerializer _serializer;
+
+    public override event EventHandler<ErrorEventArgs> Error
+    {
+      add { _serializer.Error += value; }
+      remove { _serializer.Error -= value; }
+    }
+
+    public override IReferenceResolver ReferenceResolver
+    {
+      get { return _serializer.ReferenceResolver; }
+      set { _serializer.ReferenceResolver = value; }
+    }
+
+    public override JsonConverterCollection Converters
+    {
+      get { return _serializer.Converters; }
+    }
+
+    public override DefaultValueHandling DefaultValueHandling
+    {
+      get { return _serializer.DefaultValueHandling; }
+      set { _serializer.DefaultValueHandling = value; }
+    }
+
+    public override IContractResolver ContractResolver
+    {
+      get { return _serializer.ContractResolver; }
+      set { _serializer.ContractResolver = value; }
+    }
+
+    public override MissingMemberHandling MissingMemberHandling
+    {
+      get { return _serializer.MissingMemberHandling; }
+      set { _serializer.MissingMemberHandling = value; }
+    }
+
+    public override NullValueHandling NullValueHandling
+    {
+      get { return _serializer.NullValueHandling; }
+      set { _serializer.NullValueHandling = value; }
+    }
+
+    public override ObjectCreationHandling ObjectCreationHandling
+    {
+      get { return _serializer.ObjectCreationHandling; }
+      set { _serializer.ObjectCreationHandling = value; }
+    }
+
+    public override ReferenceLoopHandling ReferenceLoopHandling
+    {
+      get { return _serializer.ReferenceLoopHandling; }
+      set { _serializer.ReferenceLoopHandling = value; }
+    }
+
+    public override PreserveReferencesHandling PreserveReferencesHandling
+    {
+      get { return _serializer.PreserveReferencesHandling; }
+      set { _serializer.PreserveReferencesHandling = value; }
+    }
+
+    public override TypeNameHandling TypeNameHandling
+    {
+      get { return _serializer.TypeNameHandling; }
+      set { _serializer.TypeNameHandling = value; }
+    }
+
+    public override FormatterAssemblyStyle TypeNameAssemblyFormat
+    {
+      get { return _serializer.TypeNameAssemblyFormat; }
+      set { _serializer.TypeNameAssemblyFormat = value; }
+    }
+
+    public override ConstructorHandling ConstructorHandling
+    {
+      get { return _serializer.ConstructorHandling; }
+      set { _serializer.ConstructorHandling = value; }
+    }
+
+    public override SerializationBinder Binder
+    {
+      get { return _serializer.Binder; }
+      set { _serializer.Binder = value; }
+    }
+
+    public override StreamingContext Context
+    {
+      get { return _serializer.Context; }
+      set { _serializer.Context = value; }
+    }
+
+    public override Formatting Formatting
+    {
+      get { return _serializer.Formatting; }
+      set { _serializer.Formatting = value; }
+    }
+
+    public override DateFormatHandling DateFormatHandling
+    {
+      get { return _serializer.DateFormatHandling; }
+      set { _serializer.DateFormatHandling = value; }
+    }
+
+    public override DateTimeZoneHandling DateTimeZoneHandling
+    {
+      get { return _serializer.DateTimeZoneHandling; }
+      set { _serializer.DateTimeZoneHandling = value; }
+    }
+
+    public override DateParseHandling DateParseHandling
+    {
+      get { return _serializer.DateParseHandling; }
+      set { _serializer.DateParseHandling = value; }
+    }
+
+    public override CultureInfo Culture
+    {
+      get { return _serializer.Culture; }
+      set { _serializer.Culture = value; }
+    }
+
+    public override int? MaxDepth
+    {
+      get { return _serializer.MaxDepth; }
+      set { _serializer.MaxDepth = value; }
+    }
+
+    public override bool CheckAdditionalContent
+    {
+      get { return _serializer.CheckAdditionalContent; }
+      set { _serializer.CheckAdditionalContent = value; }
+    }
+
+    internal JsonSerializerInternalBase GetInternalSerializer()
+    {
+      if (_serializerReader != null)
+        return _serializerReader;
+      else
+        return _serializerWriter;
+    }
+
+    public JsonSerializerProxy(JsonSerializerInternalReader serializerReader)
+    {
+      ValidationUtils.ArgumentNotNull(serializerReader, "serializerReader");
+
+      _serializerReader = serializerReader;
+      _serializer = serializerReader.Serializer;
+    }
+
+    public JsonSerializerProxy(JsonSerializerInternalWriter serializerWriter)
+    {
+      ValidationUtils.ArgumentNotNull(serializerWriter, "serializerWriter");
+
+      _serializerWriter = serializerWriter;
+      _serializer = serializerWriter.Serializer;
+    }
+
+    internal override object DeserializeInternal(JsonReader reader, Type objectType)
+    {
+      if (_serializerReader != null)
+        return _serializerReader.Deserialize(reader, objectType, false);
+      else
+        return _serializer.Deserialize(reader, objectType);
+    }
+
+    internal override void PopulateInternal(JsonReader reader, object target)
+    {
+      if (_serializerReader != null)
+        _serializerReader.Populate(reader, target);
+      else
+        _serializer.Populate(reader, target);
+    }
+
+    internal override void SerializeInternal(JsonWriter jsonWriter, object value)
+    {
+      if (_serializerWriter != null)
+        _serializerWriter.Serialize(jsonWriter, value);
+      else
+        _serializer.Serialize(jsonWriter, value);
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonStringContract.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonStringContract.cs
index 1f3f47c..3668ab4 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonStringContract.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonStringContract.cs
@@ -1,47 +1,45 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Newtonsoft.Json.Serialization
-{
-  /// <summary>
-  /// Contract details for a <see cref="Type"/> used by the <see cref="JsonSerializer"/>.
-  /// </summary>
-  public class JsonStringContract : JsonContract
-  {
-    /// <summary>
-    /// Initializes a new instance of the <see cref="JsonStringContract"/> class.
-    /// </summary>
-    /// <param name="underlyingType">The underlying type for the contract.</param>
-    public JsonStringContract(Type underlyingType)
-      : base(underlyingType)
-    {
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Contract details for a <see cref="Type"/> used by the <see cref="JsonSerializer"/>.
+  /// </summary>
+  public class JsonStringContract : JsonPrimitiveContract
+  {
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonStringContract"/> class.
+    /// </summary>
+    /// <param name="underlyingType">The underlying type for the contract.</param>
+    public JsonStringContract(Type underlyingType)
+      : base(underlyingType)
+    {
+      ContractType = JsonContractType.String;
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs
index e1d7261..795db90 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs
@@ -1,300 +1,460 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.ComponentModel;
-using System.Globalization;
-using System.Linq;
-using System.Reflection;
-using System.Runtime.Serialization;
-using System.Security.Permissions;
-using Newtonsoft.Json.Utilities;
-
-namespace Newtonsoft.Json.Serialization
-{
-#if !SILVERLIGHT && !PocketPC && !NET20
-  internal interface IMetadataTypeAttribute
-  {
-    Type MetadataClassType { get; }
-  }
-#endif
-
-  internal static class JsonTypeReflector
-  {
-    public const string IdPropertyName = "$id";
-    public const string RefPropertyName = "$ref";
-    public const string TypePropertyName = "$type";
-    public const string ArrayValuesPropertyName = "$values";
-
-    public const string ShouldSerializePrefix = "ShouldSerialize";
-
-    private static readonly ThreadSafeStore<ICustomAttributeProvider, Type> JsonConverterTypeCache = new ThreadSafeStore<ICustomAttributeProvider, Type>(GetJsonConverterTypeFromAttribute);
-#if !SILVERLIGHT && !PocketPC && !NET20
-    private static readonly ThreadSafeStore<Type, Type> AssociatedMetadataTypesCache = new ThreadSafeStore<Type, Type>(GetAssociateMetadataTypeFromAttribute);
-
-    private const string MetadataTypeAttributeTypeName =
-      "System.ComponentModel.DataAnnotations.MetadataTypeAttribute, System.ComponentModel.DataAnnotations, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";
-    private static Type _cachedMetadataTypeAttributeType;
-#endif
-#if SILVERLIGHT
-    private static readonly ThreadSafeStore<ICustomAttributeProvider, Type> TypeConverterTypeCache = new ThreadSafeStore<ICustomAttributeProvider, Type>(GetTypeConverterTypeFromAttribute);
-
-    private static Type GetTypeConverterTypeFromAttribute(ICustomAttributeProvider attributeProvider)
-    {
-      TypeConverterAttribute converterAttribute = GetAttribute<TypeConverterAttribute>(attributeProvider);
-      if (converterAttribute == null)
-        return null;
-
-      return Type.GetType(converterAttribute.ConverterTypeName);
-    }
-
-    private static Type GetTypeConverterType(ICustomAttributeProvider attributeProvider)
-    {
-      return TypeConverterTypeCache.Get(attributeProvider);
-    }
-#endif
-
-    public static JsonContainerAttribute GetJsonContainerAttribute(Type type)
-    {
-      return CachedAttributeGetter<JsonContainerAttribute>.GetAttribute(type);
-    }
-
-    public static JsonObjectAttribute GetJsonObjectAttribute(Type type)
-    {
-      return GetJsonContainerAttribute(type) as JsonObjectAttribute;
-    }
-
-    public static JsonArrayAttribute GetJsonArrayAttribute(Type type)
-    {
-      return GetJsonContainerAttribute(type) as JsonArrayAttribute;
-    }
-
-#if !PocketPC && !NET20
-    public static DataContractAttribute GetDataContractAttribute(Type type)
-    {
-      return CachedAttributeGetter<DataContractAttribute>.GetAttribute(type);
-    }
-#endif
-
-    public static MemberSerialization GetObjectMemberSerialization(Type objectType)
-    {
-      JsonObjectAttribute objectAttribute = GetJsonObjectAttribute(objectType);
-
-      if (objectAttribute == null)
-      {
-#if !PocketPC && !NET20
-        DataContractAttribute dataContractAttribute = GetDataContractAttribute(objectType);
-
-        if (dataContractAttribute != null)
-          return MemberSerialization.OptIn;
-#endif
-
-        return MemberSerialization.OptOut;
-      }
-
-      return objectAttribute.MemberSerialization;
-    }
-
-    private static Type GetJsonConverterType(ICustomAttributeProvider attributeProvider)
-    {
-      return JsonConverterTypeCache.Get(attributeProvider);
-    }
-
-    private static Type GetJsonConverterTypeFromAttribute(ICustomAttributeProvider attributeProvider)
-    {
-      JsonConverterAttribute converterAttribute = GetAttribute<JsonConverterAttribute>(attributeProvider);
-      return (converterAttribute != null)
-        ? converterAttribute.ConverterType
-        : null;
-    }
-
-    public static JsonConverter GetJsonConverter(ICustomAttributeProvider attributeProvider, Type targetConvertedType)
-    {
-      Type converterType = GetJsonConverterType(attributeProvider);
-
-      if (converterType != null)
-      {
-        JsonConverter memberConverter = JsonConverterAttribute.CreateJsonConverterInstance(converterType);
-
-        if (!memberConverter.CanConvert(targetConvertedType))
-          throw new JsonSerializationException("JsonConverter {0} on {1} is not compatible with member type {2}.".FormatWith(CultureInfo.InvariantCulture, memberConverter.GetType().Name, attributeProvider, targetConvertedType.Name));
-
-        return memberConverter;
-      }
-
-      return null;
-    }
-
-#if !PocketPC
-    public static TypeConverter GetTypeConverter(Type type)
-    {
-#if !SILVERLIGHT
-      return TypeDescriptor.GetConverter(type);
-#else
-      Type converterType = GetTypeConverterType(type);
-
-      if (converterType != null)
-        return (TypeConverter)ReflectionUtils.CreateInstance(converterType);
-
-      return null;
-#endif
-    }
-#endif
-
-#if !SILVERLIGHT && !PocketPC && !NET20
-    private static Type GetAssociatedMetadataType(Type type)
-    {
-      return AssociatedMetadataTypesCache.Get(type);
-    }
-
-    private static Type GetAssociateMetadataTypeFromAttribute(Type type)
-    {
-      Type metadataTypeAttributeType = GetMetadataTypeAttributeType();
-      if (metadataTypeAttributeType == null)
-        return null;
-
-      object attribute = type.GetCustomAttributes(metadataTypeAttributeType, true).SingleOrDefault();
-      if (attribute == null)
-        return null;
-
-      IMetadataTypeAttribute metadataTypeAttribute = (DynamicCodeGeneration)
-                                                       ? DynamicWrapper.CreateWrapper<IMetadataTypeAttribute>(attribute)
-                                                       : new LateBoundMetadataTypeAttribute(attribute);
-
-      return metadataTypeAttribute.MetadataClassType;
-    }
-
-    private static Type GetMetadataTypeAttributeType()
-    {
-      // always attempt to get the metadata type attribute type
-      // the assembly may have been loaded since last time
-      if (_cachedMetadataTypeAttributeType == null)
-      {
-        Type metadataTypeAttributeType = Type.GetType(MetadataTypeAttributeTypeName);
-
-        if (metadataTypeAttributeType != null)
-          _cachedMetadataTypeAttributeType = metadataTypeAttributeType;
-        else
-          return null;
-      }
-      
-      return _cachedMetadataTypeAttributeType;
-    }
-
-    private static T GetAttribute<T>(Type type) where T : Attribute
-    {
-      Type metadataType = GetAssociatedMetadataType(type);
-      if (metadataType != null)
-      {
-        T attribute = ReflectionUtils.GetAttribute<T>(metadataType, true);
-        if (attribute != null)
-          return attribute;
-      }
-
-      return ReflectionUtils.GetAttribute<T>(type, true);
-    }
-
-    private static T GetAttribute<T>(MemberInfo memberInfo) where T : Attribute
-    {
-      Type metadataType = GetAssociatedMetadataType(memberInfo.DeclaringType);
-      if (metadataType != null)
-      {
-        MemberInfo metadataTypeMemberInfo = metadataType.GetMember(memberInfo.Name,
-          memberInfo.MemberType,
-          BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance).SingleOrDefault();
-
-        if (metadataTypeMemberInfo != null)
-        {
-          T attribute = ReflectionUtils.GetAttribute<T>(metadataTypeMemberInfo, true);
-          if (attribute != null)
-            return attribute;
-        }
-      }
-
-      return ReflectionUtils.GetAttribute<T>(memberInfo, true);
-    }
-
-    public static T GetAttribute<T>(ICustomAttributeProvider attributeProvider) where T : Attribute
-    {
-      Type type = attributeProvider as Type;
-      if (type != null)
-        return GetAttribute<T>(type);
-
-      MemberInfo memberInfo = attributeProvider as MemberInfo;
-      if (memberInfo != null)
-        return GetAttribute<T>(memberInfo);
-
-      return ReflectionUtils.GetAttribute<T>(attributeProvider, true);
-    }
-#else
-    public static T GetAttribute<T>(ICustomAttributeProvider attributeProvider) where T : Attribute
-    {
-      return ReflectionUtils.GetAttribute<T>(attributeProvider, true);
-    }
-#endif
-
-    private static bool? _dynamicCodeGeneration;
-
-    public static bool DynamicCodeGeneration
-    {
-      get
-      {
-        if (_dynamicCodeGeneration == null)
-        {
-#if !PocketPC && !SILVERLIGHT
-          try
-          {
-            new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand();
-            new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess).Demand();
-            new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
-            _dynamicCodeGeneration = true;
-          }
-          catch (Exception)
-          {
-            _dynamicCodeGeneration = false;
-          }
-#else
-          _dynamicCodeGeneration = false;
-#endif
-        }
-
-        return _dynamicCodeGeneration.Value;
-      }
-    }
-
-    public static ReflectionDelegateFactory ReflectionDelegateFactory
-    {
-      get
-      {
-#if !PocketPC && !SILVERLIGHT
-        if (DynamicCodeGeneration)
-          return DynamicReflectionDelegateFactory.Instance;
-#endif
-
-        return LateBoundReflectionDelegateFactory.Instance;
-      }
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.ComponentModel;
+using System.Globalization;
+using System.Reflection;
+#if !(NETFX_CORE || PORTABLE)
+using System.Security.Permissions;
+#endif
+using Newtonsoft.Json.Utilities;
+#if NETFX_CORE || PORTABLE
+using ICustomAttributeProvider = Newtonsoft.Json.Utilities.CustomAttributeProvider;
+#endif
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#else
+using System.Linq;
+#endif
+using System.Runtime.Serialization;
+
+namespace Newtonsoft.Json.Serialization
+{
+#if !SILVERLIGHT && !PocketPC && !NET20 && !NETFX_CORE
+  internal interface IMetadataTypeAttribute
+  {
+    Type MetadataClassType { get; }
+  }
+#endif
+
+  internal static class JsonTypeReflector
+  {
+    public const string IdPropertyName = "$id";
+    public const string RefPropertyName = "$ref";
+    public const string TypePropertyName = "$type";
+    public const string ValuePropertyName = "$value";
+    public const string ArrayValuesPropertyName = "$values";
+
+    public const string ShouldSerializePrefix = "ShouldSerialize";
+    public const string SpecifiedPostfix = "Specified";
+
+    private static readonly ThreadSafeStore<ICustomAttributeProvider, Type> JsonConverterTypeCache = new ThreadSafeStore<ICustomAttributeProvider, Type>(GetJsonConverterTypeFromAttribute);
+#if !(SILVERLIGHT || NET20 || NETFX_CORE || PORTABLE)
+    private static readonly ThreadSafeStore<Type, Type> AssociatedMetadataTypesCache = new ThreadSafeStore<Type, Type>(GetAssociateMetadataTypeFromAttribute);
+
+    private const string MetadataTypeAttributeTypeName =
+      "System.ComponentModel.DataAnnotations.MetadataTypeAttribute, System.ComponentModel.DataAnnotations, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";
+    private static Type _cachedMetadataTypeAttributeType;
+#endif
+#if SILVERLIGHT
+    private static readonly ThreadSafeStore<ICustomAttributeProvider, Type> TypeConverterTypeCache = new ThreadSafeStore<ICustomAttributeProvider, Type>(GetTypeConverterTypeFromAttribute);
+
+    private static Type GetTypeConverterTypeFromAttribute(ICustomAttributeProvider attributeProvider)
+    {
+      TypeConverterAttribute converterAttribute = GetAttribute<TypeConverterAttribute>(attributeProvider);
+      if (converterAttribute == null)
+        return null;
+
+      return Type.GetType(converterAttribute.ConverterTypeName);
+    }
+
+    private static Type GetTypeConverterType(ICustomAttributeProvider attributeProvider)
+    {
+      return TypeConverterTypeCache.Get(attributeProvider);
+    }
+#endif
+
+    public static JsonContainerAttribute GetJsonContainerAttribute(Type type)
+    {
+      return CachedAttributeGetter<JsonContainerAttribute>.GetAttribute(type.GetCustomAttributeProvider());
+    }
+
+    public static JsonObjectAttribute GetJsonObjectAttribute(Type type)
+    {
+      return GetJsonContainerAttribute(type) as JsonObjectAttribute;
+    }
+
+    public static JsonArrayAttribute GetJsonArrayAttribute(Type type)
+    {
+      return GetJsonContainerAttribute(type) as JsonArrayAttribute;
+    }
+
+    public static JsonDictionaryAttribute GetJsonDictionaryAttribute(Type type)
+    {
+      return GetJsonContainerAttribute(type) as JsonDictionaryAttribute;
+    }
+
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+    public static SerializableAttribute GetSerializableAttribute(Type type)
+    {
+      return CachedAttributeGetter<SerializableAttribute>.GetAttribute(type.GetCustomAttributeProvider());
+    }
+#endif
+
+#if !PocketPC && !NET20
+    public static DataContractAttribute GetDataContractAttribute(Type type)
+    {
+      // DataContractAttribute does not have inheritance
+      Type currentType = type;
+
+      while (currentType != null)
+      {
+        DataContractAttribute result = CachedAttributeGetter<DataContractAttribute>.GetAttribute(currentType.GetCustomAttributeProvider());
+        if (result != null)
+          return result;
+
+        currentType = currentType.BaseType();
+      }
+
+      return null;
+    }
+
+    public static DataMemberAttribute GetDataMemberAttribute(MemberInfo memberInfo)
+    {
+      // DataMemberAttribute does not have inheritance
+
+      // can't override a field
+      if (memberInfo.MemberType() == MemberTypes.Field)
+        return CachedAttributeGetter<DataMemberAttribute>.GetAttribute(memberInfo.GetCustomAttributeProvider());
+
+      // search property and then search base properties if nothing is returned and the property is virtual
+      PropertyInfo propertyInfo = (PropertyInfo)memberInfo;
+      DataMemberAttribute result = CachedAttributeGetter<DataMemberAttribute>.GetAttribute(propertyInfo.GetCustomAttributeProvider());
+      if (result == null)
+      {
+        if (propertyInfo.IsVirtual())
+        {
+          Type currentType = propertyInfo.DeclaringType;
+
+          while (result == null && currentType != null)
+          {
+            PropertyInfo baseProperty = (PropertyInfo)ReflectionUtils.GetMemberInfoFromType(currentType, propertyInfo);
+            if (baseProperty != null && baseProperty.IsVirtual())
+              result = CachedAttributeGetter<DataMemberAttribute>.GetAttribute(baseProperty.GetCustomAttributeProvider());
+
+            currentType = currentType.BaseType();
+          }
+        }
+      }
+
+      return result;
+    }
+#endif
+
+    public static MemberSerialization GetObjectMemberSerialization(Type objectType, bool ignoreSerializableAttribute)
+    {
+      JsonObjectAttribute objectAttribute = GetJsonObjectAttribute(objectType);
+      if (objectAttribute != null)
+        return objectAttribute.MemberSerialization;
+
+#if !PocketPC && !NET20
+      DataContractAttribute dataContractAttribute = GetDataContractAttribute(objectType);
+      if (dataContractAttribute != null)
+        return MemberSerialization.OptIn;
+#endif
+
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+      if (!ignoreSerializableAttribute)
+      {
+        SerializableAttribute serializableAttribute = GetSerializableAttribute(objectType);
+        if (serializableAttribute != null)
+          return MemberSerialization.Fields;
+      }
+#endif
+
+      // the default
+      return MemberSerialization.OptOut;
+    }
+
+    private static Type GetJsonConverterType(ICustomAttributeProvider attributeProvider)
+    {
+      return JsonConverterTypeCache.Get(attributeProvider);
+    }
+
+    private static Type GetJsonConverterTypeFromAttribute(ICustomAttributeProvider attributeProvider)
+    {
+      JsonConverterAttribute converterAttribute = GetAttribute<JsonConverterAttribute>(attributeProvider);
+      return (converterAttribute != null)
+        ? converterAttribute.ConverterType
+        : null;
+    }
+
+    public static JsonConverter GetJsonConverter(ICustomAttributeProvider attributeProvider, Type targetConvertedType)
+    {
+      object provider = null;
+#if !(NETFX_CORE || PORTABLE)
+      provider = attributeProvider as MemberInfo;
+#else
+      provider = attributeProvider.UnderlyingObject;
+#endif
+
+      Type converterType = GetJsonConverterType(attributeProvider);
+
+      if (converterType != null)
+      {
+        JsonConverter memberConverter = JsonConverterAttribute.CreateJsonConverterInstance(converterType);
+
+        return memberConverter;
+      }
+
+      return null;
+    }
+
+#if !(NETFX_CORE || PORTABLE)
+#if !PocketPC
+    public static TypeConverter GetTypeConverter(Type type)
+    {
+#if !SILVERLIGHT
+      return TypeDescriptor.GetConverter(type);
+#else
+      Type converterType = GetTypeConverterType(type);
+
+      if (converterType != null)
+        return (TypeConverter)ReflectionUtils.CreateInstance(converterType);
+
+      return null;
+#endif
+#endif
+    }
+#endif
+
+#if !(SILVERLIGHT || NET20 || NETFX_CORE || PORTABLE)
+    private static Type GetAssociatedMetadataType(Type type)
+    {
+      return AssociatedMetadataTypesCache.Get(type);
+    }
+
+    private static Type GetAssociateMetadataTypeFromAttribute(Type type)
+    {
+      Type metadataTypeAttributeType = GetMetadataTypeAttributeType();
+      if (metadataTypeAttributeType == null)
+        return null;
+
+      object attribute = type.GetCustomAttributes(metadataTypeAttributeType, true).SingleOrDefault();
+      if (attribute == null)
+        return null;
+
+      IMetadataTypeAttribute metadataTypeAttribute = (DynamicCodeGeneration)
+                                                       ? DynamicWrapper.CreateWrapper<IMetadataTypeAttribute>(attribute)
+                                                       : new LateBoundMetadataTypeAttribute(attribute);
+
+      return metadataTypeAttribute.MetadataClassType;
+    }
+
+    private static Type GetMetadataTypeAttributeType()
+    {
+      // always attempt to get the metadata type attribute type
+      // the assembly may have been loaded since last time
+      if (_cachedMetadataTypeAttributeType == null)
+      {
+        Type metadataTypeAttributeType = Type.GetType(MetadataTypeAttributeTypeName);
+
+        if (metadataTypeAttributeType != null)
+          _cachedMetadataTypeAttributeType = metadataTypeAttributeType;
+        else
+          return null;
+      }
+
+      return _cachedMetadataTypeAttributeType;
+    }
+#endif
+
+    private static T GetAttribute<T>(Type type) where T : Attribute
+    {
+      T attribute;
+
+#if !(SILVERLIGHT || NET20 || NETFX_CORE || PORTABLE)
+      Type metadataType = GetAssociatedMetadataType(type);
+      if (metadataType != null)
+      {
+        attribute = ReflectionUtils.GetAttribute<T>(metadataType, true);
+        if (attribute != null)
+          return attribute;
+      }
+#endif
+
+      attribute = ReflectionUtils.GetAttribute<T>(type.GetCustomAttributeProvider(), true);
+      if (attribute != null)
+        return attribute;
+
+      foreach (Type typeInterface in type.GetInterfaces())
+      {
+        attribute = ReflectionUtils.GetAttribute<T>(typeInterface.GetCustomAttributeProvider(), true);
+        if (attribute != null)
+          return attribute;
+      }
+
+      return null;
+    }
+
+    private static T GetAttribute<T>(MemberInfo memberInfo) where T : Attribute
+    {
+      T attribute;
+
+#if !(SILVERLIGHT || NET20 || NETFX_CORE || PORTABLE)
+      Type metadataType = GetAssociatedMetadataType(memberInfo.DeclaringType);
+      if (metadataType != null)
+      {
+        MemberInfo metadataTypeMemberInfo = ReflectionUtils.GetMemberInfoFromType(metadataType, memberInfo);
+
+        if (metadataTypeMemberInfo != null)
+        {
+          attribute = ReflectionUtils.GetAttribute<T>(metadataTypeMemberInfo, true);
+          if (attribute != null)
+            return attribute;
+        }
+      }
+#endif
+
+      attribute = ReflectionUtils.GetAttribute<T>(memberInfo.GetCustomAttributeProvider(), true);
+      if (attribute != null)
+        return attribute;
+
+      if (memberInfo.DeclaringType != null)
+      {
+        foreach (Type typeInterface in memberInfo.DeclaringType.GetInterfaces())
+        {
+          MemberInfo interfaceTypeMemberInfo = ReflectionUtils.GetMemberInfoFromType(typeInterface, memberInfo);
+
+          if (interfaceTypeMemberInfo != null)
+          {
+            attribute = ReflectionUtils.GetAttribute<T>(interfaceTypeMemberInfo.GetCustomAttributeProvider(), true);
+            if (attribute != null)
+              return attribute;
+          }
+        }
+      }
+
+      return null;
+    }
+
+    public static T GetAttribute<T>(ICustomAttributeProvider attributeProvider) where T : Attribute
+    {
+      object provider = null;
+#if !(NETFX_CORE || PORTABLE)
+      provider = attributeProvider;
+#else
+      provider = attributeProvider.UnderlyingObject;
+#endif
+
+      Type type = provider as Type;
+      if (type != null)
+        return GetAttribute<T>(type);
+
+      MemberInfo memberInfo = provider as MemberInfo;
+      if (memberInfo != null)
+        return GetAttribute<T>(memberInfo);
+
+      return ReflectionUtils.GetAttribute<T>(attributeProvider, true);
+    }
+
+    private static bool? _dynamicCodeGeneration;
+    private static bool? _fullyTrusted;
+
+#if DEBUG
+    internal static void SetFullyTrusted(bool fullyTrusted)
+    {
+      _fullyTrusted = fullyTrusted;
+    }
+
+    internal static void SetDynamicCodeGeneration(bool dynamicCodeGeneration)
+    {
+      _dynamicCodeGeneration = dynamicCodeGeneration;
+    }
+#endif
+
+    public static bool DynamicCodeGeneration
+    {
+      get
+      {
+        if (_dynamicCodeGeneration == null)
+        {
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+          try
+          {
+            new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand();
+            new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess).Demand();
+            new SecurityPermission(SecurityPermissionFlag.SkipVerification).Demand();
+            new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
+            new SecurityPermission(PermissionState.Unrestricted).Demand();
+            _dynamicCodeGeneration = true;
+          }
+          catch (Exception)
+          {
+            _dynamicCodeGeneration = false;
+          }
+#else
+          _dynamicCodeGeneration = false;
+#endif
+        }
+
+        return _dynamicCodeGeneration.Value;
+      }
+    }
+
+    public static bool FullyTrusted
+    {
+      get
+      {
+        if (_fullyTrusted == null)
+        {
+#if (NETFX_CORE || SILVERLIGHT || PORTABLE)
+          _fullyTrusted = false;
+#elif !(NET20 || NET35)
+          AppDomain appDomain = AppDomain.CurrentDomain;
+
+          _fullyTrusted = appDomain.IsHomogenous && appDomain.IsFullyTrusted;
+#else
+          try
+          {
+            new SecurityPermission(PermissionState.Unrestricted).Demand();
+            _fullyTrusted = true;
+          }
+          catch (Exception)
+          {
+            _fullyTrusted = false;
+          }
+#endif
+        }
+
+        return _fullyTrusted.Value;
+      }
+    }
+
+    public static ReflectionDelegateFactory ReflectionDelegateFactory
+    {
+      get
+      {
+#if !(SILVERLIGHT || PORTABLE || NETFX_CORE)
+        if (DynamicCodeGeneration)
+          return DynamicReflectionDelegateFactory.Instance;
+#endif
+
+        return LateBoundReflectionDelegateFactory.Instance;
+      }
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/LateBoundMetadataTypeAttribute.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/LateBoundMetadataTypeAttribute.cs
index 815f20b..ec594a0 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/LateBoundMetadataTypeAttribute.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/LateBoundMetadataTypeAttribute.cs
@@ -1,59 +1,59 @@
-#region License
-// 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.
-#endregion
-
-#if !SILVERLIGHT && !PocketPC && !NET20
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Newtonsoft.Json.Utilities;
-using System.Reflection;
-
-namespace Newtonsoft.Json.Serialization
-{
-  internal class LateBoundMetadataTypeAttribute : IMetadataTypeAttribute
-  {
-    private static PropertyInfo _metadataClassTypeProperty;
-
-    private readonly object _attribute;
-
-    public LateBoundMetadataTypeAttribute(object attribute)
-    {
-      _attribute = attribute;
-    }
-
-    public Type MetadataClassType
-    {
-      get
-      {
-        if (_metadataClassTypeProperty == null)
-          _metadataClassTypeProperty = _attribute.GetType().GetProperty("MetadataClassType");
-
-        return (Type)ReflectionUtils.GetMemberValue(_metadataClassTypeProperty, _attribute);
-      }
-    }
-  }
-}
+#region License
+// 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.
+#endregion
+
+#if !SILVERLIGHT && !PocketPC && !NET20 && !NETFX_CORE
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Utilities;
+using System.Reflection;
+
+namespace Newtonsoft.Json.Serialization
+{
+  internal class LateBoundMetadataTypeAttribute : IMetadataTypeAttribute
+  {
+    private static PropertyInfo _metadataClassTypeProperty;
+
+    private readonly object _attribute;
+
+    public LateBoundMetadataTypeAttribute(object attribute)
+    {
+      _attribute = attribute;
+    }
+
+    public Type MetadataClassType
+    {
+      get
+      {
+        if (_metadataClassTypeProperty == null)
+          _metadataClassTypeProperty = _attribute.GetType().GetProperty("MetadataClassType");
+
+        return (Type)ReflectionUtils.GetMemberValue(_metadataClassTypeProperty, _attribute);
+      }
+    }
+  }
+}
 #endif
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/ObjectConstructor.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/ObjectConstructor.cs
index 094356b..b731707 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/ObjectConstructor.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/ObjectConstructor.cs
@@ -1,32 +1,33 @@
-#region License
-// 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.
-#endregion
-
-namespace Newtonsoft.Json.Serialization
-{
-  /// <summary>
-  /// Represents a method that constructs an object.
-  /// </summary>
-  public delegate object ObjectConstructor<T>(params object[] args);
+#region License
+// 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.
+#endregion
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Represents a method that constructs an object.
+  /// </summary>
+  /// <typeparam name="T">The object type to create.</typeparam>
+  public delegate object ObjectConstructor<T>(params object[] args);
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/OnErrorAttribute.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/OnErrorAttribute.cs
index 3948fa3..73e2df0 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/OnErrorAttribute.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/OnErrorAttribute.cs
@@ -1,37 +1,37 @@
-#region License
-// 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.
-#endregion
-
-using System;
-
-namespace Newtonsoft.Json.Serialization
-{
-  /// <summary>
-  /// When applied to a method, specifies that the method is called when an error occurs serializing an object.
-  /// </summary>
-  [AttributeUsage(AttributeTargets.Method, Inherited = false)]
-  public sealed class OnErrorAttribute : Attribute
-  {
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// When applied to a method, specifies that the method is called when an error occurs serializing an object.
+  /// </summary>
+  [AttributeUsage(AttributeTargets.Method, Inherited = false)]
+  public sealed class OnErrorAttribute : Attribute
+  {
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/ReflectionValueProvider.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/ReflectionValueProvider.cs
index 4013cf3..581c3e1 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/ReflectionValueProvider.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/ReflectionValueProvider.cs
@@ -1,87 +1,84 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Reflection;
-using Newtonsoft.Json.Utilities;
-using System.Globalization;
-
-namespace Newtonsoft.Json.Serialization
-{
-  /// <summary>
-  /// Get and set values for a <see cref="MemberInfo"/> using reflection.
-  /// </summary>
-  public class ReflectionValueProvider : IValueProvider
-  {
-    private readonly MemberInfo _memberInfo;
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="ReflectionValueProvider"/> class.
-    /// </summary>
-    /// <param name="memberInfo">The member info.</param>
-    public ReflectionValueProvider(MemberInfo memberInfo)
-    {
-      ValidationUtils.ArgumentNotNull(memberInfo, "memberInfo");
-      _memberInfo = memberInfo;
-    }
-
-    /// <summary>
-    /// Sets the value.
-    /// </summary>
-    /// <param name="target">The target to set the value on.</param>
-    /// <param name="value">The value to set on the target.</param>
-    public void SetValue(object target, object value)
-    {
-      try
-      {
-        ReflectionUtils.SetMemberValue(_memberInfo, target, value);
-      }
-      catch (Exception ex)
-      {
-        throw new JsonSerializationException("Error setting value to '{0}' on '{1}'.".FormatWith(CultureInfo.InvariantCulture, _memberInfo.Name, target.GetType()), ex);
-      }
-    }
-
-    /// <summary>
-    /// Gets the value.
-    /// </summary>
-    /// <param name="target">The target to get the value from.</param>
-    /// <returns>The value.</returns>
-    public object GetValue(object target)
-    {
-      try
-      {
-        return ReflectionUtils.GetMemberValue(_memberInfo, target);
-      }
-      catch (Exception ex)
-      {
-        throw new JsonSerializationException("Error getting value from '{0}' on '{1}'.".FormatWith(CultureInfo.InvariantCulture, _memberInfo.Name, target.GetType()), ex);
-      }
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Reflection;
+using Newtonsoft.Json.Utilities;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Get and set values for a <see cref="MemberInfo"/> using reflection.
+  /// </summary>
+  public class ReflectionValueProvider : IValueProvider
+  {
+    private readonly MemberInfo _memberInfo;
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="ReflectionValueProvider"/> class.
+    /// </summary>
+    /// <param name="memberInfo">The member info.</param>
+    public ReflectionValueProvider(MemberInfo memberInfo)
+    {
+      ValidationUtils.ArgumentNotNull(memberInfo, "memberInfo");
+      _memberInfo = memberInfo;
+    }
+
+    /// <summary>
+    /// Sets the value.
+    /// </summary>
+    /// <param name="target">The target to set the value on.</param>
+    /// <param name="value">The value to set on the target.</param>
+    public void SetValue(object target, object value)
+    {
+      try
+      {
+        ReflectionUtils.SetMemberValue(_memberInfo, target, value);
+      }
+      catch (Exception ex)
+      {
+        throw new JsonSerializationException("Error setting value to '{0}' on '{1}'.".FormatWith(CultureInfo.InvariantCulture, _memberInfo.Name, target.GetType()), ex);
+      }
+    }
+
+    /// <summary>
+    /// Gets the value.
+    /// </summary>
+    /// <param name="target">The target to get the value from.</param>
+    /// <returns>The value.</returns>
+    public object GetValue(object target)
+    {
+      try
+      {
+        return ReflectionUtils.GetMemberValue(_memberInfo, target);
+      }
+      catch (Exception ex)
+      {
+        throw new JsonSerializationException("Error getting value from '{0}' on '{1}'.".FormatWith(CultureInfo.InvariantCulture, _memberInfo.Name, target.GetType()), ex);
+      }
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/SerializationBinder.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/SerializationBinder.cs
index 9f55569..6930747 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/SerializationBinder.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/SerializationBinder.cs
@@ -1,21 +1,33 @@
-#if SILVERLIGHT || PocketPC
-using System;
-using System.Reflection;
-
-namespace Newtonsoft.Json
-{
-  /// <summary>
-  /// Allows users to control class loading and mandate what class to load.
-  /// </summary>
-  public abstract class SerializationBinder
-  {
-    /// <summary>
-    /// When overridden in a derived class, controls the binding of a serialized object to a type.
-    /// </summary>
-    /// <param name="assemblyName">Specifies the <see cref="Assembly"/> name of the serialized object.</param>
-    /// <param name="typeName">Specifies the <see cref="Type"/> name of the serialized object</param>
-    /// <returns></returns>
-    public abstract Type BindToType(string assemblyName, string typeName);
-  }
-}
+#if SILVERLIGHT || PocketPC || NETFX_CORE || PORTABLE
+using System;
+using System.Reflection;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Allows users to control class loading and mandate what class to load.
+  /// </summary>
+  public abstract class SerializationBinder
+  {
+    /// <summary>
+    /// When overridden in a derived class, controls the binding of a serialized object to a type.
+    /// </summary>
+    /// <param name="assemblyName">Specifies the <see cref="Assembly"/> name of the serialized object.</param>
+    /// <param name="typeName">Specifies the <see cref="Type"/> name of the serialized object</param>
+    /// <returns>The type of the object the formatter creates a new instance of.</returns>
+    public abstract Type BindToType(string assemblyName, string typeName);
+
+    /// <summary>
+    /// When overridden in a derived class, controls the binding of a serialized object to a type.
+    /// </summary>
+    /// <param name="serializedType">The type of the object the formatter creates a new instance of.</param>
+    /// <param name="assemblyName">Specifies the <see cref="Assembly"/> name of the serialized object.</param>
+    /// <param name="typeName">Specifies the <see cref="Type"/> name of the serialized object.</param>
+    public virtual void BindToName(Type serializedType, out string assemblyName, out string typeName)
+    {
+      assemblyName = null;
+      typeName = null;
+    }
+  }
+}
 #endif
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/StreamingContext.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/StreamingContext.cs
index 435be68..a602d16 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/StreamingContext.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/StreamingContext.cs
@@ -1,64 +1,64 @@
-#if PocketPC
-#pragma warning disable 1591
-
-// This class is... borrowed from .NET and Microsoft for a short time.
-// Hopefully Microsoft will add DateTimeOffset to the compact framework
-// or I will rewrite a striped down version of this file myself
-
-namespace System.Runtime.Serialization
-{
-  public enum StreamingContextStates
-  {
-    All = 255,
-    Clone = 64,
-    CrossAppDomain = 128,
-    CrossMachine = 2,
-    CrossProcess = 1,
-    File = 4,
-    Other = 32,
-    Persistence = 8,
-    Remoting = 16
-  }
-
-  public struct StreamingContext
-  {
-    internal object m_additionalContext;
-    internal StreamingContextStates m_state;
-    public StreamingContext(StreamingContextStates state)
-      : this(state, null)
-    {
-    }
-
-    public StreamingContext(StreamingContextStates state, object additional)
-    {
-      this.m_state = state;
-      this.m_additionalContext = additional;
-    }
-
-    public object Context
-    {
-      get
-      {
-        return this.m_additionalContext;
-      }
-    }
-    public override bool Equals(object obj)
-    {
-      return ((obj is StreamingContext) && ((((StreamingContext)obj).m_additionalContext == this.m_additionalContext) && (((StreamingContext)obj).m_state == this.m_state)));
-    }
-
-    public override int GetHashCode()
-    {
-      return (int)this.m_state;
-    }
-
-    public StreamingContextStates State
-    {
-      get
-      {
-        return this.m_state;
-      }
-    }
-  }
-}
+#if PocketPC
+#pragma warning disable 1591
+
+// This class is... borrowed from .NET and Microsoft for a short time.
+// Hopefully Microsoft will add DateTimeOffset to the compact framework
+// or I will rewrite a striped down version of this file myself
+
+namespace System.Runtime.Serialization
+{
+  public enum StreamingContextStates
+  {
+    All = 255,
+    Clone = 64,
+    CrossAppDomain = 128,
+    CrossMachine = 2,
+    CrossProcess = 1,
+    File = 4,
+    Other = 32,
+    Persistence = 8,
+    Remoting = 16
+  }
+
+  public struct StreamingContext
+  {
+    internal object m_additionalContext;
+    internal StreamingContextStates m_state;
+    public StreamingContext(StreamingContextStates state)
+      : this(state, null)
+    {
+    }
+
+    public StreamingContext(StreamingContextStates state, object additional)
+    {
+      this.m_state = state;
+      this.m_additionalContext = additional;
+    }
+
+    public object Context
+    {
+      get
+      {
+        return this.m_additionalContext;
+      }
+    }
+    public override bool Equals(object obj)
+    {
+      return ((obj is StreamingContext) && ((((StreamingContext)obj).m_additionalContext == this.m_additionalContext) && (((StreamingContext)obj).m_state == this.m_state)));
+    }
+
+    public override int GetHashCode()
+    {
+      return (int)this.m_state;
+    }
+
+    public StreamingContextStates State
+    {
+      get
+      {
+        return this.m_state;
+      }
+    }
+  }
+}
 #endif
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/TypeNameHandling.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/TypeNameHandling.cs
index 2a80c9c..c9b574a 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/TypeNameHandling.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/TypeNameHandling.cs
@@ -1,35 +1,57 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Newtonsoft.Json
-{
-  /// <summary>
-  /// Specifies type name handling options for the <see cref="JsonSerializer"/>.
-  /// </summary>
-  [Flags]
-  public enum TypeNameHandling
-  {
-    /// <summary>
-    /// Do not include the .NET type name when serializing types.
-    /// </summary>
-    None = 0,
-    /// <summary>
-    /// Include the .NET type name when serializing into a JSON object structure.
-    /// </summary>
-    Objects = 1,
-    /// <summary>
-    /// Include the .NET type name when serializing into a JSON array structure.
-    /// </summary>
-    Arrays = 2,
-    /// <summary>
-    /// Include the .NET type name when the type of the object being serialized is not the same as its declared type.
-    /// </summary>
-    Auto = 4,
-    /// <summary>
-    /// Always include the .NET type name when serializing.
-    /// </summary>
-    All = Objects | Arrays
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Specifies type name handling options for the <see cref="JsonSerializer"/>.
+  /// </summary>
+  [Flags]
+  public enum TypeNameHandling
+  {
+    /// <summary>
+    /// Do not include the .NET type name when serializing types.
+    /// </summary>
+    None = 0,
+    /// <summary>
+    /// Include the .NET type name when serializing into a JSON object structure.
+    /// </summary>
+    Objects = 1,
+    /// <summary>
+    /// Include the .NET type name when serializing into a JSON array structure.
+    /// </summary>
+    Arrays = 2,
+    /// <summary>
+    /// Always include the .NET type name when serializing.
+    /// </summary>
+    All = Objects | Arrays,
+    /// <summary>
+    /// Include the .NET type name when the type of the object being serialized is not the same as its declared type.
+    /// </summary>
+    Auto = 4
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/Base64Encoder.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/Base64Encoder.cs
index 2a1d86a..263bc0b 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/Base64Encoder.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/Base64Encoder.cs
@@ -1,95 +1,120 @@
-using System;
-using System.IO;
-
-namespace Newtonsoft.Json.Utilities
-{
-  internal class Base64Encoder
-  {
-    private const int Base64LineSize = 76;
-    private const int LineSizeInBytes = 57;
-
-    private readonly char[] _charsLine = new char[Base64LineSize];
-    private readonly TextWriter _writer;
-
-    private byte[] _leftOverBytes;
-    private int _leftOverBytesCount;
-
-    public Base64Encoder(TextWriter writer)
-    {
-      ValidationUtils.ArgumentNotNull(writer, "writer");
-      _writer = writer;
-    }
-
-    public void Encode(byte[] buffer, int index, int count)
-    {
-      if (buffer == null)
-        throw new ArgumentNullException("buffer");
-
-      if (index < 0)
-        throw new ArgumentOutOfRangeException("index");
-
-      if (count < 0)
-        throw new ArgumentOutOfRangeException("count");
-
-      if (count > (buffer.Length - index))
-        throw new ArgumentOutOfRangeException("count");
-
-      if (_leftOverBytesCount > 0)
-      {
-        int leftOverBytesCount = _leftOverBytesCount;
-        while (leftOverBytesCount < 3 && count > 0)
-        {
-          _leftOverBytes[leftOverBytesCount++] = buffer[index++];
-          count--;
-        }
-        if (count == 0 && leftOverBytesCount < 3)
-        {
-          _leftOverBytesCount = leftOverBytesCount;
-          return;
-        }
-        int num2 = Convert.ToBase64CharArray(_leftOverBytes, 0, 3, _charsLine, 0);
-        WriteChars(_charsLine, 0, num2);
-      }
-      _leftOverBytesCount = count % 3;
-      if (_leftOverBytesCount > 0)
-      {
-        count -= _leftOverBytesCount;
-        if (_leftOverBytes == null)
-        {
-          _leftOverBytes = new byte[3];
-        }
-        for (int i = 0; i < _leftOverBytesCount; i++)
-        {
-          _leftOverBytes[i] = buffer[(index + count) + i];
-        }
-      }
-      int num4 = index + count;
-      int length = LineSizeInBytes;
-      while (index < num4)
-      {
-        if ((index + length) > num4)
-        {
-          length = num4 - index;
-        }
-        int num6 = Convert.ToBase64CharArray(buffer, index, length, _charsLine, 0);
-        WriteChars(_charsLine, 0, num6);
-        index += length;
-      }
-    }
-
-    public void Flush()
-    {
-      if (_leftOverBytesCount > 0)
-      {
-        int count = Convert.ToBase64CharArray(_leftOverBytes, 0, _leftOverBytesCount, _charsLine, 0);
-        WriteChars(_charsLine, 0, count);
-        _leftOverBytesCount = 0;
-      }
-    }
-
-    private void WriteChars(char[] chars, int index, int count)
-    {
-      _writer.Write(chars, index, count);
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.IO;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal class Base64Encoder
+  {
+    private const int Base64LineSize = 76;
+    private const int LineSizeInBytes = 57;
+
+    private readonly char[] _charsLine = new char[Base64LineSize];
+    private readonly TextWriter _writer;
+
+    private byte[] _leftOverBytes;
+    private int _leftOverBytesCount;
+
+    public Base64Encoder(TextWriter writer)
+    {
+      ValidationUtils.ArgumentNotNull(writer, "writer");
+      _writer = writer;
+    }
+
+    public void Encode(byte[] buffer, int index, int count)
+    {
+      if (buffer == null)
+        throw new ArgumentNullException("buffer");
+
+      if (index < 0)
+        throw new ArgumentOutOfRangeException("index");
+
+      if (count < 0)
+        throw new ArgumentOutOfRangeException("count");
+
+      if (count > (buffer.Length - index))
+        throw new ArgumentOutOfRangeException("count");
+
+      if (_leftOverBytesCount > 0)
+      {
+        int leftOverBytesCount = _leftOverBytesCount;
+        while (leftOverBytesCount < 3 && count > 0)
+        {
+          _leftOverBytes[leftOverBytesCount++] = buffer[index++];
+          count--;
+        }
+        if (count == 0 && leftOverBytesCount < 3)
+        {
+          _leftOverBytesCount = leftOverBytesCount;
+          return;
+        }
+        int num2 = Convert.ToBase64CharArray(_leftOverBytes, 0, 3, _charsLine, 0);
+        WriteChars(_charsLine, 0, num2);
+      }
+      _leftOverBytesCount = count % 3;
+      if (_leftOverBytesCount > 0)
+      {
+        count -= _leftOverBytesCount;
+        if (_leftOverBytes == null)
+        {
+          _leftOverBytes = new byte[3];
+        }
+        for (int i = 0; i < _leftOverBytesCount; i++)
+        {
+          _leftOverBytes[i] = buffer[(index + count) + i];
+        }
+      }
+      int num4 = index + count;
+      int length = LineSizeInBytes;
+      while (index < num4)
+      {
+        if ((index + length) > num4)
+        {
+          length = num4 - index;
+        }
+        int num6 = Convert.ToBase64CharArray(buffer, index, length, _charsLine, 0);
+        WriteChars(_charsLine, 0, num6);
+        index += length;
+      }
+    }
+
+    public void Flush()
+    {
+      if (_leftOverBytesCount > 0)
+      {
+        int count = Convert.ToBase64CharArray(_leftOverBytes, 0, _leftOverBytesCount, _charsLine, 0);
+        WriteChars(_charsLine, 0, count);
+        _leftOverBytesCount = 0;
+      }
+    }
+
+    private void WriteChars(char[] chars, int index, int count)
+    {
+      _writer.Write(chars, index, count);
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/BidirectionalDictionary.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/BidirectionalDictionary.cs
index 1a949fe..19c8a98 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/BidirectionalDictionary.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/BidirectionalDictionary.cs
@@ -1,69 +1,67 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Newtonsoft.Json.Utilities
-{
-  internal class BidirectionalDictionary<TFirst, TSecond>
-  {
-    private readonly IDictionary<TFirst, TSecond> _firstToSecond;
-    private readonly IDictionary<TSecond, TFirst> _secondToFirst;
-
-    public BidirectionalDictionary()
-      : this(EqualityComparer<TFirst>.Default, EqualityComparer<TSecond>.Default)
-    {
-    }
-
-    public BidirectionalDictionary(IEqualityComparer<TFirst> firstEqualityComparer, IEqualityComparer<TSecond> secondEqualityComparer)
-    {
-      _firstToSecond = new Dictionary<TFirst, TSecond>(firstEqualityComparer);
-      _secondToFirst = new Dictionary<TSecond, TFirst>(secondEqualityComparer);
-    }
-
-    public void Add(TFirst first, TSecond second)
-    {
-      if (_firstToSecond.ContainsKey(first) || _secondToFirst.ContainsKey(second))
-      {
-        throw new ArgumentException("Duplicate first or second");
-      }
-      _firstToSecond.Add(first, second);
-      _secondToFirst.Add(second, first);
-    }
-
-    public bool TryGetByFirst(TFirst first, out TSecond second)
-    {
-      return _firstToSecond.TryGetValue(first, out second);
-    }
-
-    public bool TryGetBySecond(TSecond second, out TFirst first)
-    {
-      return _secondToFirst.TryGetValue(second, out first);
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal class BidirectionalDictionary<TFirst, TSecond>
+  {
+    private readonly IDictionary<TFirst, TSecond> _firstToSecond;
+    private readonly IDictionary<TSecond, TFirst> _secondToFirst;
+
+    public BidirectionalDictionary()
+      : this(EqualityComparer<TFirst>.Default, EqualityComparer<TSecond>.Default)
+    {
+    }
+
+    public BidirectionalDictionary(IEqualityComparer<TFirst> firstEqualityComparer, IEqualityComparer<TSecond> secondEqualityComparer)
+    {
+      _firstToSecond = new Dictionary<TFirst, TSecond>(firstEqualityComparer);
+      _secondToFirst = new Dictionary<TSecond, TFirst>(secondEqualityComparer);
+    }
+
+    public void Add(TFirst first, TSecond second)
+    {
+      if (_firstToSecond.ContainsKey(first) || _secondToFirst.ContainsKey(second))
+      {
+        throw new ArgumentException("Duplicate first or second");
+      }
+      _firstToSecond.Add(first, second);
+      _secondToFirst.Add(second, first);
+    }
+
+    public bool TryGetByFirst(TFirst first, out TSecond second)
+    {
+      return _firstToSecond.TryGetValue(first, out second);
+    }
+
+    public bool TryGetBySecond(TSecond second, out TFirst first)
+    {
+      return _secondToFirst.TryGetValue(second, out first);
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/CollectionUtils.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/CollectionUtils.cs
index 7e20b0e..f31bc38 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/CollectionUtils.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/CollectionUtils.cs
@@ -1,635 +1,408 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Reflection;
-using System.Text;
-using System.Collections;
-using System.Linq;
-using System.Globalization;
-
-namespace Newtonsoft.Json.Utilities
-{
-  internal static class CollectionUtils
-  {
-    public static IEnumerable<T> CastValid<T>(this IEnumerable enumerable)
-    {
-      ValidationUtils.ArgumentNotNull(enumerable, "enumerable");
-
-      return enumerable.Cast<object>().Where(o => o is T).Cast<T>();
-    }
-
-    public static List<T> CreateList<T>(params T[] values)
-    {
-      return new List<T>(values);
-    }
-
-    /// <summary>
-    /// Determines whether the collection is null or empty.
-    /// </summary>
-    /// <param name="collection">The collection.</param>
-    /// <returns>
-    /// 	<c>true</c> if the collection is null or empty; otherwise, <c>false</c>.
-    /// </returns>
-    public static bool IsNullOrEmpty(ICollection collection)
-    {
-      if (collection != null)
-      {
-        return (collection.Count == 0);
-      }
-      return true;
-    }
-
-    /// <summary>
-    /// Determines whether the collection is null or empty.
-    /// </summary>
-    /// <param name="collection">The collection.</param>
-    /// <returns>
-    /// 	<c>true</c> if the collection is null or empty; otherwise, <c>false</c>.
-    /// </returns>
-    public static bool IsNullOrEmpty<T>(ICollection<T> collection)
-    {
-      if (collection != null)
-      {
-        return (collection.Count == 0);
-      }
-      return true;
-    }
-
-    /// <summary>
-    /// Determines whether the collection is null, empty or its contents are uninitialized values.
-    /// </summary>
-    /// <param name="list">The list.</param>
-    /// <returns>
-    /// 	<c>true</c> if the collection is null or empty or its contents are uninitialized values; otherwise, <c>false</c>.
-    /// </returns>
-    public static bool IsNullOrEmptyOrDefault<T>(IList<T> list)
-    {
-      if (IsNullOrEmpty<T>(list))
-        return true;
-
-      return ReflectionUtils.ItemsUnitializedValue<T>(list);
-    }
-
-    /// <summary>
-    /// Makes a slice of the specified list in between the start and end indexes.
-    /// </summary>
-    /// <param name="list">The list.</param>
-    /// <param name="start">The start index.</param>
-    /// <param name="end">The end index.</param>
-    /// <returns>A slice of the list.</returns>
-    public static IList<T> Slice<T>(IList<T> list, int? start, int? end)
-    {
-      return Slice<T>(list, start, end, null);
-    }
-
-    /// <summary>
-    /// Makes a slice of the specified list in between the start and end indexes,
-    /// getting every so many items based upon the step.
-    /// </summary>
-    /// <param name="list">The list.</param>
-    /// <param name="start">The start index.</param>
-    /// <param name="end">The end index.</param>
-    /// <param name="step">The step.</param>
-    /// <returns>A slice of the list.</returns>
-    public static IList<T> Slice<T>(IList<T> list, int? start, int? end, int? step)
-    {
-      if (list == null)
-        throw new ArgumentNullException("list");
-
-      if (step == 0)
-        throw new ArgumentException("Step cannot be zero.", "step");
-
-      List<T> slicedList = new List<T>();
-
-      // nothing to slice
-      if (list.Count == 0)
-        return slicedList;
-
-      // set defaults for null arguments
-      int s = step ?? 1;
-      int startIndex = start ?? 0;
-      int endIndex = end ?? list.Count;
-
-      // start from the end of the list if start is negitive
-      startIndex = (startIndex < 0) ? list.Count + startIndex : startIndex;
-
-      // end from the start of the list if end is negitive
-      endIndex = (endIndex < 0) ? list.Count + endIndex : endIndex;
-
-      // ensure indexes keep within collection bounds
-      startIndex = Math.Max(startIndex, 0);
-      endIndex = Math.Min(endIndex, list.Count - 1);
-
-      // loop between start and end indexes, incrementing by the step
-      for (int i = startIndex; i < endIndex; i += s)
-      {
-        slicedList.Add(list[i]);
-      }
-
-      return slicedList;
-    }
-
-
-    /// <summary>
-    /// Group the collection using a function which returns the key.
-    /// </summary>
-    /// <param name="source">The source collection to group.</param>
-    /// <param name="keySelector">The key selector.</param>
-    /// <returns>A Dictionary with each key relating to a list of objects in a list grouped under it.</returns>
-    public static Dictionary<K, List<V>> GroupBy<K, V>(ICollection<V> source, Func<V, K> keySelector)
-    {
-      if (keySelector == null)
-        throw new ArgumentNullException("keySelector");
-
-      Dictionary<K, List<V>> groupedValues = new Dictionary<K, List<V>>();
-
-      foreach (V value in source)
-      {
-        // using delegate to get the value's key
-        K key = keySelector(value);
-        List<V> groupedValueList;
-
-        // add a list for grouped values if the key is not already in Dictionary
-        if (!groupedValues.TryGetValue(key, out groupedValueList))
-        {
-          groupedValueList = new List<V>();
-          groupedValues.Add(key, groupedValueList);
-        }
-
-        groupedValueList.Add(value);
-      }
-
-      return groupedValues;
-    }
-
-    /// <summary>
-    /// Adds the elements of the specified collection to the specified generic IList.
-    /// </summary>
-    /// <param name="initial">The list to add to.</param>
-    /// <param name="collection">The collection of elements to add.</param>
-    public static void AddRange<T>(this IList<T> initial, IEnumerable<T> collection)
-    {
-      if (initial == null)
-        throw new ArgumentNullException("initial");
-
-      if (collection == null)
-        return;
-
-      foreach (T value in collection)
-      {
-        initial.Add(value);
-      }
-    }
-
-    public static void AddRange(this IList initial, IEnumerable collection)
-    {
-      ValidationUtils.ArgumentNotNull(initial, "initial");
-
-      ListWrapper<object> wrapper = new ListWrapper<object>(initial);
-      wrapper.AddRange(collection.Cast<object>());
-    }
-
-    public static List<T> Distinct<T>(List<T> collection)
-    {
-      List<T> distinctList = new List<T>();
-
-      foreach (T value in collection)
-      {
-        if (!distinctList.Contains(value))
-          distinctList.Add(value);
-      }
-
-      return distinctList;
-    }
-
-    public static List<List<T>> Flatten<T>(params IList<T>[] lists)
-    {
-      List<List<T>> flattened = new List<List<T>>();
-      Dictionary<int, T> currentList = new Dictionary<int, T>();
-
-      Recurse<T>(new List<IList<T>>(lists), 0, currentList, flattened);
-
-      return flattened;
-    }
-
-    private static void Recurse<T>(IList<IList<T>> global, int current, Dictionary<int, T> currentSet, List<List<T>> flattenedResult)
-    {
-      IList<T> currentArray = global[current];
-
-      for (int i = 0; i < currentArray.Count; i++)
-      {
-        currentSet[current] = currentArray[i];
-
-        if (current == global.Count - 1)
-        {
-          List<T> items = new List<T>();
-
-          for (int k = 0; k < currentSet.Count; k++)
-          {
-            items.Add(currentSet[k]);
-          }
-
-          flattenedResult.Add(items);
-        }
-        else
-        {
-          Recurse(global, current + 1, currentSet, flattenedResult);
-        }
-      }
-    }
-
-    public static List<T> CreateList<T>(ICollection collection)
-    {
-      if (collection == null)
-        throw new ArgumentNullException("collection");
-
-      T[] array = new T[collection.Count];
-      collection.CopyTo(array, 0);
-
-      return new List<T>(array);
-    }
-
-    public static bool ListEquals<T>(IList<T> a, IList<T> b)
-    {
-      if (a == null || b == null)
-        return (a == null && b == null);
-
-      if (a.Count != b.Count)
-        return false;
-
-      EqualityComparer<T> comparer = EqualityComparer<T>.Default;
-
-      for (int i = 0; i < a.Count; i++)
-      {
-        if (!comparer.Equals(a[i], b[i]))
-          return false;
-      }
-
-      return true;
-    }
-
-    #region GetSingleItem
-    public static bool TryGetSingleItem<T>(IList<T> list, out T value)
-    {
-      return TryGetSingleItem<T>(list, false, out value);
-    }
-
-    public static bool TryGetSingleItem<T>(IList<T> list, bool returnDefaultIfEmpty, out T value)
-    {
-      return MiscellaneousUtils.TryAction<T>(delegate { return GetSingleItem(list, returnDefaultIfEmpty); }, out value);
-    }
-
-    public static T GetSingleItem<T>(IList<T> list)
-    {
-      return GetSingleItem<T>(list, false);
-    }
-
-    public static T GetSingleItem<T>(IList<T> list, bool returnDefaultIfEmpty)
-    {
-      if (list.Count == 1)
-        return list[0];
-      else if (returnDefaultIfEmpty && list.Count == 0)
-        return default(T);
-      else
-        throw new Exception("Expected single {0} in list but got {1}.".FormatWith(CultureInfo.InvariantCulture, typeof(T), list.Count));
-    }
-    #endregion
-
-    public static IList<T> Minus<T>(IList<T> list, IList<T> minus)
-    {
-      ValidationUtils.ArgumentNotNull(list, "list");
-
-      List<T> result = new List<T>(list.Count);
-      foreach (T t in list)
-      {
-        if (minus == null || !minus.Contains(t))
-          result.Add(t);
-      }
-
-      return result;
-    }
-
-    public static IList CreateGenericList(Type listType)
-    {
-      ValidationUtils.ArgumentNotNull(listType, "listType");
-
-      return (IList)ReflectionUtils.CreateGeneric(typeof(List<>), listType);
-    }
-
-    public static IDictionary CreateGenericDictionary(Type keyType, Type valueType)
-    {
-      ValidationUtils.ArgumentNotNull(keyType, "keyType");
-      ValidationUtils.ArgumentNotNull(valueType, "valueType");
-
-      return (IDictionary)ReflectionUtils.CreateGeneric(typeof(Dictionary<,>), keyType, valueType);
-    }
-
-    public static bool IsListType(Type type)
-    {
-      ValidationUtils.ArgumentNotNull(type, "type");
-
-      if (type.IsArray)
-        return true;
-      if (typeof(IList).IsAssignableFrom(type))
-        return true;
-      if (ReflectionUtils.ImplementsGenericDefinition(type, typeof(IList<>)))
-        return true;
-
-      return false;
-    }
-
-    public static bool IsCollectionType(Type type)
-    {
-      ValidationUtils.ArgumentNotNull(type, "type");
-
-      if (type.IsArray)
-        return true;
-      if (typeof(ICollection).IsAssignableFrom(type))
-        return true;
-      if (ReflectionUtils.ImplementsGenericDefinition(type, typeof(ICollection<>)))
-        return true;
-
-      return false;
-    }
-
-    public static bool IsDictionaryType(Type type)
-    {
-      ValidationUtils.ArgumentNotNull(type, "type");
-
-      if (typeof(IDictionary).IsAssignableFrom(type))
-        return true;
-      if (ReflectionUtils.ImplementsGenericDefinition(type, typeof (IDictionary<,>)))
-        return true;
-
-      return false;
-    }
-
-    public static IWrappedCollection CreateCollectionWrapper(object list)
-    {
-      ValidationUtils.ArgumentNotNull(list, "list");
-
-      Type collectionDefinition;
-      if (ReflectionUtils.ImplementsGenericDefinition(list.GetType(), typeof(ICollection<>), out collectionDefinition))
-      {
-        Type collectionItemType = ReflectionUtils.GetCollectionItemType(collectionDefinition);
-
-        // Activator.CreateInstance throws AmbiguousMatchException. Manually invoke constructor
-        Func<Type, IList<object>, object> instanceCreator = (t, a) =>
-        {
-          ConstructorInfo c = t.GetConstructor(new[] { collectionDefinition });
-          return c.Invoke(new[] { list });
-        };
-
-        return (IWrappedCollection)ReflectionUtils.CreateGeneric(typeof(CollectionWrapper<>), new[] { collectionItemType }, instanceCreator, list);
-      }
-      else if (list is IList)
-      {
-        return new CollectionWrapper<object>((IList)list);
-      }
-      else
-      {
-        throw new Exception("Can not create ListWrapper for type {0}.".FormatWith(CultureInfo.InvariantCulture, list.GetType()));
-      }
-    }
-    public static IWrappedList CreateListWrapper(object list)
-    {
-      ValidationUtils.ArgumentNotNull(list, "list");
-
-      Type listDefinition;
-      if (ReflectionUtils.ImplementsGenericDefinition(list.GetType(), typeof(IList<>), out listDefinition))
-      {
-        Type collectionItemType = ReflectionUtils.GetCollectionItemType(listDefinition);
-
-        // Activator.CreateInstance throws AmbiguousMatchException. Manually invoke constructor
-        Func<Type, IList<object>, object> instanceCreator = (t, a) =>
-        {
-          ConstructorInfo c = t.GetConstructor(new[] {listDefinition});
-          return c.Invoke(new[] { list });
-        };
-
-        return (IWrappedList)ReflectionUtils.CreateGeneric(typeof(ListWrapper<>), new[] { collectionItemType }, instanceCreator, list);
-      }
-      else if (list is IList)
-      {
-        return new ListWrapper<object>((IList)list);
-      }
-      else
-      {
-        throw new Exception("Can not create ListWrapper for type {0}.".FormatWith(CultureInfo.InvariantCulture, list.GetType()));
-      }
-    }
-
-    public static IWrappedDictionary CreateDictionaryWrapper(object dictionary)
-    {
-      ValidationUtils.ArgumentNotNull(dictionary, "dictionary");
-
-      Type dictionaryDefinition;
-      if (ReflectionUtils.ImplementsGenericDefinition(dictionary.GetType(), typeof(IDictionary<,>), out dictionaryDefinition))
-      {
-        Type dictionaryKeyType = ReflectionUtils.GetDictionaryKeyType(dictionaryDefinition);
-        Type dictionaryValueType = ReflectionUtils.GetDictionaryValueType(dictionaryDefinition);
-
-        // Activator.CreateInstance throws AmbiguousMatchException. Manually invoke constructor
-        Func<Type, IList<object>, object> instanceCreator = (t, a) =>
-        {
-          ConstructorInfo c = t.GetConstructor(new[] { dictionaryDefinition });
-          return c.Invoke(new[] { dictionary });
-        };
-
-        return (IWrappedDictionary)ReflectionUtils.CreateGeneric(typeof(DictionaryWrapper<,>), new[] { dictionaryKeyType, dictionaryValueType }, instanceCreator, dictionary);
-      }
-      else if (dictionary is IDictionary)
-      {
-        return new DictionaryWrapper<object, object>((IDictionary)dictionary);
-      }
-      else
-      {
-        throw new Exception("Can not create DictionaryWrapper for type {0}.".FormatWith(CultureInfo.InvariantCulture, dictionary.GetType()));
-      }
-    }
-
-    public static object CreateAndPopulateList(Type listType, Action<IList, bool> populateList)
-    {
-      ValidationUtils.ArgumentNotNull(listType, "listType");
-      ValidationUtils.ArgumentNotNull(populateList, "populateList");
-
-      IList list;
-      Type collectionType;
-      bool isReadOnlyOrFixedSize = false;
-
-      if (listType.IsArray)
-      {
-        // have to use an arraylist when creating array
-        // there is no way to know the size until it is finised
-        list = new List<object>();
-        isReadOnlyOrFixedSize = true;
-      }
-      else if (ReflectionUtils.InheritsGenericDefinition(listType, typeof(ReadOnlyCollection<>), out collectionType))
-      {
-        Type readOnlyCollectionContentsType = collectionType.GetGenericArguments()[0];
-        Type genericEnumerable = ReflectionUtils.MakeGenericType(typeof(IEnumerable<>), readOnlyCollectionContentsType);
-        bool suitableConstructor = false;
-
-        foreach (ConstructorInfo constructor in listType.GetConstructors())
-        {
-          IList<ParameterInfo> parameters = constructor.GetParameters();
-
-          if (parameters.Count == 1)
-          {
-            if (genericEnumerable.IsAssignableFrom(parameters[0].ParameterType))
-            {
-              suitableConstructor = true;
-              break;
-            }
-          }
-        }
-
-        if (!suitableConstructor)
-          throw new Exception("Read-only type {0} does not have a public constructor that takes a type that implements {1}.".FormatWith(CultureInfo.InvariantCulture, listType, genericEnumerable));
-
-        // can't add or modify a readonly list
-        // use List<T> and convert once populated
-        list = CreateGenericList(readOnlyCollectionContentsType);
-        isReadOnlyOrFixedSize = true;
-      }
-      else if (typeof(IList).IsAssignableFrom(listType))
-      {
-        if (ReflectionUtils.IsInstantiatableType(listType))
-          list = (IList)Activator.CreateInstance(listType);
-        else if (listType == typeof(IList))
-          list = new List<object>();
-        else
-          list = null;
-      }
-      else if (ReflectionUtils.ImplementsGenericDefinition(listType, typeof(ICollection<>)))
-      {
-        if (ReflectionUtils.IsInstantiatableType(listType))
-          list = CreateCollectionWrapper(Activator.CreateInstance(listType));
-        else
-          list = null;
-      }
-      else
-      {
-        list = null;
-      }
-
-      if (list == null)
-        throw new Exception("Cannot create and populate list type {0}.".FormatWith(CultureInfo.InvariantCulture, listType));
-
-      populateList(list, isReadOnlyOrFixedSize);
-
-      // create readonly and fixed sized collections using the temporary list
-      if (isReadOnlyOrFixedSize)
-      {
-        if (listType.IsArray)
-          list = ToArray(((List<object>)list).ToArray(), ReflectionUtils.GetCollectionItemType(listType));
-        else if (ReflectionUtils.InheritsGenericDefinition(listType, typeof(ReadOnlyCollection<>)))
-          list = (IList)ReflectionUtils.CreateInstance(listType, list);
-      }
-      else if (list is IWrappedCollection)
-      {
-        return ((IWrappedCollection) list).UnderlyingCollection;
-      }
-
-      return list;
-    }
-
-    public static Array ToArray(Array initial, Type type)
-    {
-      if (type == null)
-        throw new ArgumentNullException("type");
-
-      Array destinationArray = Array.CreateInstance(type, initial.Length);
-      Array.Copy(initial, 0, destinationArray, 0, initial.Length);
-      return destinationArray;
-    }
-
-    public static bool AddDistinct<T>(this IList<T> list, T value)
-    {
-      return list.AddDistinct(value, EqualityComparer<T>.Default);
-    }
-
-    public static bool AddDistinct<T>(this IList<T> list, T value, IEqualityComparer<T> comparer)
-    {
-      if (list.ContainsValue(value, comparer))
-        return false;
-
-      list.Add(value);
-      return true;
-    }
-
-    // this is here because LINQ Bridge doesn't support Contains with IEqualityComparer<T>
-    public static bool ContainsValue<TSource>(this IEnumerable<TSource> source, TSource value, IEqualityComparer<TSource> comparer)
-    {
-      if (comparer == null)
-        comparer = EqualityComparer<TSource>.Default;
-
-      if (source == null)
-        throw new ArgumentNullException("source");
-
-      foreach (TSource local in source)
-      {
-        if (comparer.Equals(local, value))
-          return true;
-      }
-
-      return false;
-    }
-
-    public static bool AddRangeDistinct<T>(this IList<T> list, IEnumerable<T> values)
-    {
-      return list.AddRangeDistinct(values, EqualityComparer<T>.Default);
-    }
-
-    public static bool AddRangeDistinct<T>(this IList<T> list, IEnumerable<T> values, IEqualityComparer<T> comparer)
-    {
-      bool allAdded = true;
-      foreach (T value in values)
-      {
-        if (!list.AddDistinct(value, comparer))
-          allAdded = false;
-      }
-
-      return allAdded;
-    }
-
-    public static int IndexOf<T>(this IEnumerable<T> collection, Func<T, bool> predicate)
-    {
-      int index = 0;
-      foreach (T value in collection)
-      {
-        if (predicate(value))
-          return index;
-
-        index++;
-      }
-
-      return -1;
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Reflection;
+using System.Text;
+using System.Collections;
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#else
+using System.Linq;
+#endif
+using System.Globalization;
+using Newtonsoft.Json.Serialization;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal static class CollectionUtils
+  {
+    public static IEnumerable<T> CastValid<T>(this IEnumerable enumerable)
+    {
+      ValidationUtils.ArgumentNotNull(enumerable, "enumerable");
+
+      return enumerable.Cast<object>().Where(o => o is T).Cast<T>();
+    }
+
+    /// <summary>
+    /// Determines whether the collection is null or empty.
+    /// </summary>
+    /// <param name="collection">The collection.</param>
+    /// <returns>
+    /// 	<c>true</c> if the collection is null or empty; otherwise, <c>false</c>.
+    /// </returns>
+    public static bool IsNullOrEmpty<T>(ICollection<T> collection)
+    {
+      if (collection != null)
+      {
+        return (collection.Count == 0);
+      }
+      return true;
+    }
+
+    /// <summary>
+    /// Adds the elements of the specified collection to the specified generic IList.
+    /// </summary>
+    /// <param name="initial">The list to add to.</param>
+    /// <param name="collection">The collection of elements to add.</param>
+    public static void AddRange<T>(this IList<T> initial, IEnumerable<T> collection)
+    {
+      if (initial == null)
+        throw new ArgumentNullException("initial");
+
+      if (collection == null)
+        return;
+
+      foreach (T value in collection)
+      {
+        initial.Add(value);
+      }
+    }
+
+    public static void AddRange(this IList initial, IEnumerable collection)
+    {
+      ValidationUtils.ArgumentNotNull(initial, "initial");
+
+      ListWrapper<object> wrapper = new ListWrapper<object>(initial);
+      wrapper.AddRange(collection.Cast<object>());
+    }
+
+    public static IList CreateGenericList(Type listType)
+    {
+      ValidationUtils.ArgumentNotNull(listType, "listType");
+
+      return (IList)ReflectionUtils.CreateGeneric(typeof(List<>), listType);
+    }
+
+    public static bool IsDictionaryType(Type type)
+    {
+      ValidationUtils.ArgumentNotNull(type, "type");
+
+      if (typeof(IDictionary).IsAssignableFrom(type))
+        return true;
+      if (ReflectionUtils.ImplementsGenericDefinition(type, typeof (IDictionary<,>)))
+        return true;
+
+      return false;
+    }
+
+    public static IWrappedCollection CreateCollectionWrapper(object list)
+    {
+      ValidationUtils.ArgumentNotNull(list, "list");
+
+      Type collectionDefinition;
+      if (ReflectionUtils.ImplementsGenericDefinition(list.GetType(), typeof(ICollection<>), out collectionDefinition))
+      {
+        Type collectionItemType = ReflectionUtils.GetCollectionItemType(collectionDefinition);
+
+        // Activator.CreateInstance throws AmbiguousMatchException. Manually invoke constructor
+        Func<Type, IList<object>, object> instanceCreator = (t, a) =>
+        {
+          ConstructorInfo c = t.GetConstructor(new[] { collectionDefinition });
+          return c.Invoke(new[] { list });
+        };
+
+        return (IWrappedCollection)ReflectionUtils.CreateGeneric(typeof(CollectionWrapper<>), new[] { collectionItemType }, instanceCreator, list);
+      }
+      else if (list is IList)
+      {
+        return new CollectionWrapper<object>((IList)list);
+      }
+      else
+      {
+        throw new ArgumentException("Can not create ListWrapper for type {0}.".FormatWith(CultureInfo.InvariantCulture, list.GetType()), "list");
+      }
+    }
+
+    public static IWrappedDictionary CreateDictionaryWrapper(object dictionary)
+    {
+      ValidationUtils.ArgumentNotNull(dictionary, "dictionary");
+
+      Type dictionaryDefinition;
+      if (ReflectionUtils.ImplementsGenericDefinition(dictionary.GetType(), typeof(IDictionary<,>), out dictionaryDefinition))
+      {
+        Type dictionaryKeyType = ReflectionUtils.GetDictionaryKeyType(dictionaryDefinition);
+        Type dictionaryValueType = ReflectionUtils.GetDictionaryValueType(dictionaryDefinition);
+
+        // Activator.CreateInstance throws AmbiguousMatchException. Manually invoke constructor
+        Func<Type, IList<object>, object> instanceCreator = (t, a) =>
+        {
+          ConstructorInfo c = t.GetConstructor(new[] { dictionaryDefinition });
+          return c.Invoke(new[] { dictionary });
+        };
+
+        return (IWrappedDictionary)ReflectionUtils.CreateGeneric(typeof(DictionaryWrapper<,>), new[] { dictionaryKeyType, dictionaryValueType }, instanceCreator, dictionary);
+      }
+      else if (dictionary is IDictionary)
+      {
+        return new DictionaryWrapper<object, object>((IDictionary)dictionary);
+      }
+      else
+      {
+        throw new ArgumentException("Can not create DictionaryWrapper for type {0}.".FormatWith(CultureInfo.InvariantCulture, dictionary.GetType()), "dictionary");
+      }
+    }
+
+    public static IList CreateList(Type listType, out bool isReadOnlyOrFixedSize)
+    {
+      ValidationUtils.ArgumentNotNull(listType, "listType");
+
+      IList list;
+      Type collectionType;
+      isReadOnlyOrFixedSize = false;
+
+      if (listType.IsArray)
+      {
+        // have to use an arraylist when creating array
+        // there is no way to know the size until it is finised
+        list = new List<object>();
+        isReadOnlyOrFixedSize = true;
+      }
+      else if (ReflectionUtils.InheritsGenericDefinition(listType, typeof(ReadOnlyCollection<>), out collectionType))
+      {
+        Type readOnlyCollectionContentsType = collectionType.GetGenericArguments()[0];
+        Type genericEnumerable = ReflectionUtils.MakeGenericType(typeof(IEnumerable<>), readOnlyCollectionContentsType);
+        bool suitableConstructor = false;
+
+        foreach (ConstructorInfo constructor in listType.GetConstructors())
+        {
+          IList<ParameterInfo> parameters = constructor.GetParameters();
+
+          if (parameters.Count == 1)
+          {
+            if (genericEnumerable.IsAssignableFrom(parameters[0].ParameterType))
+            {
+              suitableConstructor = true;
+              break;
+            }
+          }
+        }
+
+        if (!suitableConstructor)
+          throw new Exception("Read-only type {0} does not have a public constructor that takes a type that implements {1}.".FormatWith(CultureInfo.InvariantCulture, listType, genericEnumerable));
+
+        // can't add or modify a readonly list
+        // use List<T> and convert once populated
+        list = CreateGenericList(readOnlyCollectionContentsType);
+        isReadOnlyOrFixedSize = true;
+      }
+      else if (typeof(IList).IsAssignableFrom(listType))
+      {
+        if (ReflectionUtils.IsInstantiatableType(listType))
+          list = (IList)Activator.CreateInstance(listType);
+        else if (listType == typeof(IList))
+          list = new List<object>();
+        else
+          list = null;
+      }
+      else if (ReflectionUtils.ImplementsGenericDefinition(listType, typeof(ICollection<>)))
+      {
+        if (ReflectionUtils.IsInstantiatableType(listType))
+          list = CreateCollectionWrapper(Activator.CreateInstance(listType));
+        else
+          list = null;
+      }
+      else
+      {
+        list = null;
+      }
+
+      if (list == null)
+        throw new InvalidOperationException("Cannot create and populate list type {0}.".FormatWith(CultureInfo.InvariantCulture, listType));
+
+      return list;
+    }
+
+    public static Array ToArray(Array initial, Type type)
+    {
+      if (type == null)
+        throw new ArgumentNullException("type");
+
+      Array destinationArray = Array.CreateInstance(type, initial.Length);
+      Array.Copy(initial, 0, destinationArray, 0, initial.Length);
+      return destinationArray;
+    }
+
+    public static bool AddDistinct<T>(this IList<T> list, T value)
+    {
+      return list.AddDistinct(value, EqualityComparer<T>.Default);
+    }
+
+    public static bool AddDistinct<T>(this IList<T> list, T value, IEqualityComparer<T> comparer)
+    {
+      if (list.ContainsValue(value, comparer))
+        return false;
+
+      list.Add(value);
+      return true;
+    }
+
+    // this is here because LINQ Bridge doesn't support Contains with IEqualityComparer<T>
+    public static bool ContainsValue<TSource>(this IEnumerable<TSource> source, TSource value, IEqualityComparer<TSource> comparer)
+    {
+      if (comparer == null)
+        comparer = EqualityComparer<TSource>.Default;
+
+      if (source == null)
+        throw new ArgumentNullException("source");
+
+      foreach (TSource local in source)
+      {
+        if (comparer.Equals(local, value))
+          return true;
+      }
+
+      return false;
+    }
+
+    public static bool AddRangeDistinct<T>(this IList<T> list, IEnumerable<T> values, IEqualityComparer<T> comparer)
+    {
+      bool allAdded = true;
+      foreach (T value in values)
+      {
+        if (!list.AddDistinct(value, comparer))
+          allAdded = false;
+      }
+
+      return allAdded;
+    }
+
+    public static int IndexOf<T>(this IEnumerable<T> collection, Func<T, bool> predicate)
+    {
+      int index = 0;
+      foreach (T value in collection)
+      {
+        if (predicate(value))
+          return index;
+
+        index++;
+      }
+
+      return -1;
+    }
+
+    /// <summary>
+    /// Returns the index of the first occurrence in a sequence by using a specified IEqualityComparer.
+    /// </summary>
+    /// <typeparam name="TSource">The type of the elements of source.</typeparam>
+    /// <param name="list">A sequence in which to locate a value.</param>
+    /// <param name="value">The object to locate in the sequence</param>
+    /// <param name="comparer">An equality comparer to compare values.</param>
+    /// <returns>The zero-based index of the first occurrence of value within the entire sequence, if found; otherwise, –1.</returns>
+    public static int IndexOf<TSource>(this IEnumerable<TSource> list, TSource value, IEqualityComparer<TSource> comparer)
+    {
+      int index = 0;
+      foreach (TSource item in list)
+      {
+        if (comparer.Equals(item, value))
+        {
+          return index;
+        }
+        index++;
+      }
+      return -1;
+    }
+
+    private static IList<int> GetDimensions(IList values)
+    {
+      IList<int> dimensions = new List<int>();
+
+      IList currentArray = values;
+      while (true)
+      {
+        dimensions.Add(currentArray.Count);
+        if (currentArray.Count == 0)
+          break;
+
+        object v = currentArray[0];
+        if (v is IList)
+          currentArray = (IList)v;
+        else
+          break;
+      }
+
+      return dimensions;
+    }
+
+    private static void CopyFromJaggedToMultidimensionalArray(IList values, Array multidimensionalArray, int[] indices)
+    {
+      int dimension = indices.Length;
+      if (dimension == multidimensionalArray.Rank)
+      {
+        multidimensionalArray.SetValue(JaggedArrayGetValue(values, indices), indices);
+        return;
+      }
+
+      int dimensionLength = multidimensionalArray.GetLength(dimension);
+      IList list = (IList)JaggedArrayGetValue(values, indices);
+      int currentValuesLength = list.Count;
+      if (currentValuesLength != dimensionLength)
+        throw new Exception("Cannot deserialize non-cubical array as multidimensional array.");
+
+      int[] newIndices = new int[dimension + 1];
+      for (int i = 0; i < dimension; i++)
+      {
+        newIndices[i] = indices[i];
+      }
+
+      for (int i = 0; i < multidimensionalArray.GetLength(dimension); i++)
+      {
+        newIndices[dimension] = i;
+        CopyFromJaggedToMultidimensionalArray(values, multidimensionalArray, newIndices);
+      }
+    }
+
+    private static object JaggedArrayGetValue(IList values, int[] indices)
+    {
+      IList currentList = values;
+      for (int i = 0; i < indices.Length; i++)
+      {
+        int index = indices[i];
+        if (i == indices.Length - 1)
+          return currentList[index];
+        else
+          currentList = (IList)currentList[index];
+      }
+      return currentList;
+    }
+
+    public static Array ToMultidimensionalArray(IList values, Type type, int rank)
+    {
+      IList<int> dimensions = GetDimensions(values);
+
+      while (dimensions.Count < rank)
+      {
+        dimensions.Add(0);
+      }
+
+      Array multidimensionalArray = Array.CreateInstance(type, dimensions.ToArray());
+      CopyFromJaggedToMultidimensionalArray(values, multidimensionalArray, new int[0]);
+
+      return multidimensionalArray;
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/CollectionWrapper.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/CollectionWrapper.cs
index 1eb4535..24f2fa0 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/CollectionWrapper.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/CollectionWrapper.cs
@@ -1,271 +1,281 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Threading;
-using Newtonsoft.Json.Utilities;
-using System.Linq;
-using System.Globalization;
-
-namespace Newtonsoft.Json.Utilities
-{
-  internal interface IWrappedCollection : IList
-  {
-    object UnderlyingCollection { get; }
-  }
-
-  internal class CollectionWrapper<T> : ICollection<T>, IWrappedCollection
-  {
-    private readonly IList _list;
-    private readonly ICollection<T> _genericCollection;
-    private object _syncRoot;
-
-    public CollectionWrapper(IList list)
-    {
-      ValidationUtils.ArgumentNotNull(list, "list");
-
-      if (list is ICollection<T>)
-        _genericCollection = (ICollection<T>)list;
-      else
-        _list = list;
-    }
-
-    public CollectionWrapper(ICollection<T> list)
-    {
-      ValidationUtils.ArgumentNotNull(list, "list");
-
-      _genericCollection = list;
-    }
-
-    public void Add(T item)
-    {
-      if (_genericCollection != null)
-        _genericCollection.Add(item);
-      else
-        _list.Add(item);
-    }
-
-    public void Clear()
-    {
-      if (_genericCollection != null)
-        _genericCollection.Clear();
-      else
-        _list.Clear();
-    }
-
-    public bool Contains(T item)
-    {
-      if (_genericCollection != null)
-        return _genericCollection.Contains(item);
-      else
-        return _list.Contains(item);
-    }
-
-    public void CopyTo(T[] array, int arrayIndex)
-    {
-      if (_genericCollection != null)
-        _genericCollection.CopyTo(array, arrayIndex);
-      else
-        _list.CopyTo(array, arrayIndex);
-    }
-
-    public int Count
-    {
-      get
-      {
-        if (_genericCollection != null)
-          return _genericCollection.Count;
-        else
-          return _list.Count;
-      }
-    }
-
-    public bool IsReadOnly
-    {
-      get
-      {
-        if (_genericCollection != null)
-          return _genericCollection.IsReadOnly;
-        else
-          return _list.IsReadOnly;
-      }
-    }
-
-    public bool Remove(T item)
-    {
-      if (_genericCollection != null)
-      {
-        return _genericCollection.Remove(item);
-      }
-      else
-      {
-        bool contains = _list.Contains(item);
-
-        if (contains)
-          _list.Remove(item);
-
-        return contains;
-      }
-    }
-
-    public IEnumerator<T> GetEnumerator()
-    {
-      if (_genericCollection != null)
-        return _genericCollection.GetEnumerator();
-
-      return _list.Cast<T>().GetEnumerator();
-    }
-
-    IEnumerator IEnumerable.GetEnumerator()
-    {
-      if (_genericCollection != null)
-        return _genericCollection.GetEnumerator();
-      else
-        return _list.GetEnumerator();
-    }
-
-    int IList.Add(object value)
-    {
-      VerifyValueType(value);
-      Add((T)value);
-
-      return (Count - 1);
-    }
-
-    bool IList.Contains(object value)
-    {
-      if (IsCompatibleObject(value))
-        return Contains((T)value);
-
-      return false;
-    }
-
-    int IList.IndexOf(object value)
-    {
-      if (_genericCollection != null)
-        throw new Exception("Wrapped ICollection<T> does not support IndexOf.");
-
-      if (IsCompatibleObject(value))
-        return _list.IndexOf((T)value);
-
-      return -1;
-    }
-
-    void IList.RemoveAt(int index)
-    {
-      if (_genericCollection != null)
-        throw new Exception("Wrapped ICollection<T> does not support RemoveAt.");
-
-      _list.RemoveAt(index);
-    }
-
-    void IList.Insert(int index, object value)
-    {
-      if (_genericCollection != null)
-        throw new Exception("Wrapped ICollection<T> does not support Insert.");
-
-      VerifyValueType(value);
-      _list.Insert(index, (T)value);
-    }
-
-    bool IList.IsFixedSize
-    {
-      get { return false; }
-    }
-
-    void IList.Remove(object value)
-    {
-      if (IsCompatibleObject(value))
-        Remove((T)value);
-    }
-
-    object IList.this[int index]
-    {
-      get
-      {
-        if (_genericCollection != null)
-          throw new Exception("Wrapped ICollection<T> does not support indexer.");
-
-        return _list[index];
-      }
-      set
-      {
-        if (_genericCollection != null)
-          throw new Exception("Wrapped ICollection<T> does not support indexer.");
-
-        VerifyValueType(value);
-        _list[index] = (T)value;
-      }
-    }
-
-    void ICollection.CopyTo(Array array, int arrayIndex)
-    {
-      CopyTo((T[])array, arrayIndex);
-    }
-
-    bool ICollection.IsSynchronized
-    {
-      get { return false; }
-    }
-
-    object ICollection.SyncRoot
-    {
-      get
-      {
-        if (_syncRoot == null)
-          Interlocked.CompareExchange(ref _syncRoot, new object(), null);
-
-        return _syncRoot;
-      }
-    }
-
-    private static void VerifyValueType(object value)
-    {
-      if (!IsCompatibleObject(value))
-        throw new ArgumentException("The value '{0}' is not of type '{1}' and cannot be used in this generic collection.".FormatWith(CultureInfo.InvariantCulture, value, typeof(T)), "value");
-    }
-
-    private static bool IsCompatibleObject(object value)
-    {
-      if (!(value is T) && (value != null || (typeof(T).IsValueType && !ReflectionUtils.IsNullableType(typeof(T)))))
-        return false;
-
-      return true;
-    }
-
-    public object UnderlyingCollection
-    {
-      get
-      {
-        if (_genericCollection != null)
-          return _genericCollection;
-        else
-          return _list;
-      }
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Threading;
+using System.Globalization;
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#else
+using System.Linq;
+#endif
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal interface IWrappedCollection : IList
+  {
+    object UnderlyingCollection { get; }
+  }
+
+  internal class CollectionWrapper<T> : ICollection<T>, IWrappedCollection
+  {
+    private readonly IList _list;
+    private readonly ICollection<T> _genericCollection;
+    private object _syncRoot;
+
+    public CollectionWrapper(IList list)
+    {
+      ValidationUtils.ArgumentNotNull(list, "list");
+
+      if (list is ICollection<T>)
+        _genericCollection = (ICollection<T>)list;
+      else
+        _list = list;
+    }
+
+    public CollectionWrapper(ICollection<T> list)
+    {
+      ValidationUtils.ArgumentNotNull(list, "list");
+
+      _genericCollection = list;
+    }
+
+    public virtual void Add(T item)
+    {
+      if (_genericCollection != null)
+        _genericCollection.Add(item);
+      else
+        _list.Add(item);
+    }
+
+    public virtual void Clear()
+    {
+      if (_genericCollection != null)
+        _genericCollection.Clear();
+      else
+        _list.Clear();
+    }
+
+    public virtual bool Contains(T item)
+    {
+      if (_genericCollection != null)
+        return _genericCollection.Contains(item);
+      else
+        return _list.Contains(item);
+    }
+
+    public virtual void CopyTo(T[] array, int arrayIndex)
+    {
+      if (_genericCollection != null)
+        _genericCollection.CopyTo(array, arrayIndex);
+      else
+        _list.CopyTo(array, arrayIndex);
+    }
+
+    public virtual int Count
+    {
+      get
+      {
+        if (_genericCollection != null)
+          return _genericCollection.Count;
+        else
+          return _list.Count;
+      }
+    }
+
+    public virtual bool IsReadOnly
+    {
+      get
+      {
+        if (_genericCollection != null)
+          return _genericCollection.IsReadOnly;
+        else
+          return _list.IsReadOnly;
+      }
+    }
+
+    public virtual bool Remove(T item)
+    {
+      if (_genericCollection != null)
+      {
+        return _genericCollection.Remove(item);
+      }
+      else
+      {
+        bool contains = _list.Contains(item);
+
+        if (contains)
+          _list.Remove(item);
+
+        return contains;
+      }
+    }
+
+    public virtual IEnumerator<T> GetEnumerator()
+    {
+      if (_genericCollection != null)
+        return _genericCollection.GetEnumerator();
+
+      return _list.Cast<T>().GetEnumerator();
+    }
+
+    IEnumerator IEnumerable.GetEnumerator()
+    {
+      if (_genericCollection != null)
+        return _genericCollection.GetEnumerator();
+      else
+        return _list.GetEnumerator();
+    }
+
+    int IList.Add(object value)
+    {
+      VerifyValueType(value);
+      Add((T)value);
+
+      return (Count - 1);
+    }
+
+    bool IList.Contains(object value)
+    {
+      if (IsCompatibleObject(value))
+        return Contains((T)value);
+
+      return false;
+    }
+
+    int IList.IndexOf(object value)
+    {
+      if (_genericCollection != null)
+        throw new InvalidOperationException("Wrapped ICollection<T> does not support IndexOf.");
+
+      if (IsCompatibleObject(value))
+        return _list.IndexOf((T)value);
+
+      return -1;
+    }
+
+    void IList.RemoveAt(int index)
+    {
+      if (_genericCollection != null)
+        throw new InvalidOperationException("Wrapped ICollection<T> does not support RemoveAt.");
+
+      _list.RemoveAt(index);
+    }
+
+    void IList.Insert(int index, object value)
+    {
+      if (_genericCollection != null)
+        throw new InvalidOperationException("Wrapped ICollection<T> does not support Insert.");
+
+      VerifyValueType(value);
+      _list.Insert(index, (T)value);
+    }
+
+    bool IList.IsFixedSize
+    {
+      get
+      {
+        if (_genericCollection != null)
+          // ICollection<T> only has IsReadOnly
+          return _genericCollection.IsReadOnly;
+        else
+          return _list.IsFixedSize;
+      }
+    }
+
+    void IList.Remove(object value)
+    {
+      if (IsCompatibleObject(value))
+        Remove((T)value);
+    }
+
+    object IList.this[int index]
+    {
+      get
+      {
+        if (_genericCollection != null)
+          throw new InvalidOperationException("Wrapped ICollection<T> does not support indexer.");
+
+        return _list[index];
+      }
+      set
+      {
+        if (_genericCollection != null)
+          throw new InvalidOperationException("Wrapped ICollection<T> does not support indexer.");
+
+        VerifyValueType(value);
+        _list[index] = (T)value;
+      }
+    }
+
+    void ICollection.CopyTo(Array array, int arrayIndex)
+    {
+      CopyTo((T[])array, arrayIndex);
+    }
+
+    bool ICollection.IsSynchronized
+    {
+      get { return false; }
+    }
+
+    object ICollection.SyncRoot
+    {
+      get
+      {
+        if (_syncRoot == null)
+          Interlocked.CompareExchange(ref _syncRoot, new object(), null);
+
+        return _syncRoot;
+      }
+    }
+
+    private static void VerifyValueType(object value)
+    {
+      if (!IsCompatibleObject(value))
+        throw new ArgumentException("The value '{0}' is not of type '{1}' and cannot be used in this generic collection.".FormatWith(CultureInfo.InvariantCulture, value, typeof(T)), "value");
+    }
+
+    private static bool IsCompatibleObject(object value)
+    {
+      if (!(value is T) && (value != null || (typeof(T).IsValueType() && !ReflectionUtils.IsNullableType(typeof(T)))))
+        return false;
+
+      return true;
+    }
+
+    public object UnderlyingCollection
+    {
+      get
+      {
+        if (_genericCollection != null)
+          return _genericCollection;
+        else
+          return _list;
+      }
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs
index 4c9ea1d..25286a8 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs
@@ -1,511 +1,498 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Globalization;
-using System.ComponentModel;
-using Newtonsoft.Json.Serialization;
-using System.Reflection;
-
-#if !SILVERLIGHT
-using System.Data.SqlTypes;
-#endif
-
-namespace Newtonsoft.Json.Utilities
-{
-  internal static class ConvertUtils
-  {
-    internal struct TypeConvertKey : IEquatable<TypeConvertKey>
-    {
-      private readonly Type _initialType;
-      private readonly Type _targetType;
-
-      public Type InitialType
-      {
-        get { return _initialType; }
-      }
-
-      public Type TargetType
-      {
-        get { return _targetType; }
-      }
-
-      public TypeConvertKey(Type initialType, Type targetType)
-      {
-        _initialType = initialType;
-        _targetType = targetType;
-      }
-
-      public override int GetHashCode()
-      {
-        return _initialType.GetHashCode() ^ _targetType.GetHashCode();
-      }
-
-      public override bool Equals(object obj)
-      {
-        if (!(obj is TypeConvertKey))
-          return false;
-
-        return Equals((TypeConvertKey)obj);
-      }
-
-      public bool Equals(TypeConvertKey other)
-      {
-        return (_initialType == other._initialType && _targetType == other._targetType);
-      }
-    }
-
-    private static readonly ThreadSafeStore<TypeConvertKey, Func<object, object>> CastConverters =
-      new ThreadSafeStore<TypeConvertKey, Func<object, object>>(CreateCastConverter);
-
-    private static Func<object, object> CreateCastConverter(TypeConvertKey t)
-    {
-      MethodInfo castMethodInfo = t.TargetType.GetMethod("op_Implicit", new[] { t.InitialType });
-      if (castMethodInfo == null)
-        castMethodInfo = t.TargetType.GetMethod("op_Explicit", new[] { t.InitialType });
-
-      if (castMethodInfo == null)
-        return null;
-
-      MethodCall<object, object> call = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall<object>(castMethodInfo);
-
-      return o => call(null, o);
-    }
-
-    public static bool CanConvertType(Type initialType, Type targetType, bool allowTypeNameToString)
-    {
-      ValidationUtils.ArgumentNotNull(initialType, "initialType");
-      ValidationUtils.ArgumentNotNull(targetType, "targetType");
-
-      if (ReflectionUtils.IsNullableType(targetType))
-        targetType = Nullable.GetUnderlyingType(targetType);
-
-      if (targetType == initialType)
-        return true;
-
-      if (typeof(IConvertible).IsAssignableFrom(initialType) && typeof(IConvertible).IsAssignableFrom(targetType))
-      {
-        return true;
-      }
-
-#if !PocketPC && !NET20
-      if (initialType == typeof(DateTime) && targetType == typeof(DateTimeOffset))
-        return true;
-#endif
-
-      if (initialType == typeof(Guid) && (targetType == typeof(Guid) || targetType == typeof(string)))
-        return true;
-
-      if (initialType == typeof(Type) && targetType == typeof(string))
-        return true;
-
-#if !PocketPC
-      // see if source or target types have a TypeConverter that converts between the two
-      TypeConverter toConverter = GetConverter(initialType);
-
-      if (toConverter != null && !IsComponentConverter(toConverter) && toConverter.CanConvertTo(targetType))
-      {
-        if (allowTypeNameToString || toConverter.GetType() != typeof(TypeConverter))
-          return true;
-      }
-
-      TypeConverter fromConverter = GetConverter(targetType);
-
-      if (fromConverter != null && !IsComponentConverter(fromConverter) && fromConverter.CanConvertFrom(initialType))
-        return true;
-#endif
-
-      // handle DBNull and INullable
-      if (initialType == typeof(DBNull))
-      {
-        if (ReflectionUtils.IsNullable(targetType))
-          return true;
-      }
-
-      return false;
-    }
-
-    private static bool IsComponentConverter(TypeConverter converter)
-    {
-#if !SILVERLIGHT && !PocketPC
-      return (converter is ComponentConverter);
-#else
-      return false;
-#endif
-    }
-
-    #region Convert
-    /// <summary>
-    /// Converts the value to the specified type.
-    /// </summary>
-    /// <typeparam name="T">The type to convert the value to.</typeparam>
-    /// <param name="initialValue">The value to convert.</param>
-    /// <returns>The converted type.</returns>
-    public static T Convert<T>(object initialValue)
-    {
-      return Convert<T>(initialValue, CultureInfo.CurrentCulture);
-    }
-
-    /// <summary>
-    /// Converts the value to the specified type.
-    /// </summary>
-    /// <typeparam name="T">The type to convert the value to.</typeparam>
-    /// <param name="initialValue">The value to convert.</param>
-    /// <param name="culture">The culture to use when converting.</param>
-    /// <returns>The converted type.</returns>
-    public static T Convert<T>(object initialValue, CultureInfo culture)
-    {
-      return (T)Convert(initialValue, culture, typeof(T));
-    }
-
-    /// <summary>
-    /// Converts the value to the specified type.
-    /// </summary>
-    /// <param name="initialValue">The value to convert.</param>
-    /// <param name="culture">The culture to use when converting.</param>
-    /// <param name="targetType">The type to convert the value to.</param>
-    /// <returns>The converted type.</returns>
-    public static object Convert(object initialValue, CultureInfo culture, Type targetType)
-    {
-      if (initialValue == null)
-        throw new ArgumentNullException("initialValue");
-
-      if (ReflectionUtils.IsNullableType(targetType))
-        targetType = Nullable.GetUnderlyingType(targetType);
-
-      Type initialType = initialValue.GetType();
-
-      if (targetType == initialType)
-        return initialValue;
-
-      if (initialValue is string && typeof(Type).IsAssignableFrom(targetType))
-        return Type.GetType((string) initialValue, true);
-
-      if (targetType.IsInterface || targetType.IsGenericTypeDefinition || targetType.IsAbstract)
-        throw new ArgumentException("Target type {0} is not a value type or a non-abstract class.".FormatWith(CultureInfo.InvariantCulture, targetType), "targetType");
-
-      // use Convert.ChangeType if both types are IConvertible
-      if (initialValue is IConvertible && typeof(IConvertible).IsAssignableFrom(targetType))
-      {
-        if (targetType.IsEnum)
-        {
-          if (initialValue is string)
-            return Enum.Parse(targetType, initialValue.ToString(), true);
-          else if (IsInteger(initialValue))
-            return Enum.ToObject(targetType, initialValue);
-        }
-        
-        return System.Convert.ChangeType(initialValue, targetType, culture);
-      }
-
-#if !PocketPC && !NET20
-      if (initialValue is DateTime && targetType == typeof(DateTimeOffset))
-        return new DateTimeOffset((DateTime)initialValue);
-#endif
-
-      if (initialValue is string)
-      {
-        if (targetType == typeof (Guid))
-          return new Guid((string) initialValue);
-        if (targetType == typeof (Uri))
-          return new Uri((string) initialValue);
-        if (targetType == typeof (TimeSpan))
-          return TimeSpan.Parse((string) initialValue);
-      }
-
-#if !PocketPC
-      // see if source or target types have a TypeConverter that converts between the two
-      TypeConverter toConverter = GetConverter(initialType);
-
-      if (toConverter != null && toConverter.CanConvertTo(targetType))
-      {
-#if !SILVERLIGHT
-        return toConverter.ConvertTo(null, culture, initialValue, targetType);
-#else
-        return toConverter.ConvertTo(initialValue, targetType);
-#endif
-      }
-
-      TypeConverter fromConverter = GetConverter(targetType);
-
-      if (fromConverter != null && fromConverter.CanConvertFrom(initialType))
-      {
-#if !SILVERLIGHT
-        return fromConverter.ConvertFrom(null, culture, initialValue);
-#else
-        return fromConverter.ConvertFrom(initialValue);
-#endif
-      }
-#endif
-
-      // handle DBNull and INullable
-      if (initialValue == DBNull.Value)
-      {
-        if (ReflectionUtils.IsNullable(targetType))
-          return EnsureTypeAssignable(null, initialType, targetType);
-        
-        throw new Exception("Can not convert null {0} into non-nullable {1}.".FormatWith(CultureInfo.InvariantCulture, initialType, targetType));
-      }
-#if !SILVERLIGHT
-      if (initialValue is INullable)
-        return EnsureTypeAssignable(ToValue((INullable)initialValue), initialType, targetType);
-#endif
-
-      throw new Exception("Can not convert from {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, initialType, targetType));
-    }
-    #endregion
-
-    #region TryConvert
-    /// <summary>
-    /// Converts the value to the specified type.
-    /// </summary>
-    /// <typeparam name="T">The type to convert the value to.</typeparam>
-    /// <param name="initialValue">The value to convert.</param>
-    /// <param name="convertedValue">The converted value if the conversion was successful or the default value of <c>T</c> if it failed.</param>
-    /// <returns>
-    /// 	<c>true</c> if <c>initialValue</c> was converted successfully; otherwise, <c>false</c>.
-    /// </returns>
-    public static bool TryConvert<T>(object initialValue, out T convertedValue)
-    {
-      return TryConvert(initialValue, CultureInfo.CurrentCulture, out convertedValue);
-    }
-
-    /// <summary>
-    /// Converts the value to the specified type.
-    /// </summary>
-    /// <typeparam name="T">The type to convert the value to.</typeparam>
-    /// <param name="initialValue">The value to convert.</param>
-    /// <param name="culture">The culture to use when converting.</param>
-    /// <param name="convertedValue">The converted value if the conversion was successful or the default value of <c>T</c> if it failed.</param>
-    /// <returns>
-    /// 	<c>true</c> if <c>initialValue</c> was converted successfully; otherwise, <c>false</c>.
-    /// </returns>
-    public static bool TryConvert<T>(object initialValue, CultureInfo culture, out T convertedValue)
-    {
-      return MiscellaneousUtils.TryAction<T>(delegate
-      {
-        object tempConvertedValue;
-        TryConvert(initialValue, CultureInfo.CurrentCulture, typeof(T), out tempConvertedValue);
-
-        return (T)tempConvertedValue;
-      }, out convertedValue);
-    }
-
-    /// <summary>
-    /// Converts the value to the specified type.
-    /// </summary>
-    /// <param name="initialValue">The value to convert.</param>
-    /// <param name="culture">The culture to use when converting.</param>
-    /// <param name="targetType">The type to convert the value to.</param>
-    /// <param name="convertedValue">The converted value if the conversion was successful or the default value of <c>T</c> if it failed.</param>
-    /// <returns>
-    /// 	<c>true</c> if <c>initialValue</c> was converted successfully; otherwise, <c>false</c>.
-    /// </returns>
-    public static bool TryConvert(object initialValue, CultureInfo culture, Type targetType, out object convertedValue)
-    {
-      return MiscellaneousUtils.TryAction<object>(delegate { return Convert(initialValue, culture, targetType); }, out convertedValue);
-    }
-    #endregion
-
-    #region ConvertOrCast
-    /// <summary>
-    /// Converts the value to the specified type. If the value is unable to be converted, the
-    /// value is checked whether it assignable to the specified type.
-    /// </summary>
-    /// <typeparam name="T">The type to convert or cast the value to.</typeparam>
-    /// <param name="initialValue">The value to convert.</param>
-    /// <returns>The converted type. If conversion was unsuccessful, the initial value is returned if assignable to the target type</returns>
-    public static T ConvertOrCast<T>(object initialValue)
-    {
-      return ConvertOrCast<T>(initialValue, CultureInfo.CurrentCulture);
-    }
-
-    /// <summary>
-    /// Converts the value to the specified type. If the value is unable to be converted, the
-    /// value is checked whether it assignable to the specified type.
-    /// </summary>
-    /// <typeparam name="T">The type to convert or cast the value to.</typeparam>
-    /// <param name="initialValue">The value to convert.</param>
-    /// <param name="culture">The culture to use when converting.</param>
-    /// <returns>The converted type. If conversion was unsuccessful, the initial value is returned if assignable to the target type</returns>
-    public static T ConvertOrCast<T>(object initialValue, CultureInfo culture)
-    {
-      return (T)ConvertOrCast(initialValue, culture, typeof(T));
-    }
-
-    /// <summary>
-    /// Converts the value to the specified type. If the value is unable to be converted, the
-    /// value is checked whether it assignable to the specified type.
-    /// </summary>
-    /// <param name="initialValue">The value to convert.</param>
-    /// <param name="culture">The culture to use when converting.</param>
-    /// <param name="targetType">The type to convert or cast the value to.</param>
-    /// <returns>
-    /// The converted type. If conversion was unsuccessful, the initial value
-    /// is returned if assignable to the target type.
-    /// </returns>
-    public static object ConvertOrCast(object initialValue, CultureInfo culture, Type targetType)
-    {
-      object convertedValue;
-
-      if (targetType == typeof(object))
-        return initialValue;
-
-      if (initialValue == null && ReflectionUtils.IsNullable(targetType))
-        return null;
-
-      if (TryConvert(initialValue, culture, targetType, out convertedValue))
-        return convertedValue;
-
-      return EnsureTypeAssignable(initialValue, ReflectionUtils.GetObjectType(initialValue), targetType);
-    }
-    #endregion
-
-    #region TryConvertOrCast
-    /// <summary>
-    /// Converts the value to the specified type. If the value is unable to be converted, the
-    /// value is checked whether it assignable to the specified type.
-    /// </summary>
-    /// <typeparam name="T">The type to convert the value to.</typeparam>
-    /// <param name="initialValue">The value to convert.</param>
-    /// <param name="convertedValue">The converted value if the conversion was successful or the default value of <c>T</c> if it failed.</param>
-    /// <returns>
-    /// 	<c>true</c> if <c>initialValue</c> was converted successfully or is assignable; otherwise, <c>false</c>.
-    /// </returns>
-    public static bool TryConvertOrCast<T>(object initialValue, out T convertedValue)
-    {
-      return TryConvertOrCast<T>(initialValue, CultureInfo.CurrentCulture, out convertedValue);
-    }
-
-    /// <summary>
-    /// Converts the value to the specified type. If the value is unable to be converted, the
-    /// value is checked whether it assignable to the specified type.
-    /// </summary>
-    /// <typeparam name="T">The type to convert the value to.</typeparam>
-    /// <param name="initialValue">The value to convert.</param>
-    /// <param name="culture">The culture to use when converting.</param>
-    /// <param name="convertedValue">The converted value if the conversion was successful or the default value of <c>T</c> if it failed.</param>
-    /// <returns>
-    /// 	<c>true</c> if <c>initialValue</c> was converted successfully or is assignable; otherwise, <c>false</c>.
-    /// </returns>
-    public static bool TryConvertOrCast<T>(object initialValue, CultureInfo culture, out T convertedValue)
-    {
-      return MiscellaneousUtils.TryAction<T>(delegate
-      {
-        object tempConvertedValue;
-        TryConvertOrCast(initialValue, CultureInfo.CurrentCulture, typeof(T), out tempConvertedValue);
-
-        return (T)tempConvertedValue;
-      }, out convertedValue);
-    }
-
-    /// <summary>
-    /// Converts the value to the specified type. If the value is unable to be converted, the
-    /// value is checked whether it assignable to the specified type.
-    /// </summary>
-    /// <param name="initialValue">The value to convert.</param>
-    /// <param name="culture">The culture to use when converting.</param>
-    /// <param name="targetType">The type to convert the value to.</param>
-    /// <param name="convertedValue">The converted value if the conversion was successful or the default value of <c>T</c> if it failed.</param>
-    /// <returns>
-    /// 	<c>true</c> if <c>initialValue</c> was converted successfully or is assignable; otherwise, <c>false</c>.
-    /// </returns>
-    public static bool TryConvertOrCast(object initialValue, CultureInfo culture, Type targetType, out object convertedValue)
-    {
-      return MiscellaneousUtils.TryAction<object>(delegate { return ConvertOrCast(initialValue, culture, targetType); }, out convertedValue);
-    }
-    #endregion
-
-    private static object EnsureTypeAssignable(object value, Type initialType, Type targetType)
-    {
-      Type valueType = (value != null) ? value.GetType() : null;
-
-      if (value != null)
-      {
-        if (targetType.IsAssignableFrom(valueType))
-          return value;
-
-        Func<object, object> castConverter = CastConverters.Get(new TypeConvertKey(valueType, targetType));
-        if (castConverter != null)
-          return castConverter(value);
-      }
-      else
-      {
-        if (ReflectionUtils.IsNullable(targetType))
-          return null;
-      }
-
-      throw new Exception("Could not cast or convert from {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, (initialType != null) ? initialType.ToString() : "{null}", targetType));
-    }
-
-#if !SILVERLIGHT
-    public static object ToValue(INullable nullableValue)
-    {
-      if (nullableValue == null)
-        return null;
-      else if (nullableValue is SqlInt32)
-        return ToValue((SqlInt32)nullableValue);
-      else if (nullableValue is SqlInt64)
-        return ToValue((SqlInt64)nullableValue);
-      else if (nullableValue is SqlBoolean)
-        return ToValue((SqlBoolean)nullableValue);
-      else if (nullableValue is SqlString)
-        return ToValue((SqlString)nullableValue);
-      else if (nullableValue is SqlDateTime)
-        return ToValue((SqlDateTime)nullableValue);
-
-      throw new Exception("Unsupported INullable type: {0}".FormatWith(CultureInfo.InvariantCulture, nullableValue.GetType()));
-    }
-#endif
-
-#if !PocketPC
-    internal static TypeConverter GetConverter(Type t)
-    {
-      return JsonTypeReflector.GetTypeConverter(t);
-    }
-#endif
-
-    public static bool IsInteger(object value)
-    {
-      switch (System.Convert.GetTypeCode(value))
-      {
-        case TypeCode.SByte:
-        case TypeCode.Byte:
-        case TypeCode.Int16:
-        case TypeCode.UInt16:
-        case TypeCode.Int32:
-        case TypeCode.UInt32:
-        case TypeCode.Int64:
-        case TypeCode.UInt64:
-          return true;
-        default:
-          return false;
-      }
-    }
-  }
-}
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Globalization;
+using System.ComponentModel;
+using Newtonsoft.Json.Serialization;
+using System.Reflection;
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#endif
+
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+using System.Data.SqlTypes;
+#endif
+#if NETFX_CORE
+using IConvertible = Newtonsoft.Json.Utilities.Convertible;
+#endif
+
+namespace Newtonsoft.Json.Utilities
+{
+#if NETFX_CORE
+  internal class Convertible
+  {
+    private object _underlyingValue;
+
+    public Convertible(object o)
+    {
+      _underlyingValue = o;
+    }
+
+    public TypeCode GetTypeCode()
+    {
+      return ConvertUtils.GetTypeCode(_underlyingValue);
+    }
+
+    public bool ToBoolean(IFormatProvider provider)
+    {
+      return Convert.ToBoolean(_underlyingValue, provider);
+    }
+    public byte ToByte(IFormatProvider provider)
+    {
+      return Convert.ToByte(_underlyingValue, provider);
+    }
+    public char ToChar(IFormatProvider provider)
+    {
+      return Convert.ToChar(_underlyingValue, provider);
+    }
+    public DateTime ToDateTime(IFormatProvider provider)
+    {
+      return Convert.ToDateTime(_underlyingValue, provider);
+    }
+    public decimal ToDecimal(IFormatProvider provider)
+    {
+      return Convert.ToDecimal(_underlyingValue, provider);
+    }
+    public double ToDouble(IFormatProvider provider)
+    {
+      return Convert.ToDouble(_underlyingValue, provider);
+    }
+    public short ToInt16(IFormatProvider provider)
+    {
+      return Convert.ToInt16(_underlyingValue, provider);
+    }
+    public int ToInt32(IFormatProvider provider)
+    {
+      return Convert.ToInt32(_underlyingValue, provider);
+    }
+    public long ToInt64(IFormatProvider provider)
+    {
+      return Convert.ToInt64(_underlyingValue, provider);
+    }
+    public sbyte ToSByte(IFormatProvider provider)
+    {
+      return Convert.ToSByte(_underlyingValue, provider);
+    }
+    public float ToSingle(IFormatProvider provider)
+    {
+      return Convert.ToSingle(_underlyingValue, provider);
+    }
+    public string ToString(IFormatProvider provider)
+    {
+      return Convert.ToString(_underlyingValue, provider);
+    }
+    public object ToType(Type conversionType, IFormatProvider provider)
+    {
+      return Convert.ChangeType(_underlyingValue, conversionType, provider);
+    }
+    public ushort ToUInt16(IFormatProvider provider)
+    {
+      return Convert.ToUInt16(_underlyingValue, provider);
+    }
+    public uint ToUInt32(IFormatProvider provider)
+    {
+      return Convert.ToUInt32(_underlyingValue, provider);
+    }
+    public ulong ToUInt64(IFormatProvider provider)
+    {
+      return Convert.ToUInt64(_underlyingValue, provider);
+    }
+  }
+#endif
+
+  internal static class ConvertUtils
+  {
+    public static TypeCode GetTypeCode(this IConvertible convertible)
+    {
+#if !NETFX_CORE
+      return convertible.GetTypeCode();
+#else
+      return GetTypeCode((object)convertible);
+#endif
+    }
+
+    public static TypeCode GetTypeCode(object o)
+    {
+#if !(NETFX_CORE || PORTABLE)
+      return System.Convert.GetTypeCode(o);
+#else
+      return GetTypeCode(o.GetType());
+#endif
+    }
+
+    public static TypeCode GetTypeCode(Type t)
+    {
+#if !NETFX_CORE
+      return Type.GetTypeCode(t);
+#else
+      if (t == typeof(bool))
+        return TypeCode.Boolean;
+      if (t == typeof(byte))
+        return TypeCode.Byte;
+      if (t == typeof(char))
+        return TypeCode.Char;
+      if (t == typeof(DateTime))
+        return TypeCode.DateTime;
+      if (t == typeof(decimal))
+        return TypeCode.Decimal;
+      if (t == typeof(double))
+        return TypeCode.Double;
+      if (t == typeof(short))
+        return TypeCode.Int16;
+      if (t == typeof(int))
+        return TypeCode.Int32;
+      if (t == typeof(long))
+        return TypeCode.Int64;
+      if (t == typeof(sbyte))
+        return TypeCode.SByte;
+      if (t == typeof(float))
+        return TypeCode.Single;
+      if (t == typeof(string))
+        return TypeCode.String;
+      if (t == typeof(ushort))
+        return TypeCode.UInt16;
+      if (t == typeof(uint))
+        return TypeCode.UInt32;
+      if (t == typeof(ulong))
+        return TypeCode.UInt64;
+      if (t.IsEnum())
+        return GetTypeCode(Enum.GetUnderlyingType(t));
+
+      return TypeCode.Object;
+#endif
+    }
+
+    public static IConvertible ToConvertible(object o)
+    {
+#if !NETFX_CORE
+      return o as IConvertible;
+#else
+      if (!IsConvertible(o))
+        return null;
+
+      return new IConvertible(o);
+#endif
+    }
+
+    public static bool IsConvertible(object o)
+    {
+#if !NETFX_CORE
+      return o is IConvertible;
+#else
+      if (o == null)
+        return false;
+
+      return (
+        o is bool || o is byte || o is char || o is DateTime || o is decimal || o is double || o is short || o is int ||
+        o is long || o is sbyte || o is float || o is string || o is ushort || o is uint || o is ulong || o is Enum);
+#endif
+    }
+
+    public static bool IsConvertible(Type t)
+    {
+#if !NETFX_CORE
+      return typeof(IConvertible).IsAssignableFrom(t);
+#else
+      return (
+        t == typeof(bool) || t == typeof(byte) || t == typeof(char) || t == typeof(DateTime) || t == typeof(decimal) || t == typeof(double) || t == typeof(short) || t == typeof(int) ||
+        t == typeof(long) || t == typeof(sbyte) || t == typeof(float) || t == typeof(string) || t == typeof(ushort) || t == typeof(uint) || t == typeof(ulong) || t.IsEnum());
+#endif
+    }
+
+    internal struct TypeConvertKey : IEquatable<TypeConvertKey>
+    {
+      private readonly Type _initialType;
+      private readonly Type _targetType;
+
+      public Type InitialType
+      {
+        get { return _initialType; }
+      }
+
+      public Type TargetType
+      {
+        get { return _targetType; }
+      }
+
+      public TypeConvertKey(Type initialType, Type targetType)
+      {
+        _initialType = initialType;
+        _targetType = targetType;
+      }
+
+      public override int GetHashCode()
+      {
+        return _initialType.GetHashCode() ^ _targetType.GetHashCode();
+      }
+
+      public override bool Equals(object obj)
+      {
+        if (!(obj is TypeConvertKey))
+          return false;
+
+        return Equals((TypeConvertKey)obj);
+      }
+
+      public bool Equals(TypeConvertKey other)
+      {
+        return (_initialType == other._initialType && _targetType == other._targetType);
+      }
+    }
+
+    private static readonly ThreadSafeStore<TypeConvertKey, Func<object, object>> CastConverters =
+      new ThreadSafeStore<TypeConvertKey, Func<object, object>>(CreateCastConverter);
+
+    private static Func<object, object> CreateCastConverter(TypeConvertKey t)
+    {
+      MethodInfo castMethodInfo = t.TargetType.GetMethod("op_Implicit", new[] { t.InitialType });
+      if (castMethodInfo == null)
+        castMethodInfo = t.TargetType.GetMethod("op_Explicit", new[] { t.InitialType });
+
+      if (castMethodInfo == null)
+        return null;
+
+      MethodCall<object, object> call = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall<object>(castMethodInfo);
+
+      return o => call(null, o);
+    }
+
+    #region Convert
+    /// <summary>
+    /// Converts the value to the specified type.
+    /// </summary>
+    /// <param name="initialValue">The value to convert.</param>
+    /// <param name="culture">The culture to use when converting.</param>
+    /// <param name="targetType">The type to convert the value to.</param>
+    /// <returns>The converted type.</returns>
+    public static object Convert(object initialValue, CultureInfo culture, Type targetType)
+    {
+      if (initialValue == null)
+        throw new ArgumentNullException("initialValue");
+
+      if (ReflectionUtils.IsNullableType(targetType))
+        targetType = Nullable.GetUnderlyingType(targetType);
+
+      Type initialType = initialValue.GetType();
+
+      if (targetType == initialType)
+        return initialValue;
+
+      // use Convert.ChangeType if both types are IConvertible
+      if (ConvertUtils.IsConvertible(initialValue) && ConvertUtils.IsConvertible(targetType))
+      {
+        if (targetType.IsEnum())
+        {
+          if (initialValue is string)
+            return Enum.Parse(targetType, initialValue.ToString(), true);
+          else if (IsInteger(initialValue))
+            return Enum.ToObject(targetType, initialValue);
+        }
+
+        return System.Convert.ChangeType(initialValue, targetType, culture);
+      }
+
+      if (initialValue is string && typeof(Type).IsAssignableFrom(targetType))
+        return Type.GetType((string) initialValue, true);
+
+      if (targetType.IsInterface() || targetType.IsGenericTypeDefinition() || targetType.IsAbstract())
+        throw new ArgumentException("Target type {0} is not a value type or a non-abstract class.".FormatWith(CultureInfo.InvariantCulture, targetType), "targetType");
+
+#if !PocketPC && !NET20
+      if (initialValue is DateTime && targetType == typeof(DateTimeOffset))
+        return new DateTimeOffset((DateTime)initialValue);
+#endif
+
+      if (initialValue is string)
+      {
+        if (targetType == typeof (Guid))
+          return new Guid((string) initialValue);
+        if (targetType == typeof (Uri))
+          return new Uri((string) initialValue, UriKind.RelativeOrAbsolute);
+        if (targetType == typeof (TimeSpan))
+#if !(NET35 || NET20 || SILVERLIGHT || PORTABLE)
+          return TimeSpan.Parse((string) initialValue, CultureInfo.InvariantCulture);
+#else
+          return TimeSpan.Parse((string)initialValue);
+#endif
+      }
+
+#if !(NETFX_CORE || PORTABLE)
+      // see if source or target types have a TypeConverter that converts between the two
+      TypeConverter toConverter = GetConverter(initialType);
+
+      if (toConverter != null && toConverter.CanConvertTo(targetType))
+      {
+#if !SILVERLIGHT
+        return toConverter.ConvertTo(null, culture, initialValue, targetType);
+#else
+        return toConverter.ConvertTo(initialValue, targetType);
+#endif
+      }
+
+      TypeConverter fromConverter = GetConverter(targetType);
+
+      if (fromConverter != null && fromConverter.CanConvertFrom(initialType))
+      {
+#if !SILVERLIGHT
+        return fromConverter.ConvertFrom(null, culture, initialValue);
+#else
+        return fromConverter.ConvertFrom(initialValue);
+#endif
+      }
+#endif
+#if !(NETFX_CORE || PORTABLE)
+      // handle DBNull and INullable
+      if (initialValue == DBNull.Value)
+      {
+        if (ReflectionUtils.IsNullable(targetType))
+          return EnsureTypeAssignable(null, initialType, targetType);
+        
+        throw new Exception("Can not convert null {0} into non-nullable {1}.".FormatWith(CultureInfo.InvariantCulture, initialType, targetType));
+      }
+#endif
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+      if (initialValue is INullable)
+        return EnsureTypeAssignable(ToValue((INullable)initialValue), initialType, targetType);
+#endif
+
+      throw new InvalidOperationException("Can not convert from {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, initialType, targetType));
+    }
+    #endregion
+
+    #region TryConvert
+    /// <summary>
+    /// Converts the value to the specified type.
+    /// </summary>
+    /// <param name="initialValue">The value to convert.</param>
+    /// <param name="culture">The culture to use when converting.</param>
+    /// <param name="targetType">The type to convert the value to.</param>
+    /// <param name="convertedValue">The converted value if the conversion was successful or the default value of <c>T</c> if it failed.</param>
+    /// <returns>
+    /// 	<c>true</c> if <c>initialValue</c> was converted successfully; otherwise, <c>false</c>.
+    /// </returns>
+    public static bool TryConvert(object initialValue, CultureInfo culture, Type targetType, out object convertedValue)
+    {
+      return MiscellaneousUtils.TryAction<object>(delegate { return Convert(initialValue, culture, targetType); }, out convertedValue);
+    }
+    #endregion
+
+    #region ConvertOrCast
+    /// <summary>
+    /// Converts the value to the specified type. If the value is unable to be converted, the
+    /// value is checked whether it assignable to the specified type.
+    /// </summary>
+    /// <param name="initialValue">The value to convert.</param>
+    /// <param name="culture">The culture to use when converting.</param>
+    /// <param name="targetType">The type to convert or cast the value to.</param>
+    /// <returns>
+    /// The converted type. If conversion was unsuccessful, the initial value
+    /// is returned if assignable to the target type.
+    /// </returns>
+    public static object ConvertOrCast(object initialValue, CultureInfo culture, Type targetType)
+    {
+      object convertedValue;
+
+      if (targetType == typeof(object))
+        return initialValue;
+
+      if (initialValue == null && ReflectionUtils.IsNullable(targetType))
+        return null;
+
+      if (TryConvert(initialValue, culture, targetType, out convertedValue))
+        return convertedValue;
+
+      return EnsureTypeAssignable(initialValue, ReflectionUtils.GetObjectType(initialValue), targetType);
+    }
+    #endregion
+
+    private static object EnsureTypeAssignable(object value, Type initialType, Type targetType)
+    {
+      Type valueType = (value != null) ? value.GetType() : null;
+
+      if (value != null)
+      {
+        if (targetType.IsAssignableFrom(valueType))
+          return value;
+
+        Func<object, object> castConverter = CastConverters.Get(new TypeConvertKey(valueType, targetType));
+        if (castConverter != null)
+          return castConverter(value);
+      }
+      else
+      {
+        if (ReflectionUtils.IsNullable(targetType))
+          return null;
+      }
+
+      throw new ArgumentException("Could not cast or convert from {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, (initialType != null) ? initialType.ToString() : "{null}", targetType));
+    }
+
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+    public static object ToValue(INullable nullableValue)
+    {
+      if (nullableValue == null)
+        return null;
+      else if (nullableValue is SqlInt32)
+        return ToValue((SqlInt32)nullableValue);
+      else if (nullableValue is SqlInt64)
+        return ToValue((SqlInt64)nullableValue);
+      else if (nullableValue is SqlBoolean)
+        return ToValue((SqlBoolean)nullableValue);
+      else if (nullableValue is SqlString)
+        return ToValue((SqlString)nullableValue);
+      else if (nullableValue is SqlDateTime)
+        return ToValue((SqlDateTime)nullableValue);
+
+      throw new ArgumentException("Unsupported INullable type: {0}".FormatWith(CultureInfo.InvariantCulture, nullableValue.GetType()));
+    }
+#endif
+
+#if !(NETFX_CORE || PORTABLE)
+    internal static TypeConverter GetConverter(Type t)
+    {
+      return JsonTypeReflector.GetTypeConverter(t);
+    }
+#endif
+
+    public static bool IsInteger(object value)
+    {
+      switch (GetTypeCode(value))
+      {
+        case TypeCode.SByte:
+        case TypeCode.Byte:
+        case TypeCode.Int16:
+        case TypeCode.UInt16:
+        case TypeCode.Int32:
+        case TypeCode.UInt32:
+        case TypeCode.Int64:
+        case TypeCode.UInt64:
+          return true;
+        default:
+          return false;
+      }
+    }
+  }
+}
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DateTimeUtils.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DateTimeUtils.cs
index 21100cd..9330c5b 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DateTimeUtils.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DateTimeUtils.cs
@@ -1,39 +1,67 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Xml;
-using System.Globalization;
-
-namespace Newtonsoft.Json.Utilities
-{
-  internal static class DateTimeUtils
-  {
-    public static string GetLocalOffset(this DateTime d)
-    {
-      TimeSpan utcOffset;
-#if PocketPC || NET20
-      utcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(d);
-#else
-      utcOffset = TimeZoneInfo.Local.GetUtcOffset(d);
-#endif
-
-      return utcOffset.Hours.ToString("+00;-00", CultureInfo.InvariantCulture) + ":" + utcOffset.Minutes.ToString("00;00", CultureInfo.InvariantCulture);
-    }
-
-    public static XmlDateTimeSerializationMode ToSerializationMode(DateTimeKind kind)
-    {
-      switch (kind)
-      {
-        case DateTimeKind.Local:
-          return XmlDateTimeSerializationMode.Local;
-        case DateTimeKind.Unspecified:
-          return XmlDateTimeSerializationMode.Unspecified;
-        case DateTimeKind.Utc:
-          return XmlDateTimeSerializationMode.Utc;
-        default:
-          throw MiscellaneousUtils.CreateArgumentOutOfRangeException("kind", kind, "Unexpected DateTimeKind value.");
-      }
-    }
-  }
-}
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Xml;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal static class DateTimeUtils
+  {
+    public static string GetUtcOffsetText(this DateTime d)
+    {
+      TimeSpan utcOffset = d.GetUtcOffset();
+
+      return utcOffset.Hours.ToString("+00;-00", CultureInfo.InvariantCulture) + ":" + utcOffset.Minutes.ToString("00;00", CultureInfo.InvariantCulture);
+    }
+
+    public static TimeSpan GetUtcOffset(this DateTime d)
+    {
+#if NET20
+      return TimeZone.CurrentTimeZone.GetUtcOffset(d);
+#else
+      return TimeZoneInfo.Local.GetUtcOffset(d);
+#endif
+    }
+
+#if !(NETFX_CORE || PORTABLE)
+    public static XmlDateTimeSerializationMode ToSerializationMode(DateTimeKind kind)
+    {
+      switch (kind)
+      {
+        case DateTimeKind.Local:
+          return XmlDateTimeSerializationMode.Local;
+        case DateTimeKind.Unspecified:
+          return XmlDateTimeSerializationMode.Unspecified;
+        case DateTimeKind.Utc:
+          return XmlDateTimeSerializationMode.Utc;
+        default:
+          throw MiscellaneousUtils.CreateArgumentOutOfRangeException("kind", kind, "Unexpected DateTimeKind value.");
+      }
+    }
+#endif
+  }
+}
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DictionaryWrapper.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DictionaryWrapper.cs
index d67734d..8d45e66 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DictionaryWrapper.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DictionaryWrapper.cs
@@ -1,400 +1,424 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Collections;
-using System.Threading;
-
-namespace Newtonsoft.Json.Utilities
-{
-  internal interface IWrappedDictionary : IDictionary
-  {
-    object UnderlyingDictionary { get; }
-  }
-
-  internal class DictionaryWrapper<TKey, TValue> : IDictionary<TKey, TValue>, IWrappedDictionary
-  {
-    private readonly IDictionary _dictionary;
-    private readonly IDictionary<TKey, TValue> _genericDictionary;
-    private object _syncRoot;
-
-    public DictionaryWrapper(IDictionary dictionary)
-    {
-      ValidationUtils.ArgumentNotNull(dictionary, "dictionary");
-
-      _dictionary = dictionary;
-    }
-
-    public DictionaryWrapper(IDictionary<TKey, TValue> dictionary)
-    {
-      ValidationUtils.ArgumentNotNull(dictionary, "dictionary");
-
-      _genericDictionary = dictionary;
-    }
-
-    public void Add(TKey key, TValue value)
-    {
-      if (_genericDictionary != null)
-        _genericDictionary.Add(key, value);
-      else
-        _dictionary.Add(key, value);
-    }
-
-    public bool ContainsKey(TKey key)
-    {
-      if (_genericDictionary != null)
-        return _genericDictionary.ContainsKey(key);
-      else
-        return _dictionary.Contains(key);
-    }
-
-    public ICollection<TKey> Keys
-    {
-      get
-      {
-        if (_genericDictionary != null)
-          return _genericDictionary.Keys;
-        else
-          return _dictionary.Keys.Cast<TKey>().ToList();
-      }
-    }
-
-    public bool Remove(TKey key)
-    {
-      if (_genericDictionary != null)
-      {
-        return _genericDictionary.Remove(key);
-      }
-      else
-      {
-        if (_dictionary.Contains(key))
-        {
-          _dictionary.Remove(key);
-          return true;
-        }
-        else
-        {
-          return false;
-        }
-      }
-    }
-
-    public bool TryGetValue(TKey key, out TValue value)
-    {
-      if (_genericDictionary != null)
-      {
-        return _genericDictionary.TryGetValue(key, out value);
-      }
-      else
-      {
-        if (!_dictionary.Contains(key))
-        {
-          value = default(TValue);
-          return false;
-        }
-        else
-        {
-          value = (TValue)_dictionary[key];
-          return true;
-        }
-      }
-    }
-
-    public ICollection<TValue> Values
-    {
-      get
-      {
-        if (_genericDictionary != null)
-          return _genericDictionary.Values;
-        else
-          return _dictionary.Values.Cast<TValue>().ToList();
-      }
-    }
-
-    public TValue this[TKey key]
-    {
-      get
-      {
-        if (_genericDictionary != null)
-          return _genericDictionary[key];
-        else
-          return (TValue)_dictionary[key];
-      }
-      set
-      {
-        if (_genericDictionary != null)
-          _genericDictionary[key] = value;
-        else
-          _dictionary[key] = value;
-      }
-    }
-
-    public void Add(KeyValuePair<TKey, TValue> item)
-    {
-      if (_genericDictionary != null)
-        _genericDictionary.Add(item);
-      else
-        ((IList)_dictionary).Add(item);
-    }
-
-    public void Clear()
-    {
-      if (_genericDictionary != null)
-        _genericDictionary.Clear();
-      else
-        _dictionary.Clear();
-    }
-
-    public bool Contains(KeyValuePair<TKey, TValue> item)
-    {
-      if (_genericDictionary != null)
-        return _genericDictionary.Contains(item);
-      else
-        return ((IList)_dictionary).Contains(item);
-    }
-
-    public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
-    {
-      if (_genericDictionary != null)
-      {
-        _genericDictionary.CopyTo(array, arrayIndex);
-      }
-      else
-      {
-        foreach (DictionaryEntry item in _dictionary)
-        {
-          array[arrayIndex++] = new KeyValuePair<TKey, TValue>((TKey)item.Key, (TValue)item.Value);
-        }
-      }
-    }
-
-    public int Count
-    {
-      get
-      {
-        if (_genericDictionary != null)
-          return _genericDictionary.Count;
-        else
-          return _dictionary.Count;
-      }
-    }
-
-    public bool IsReadOnly
-    {
-      get
-      {
-        if (_genericDictionary != null)
-          return _genericDictionary.IsReadOnly;
-        else
-          return _dictionary.IsReadOnly;
-      }
-    }
-
-    public bool Remove(KeyValuePair<TKey, TValue> item)
-    {
-      if (_genericDictionary != null)
-      {
-        return _genericDictionary.Remove(item);
-      }
-      else
-      {
-        if (_dictionary.Contains(item.Key))
-        {
-          object value = _dictionary[item.Key];
-
-          if (object.Equals(value, item.Value))
-          {
-            _dictionary.Remove(item.Key);
-            return true;
-          }
-          else
-          {
-            return false;
-          }
-        }
-        else
-        {
-          return true;
-        }
-      }
-    }
-
-    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
-    {
-      if (_genericDictionary != null)
-        return _genericDictionary.GetEnumerator();
-      else
-        return _dictionary.Cast<DictionaryEntry>().Select(de => new KeyValuePair<TKey, TValue>((TKey)de.Key, (TValue)de.Value)).GetEnumerator();
-    }
-
-    IEnumerator IEnumerable.GetEnumerator()
-    {
-      return GetEnumerator();
-    }
-
-    void IDictionary.Add(object key, object value)
-    {
-      if (_genericDictionary != null)
-        _genericDictionary.Add((TKey)key, (TValue)value);
-      else
-        _dictionary.Add(key, value);
-    }
-
-    bool IDictionary.Contains(object key)
-    {
-      if (_genericDictionary != null)
-        return _genericDictionary.ContainsKey((TKey)key);
-      else
-        return _dictionary.Contains(key);
-    }
-
-    private struct DictionaryEnumerator<TEnumeratorKey, TEnumeratorValue> : IDictionaryEnumerator
-    {
-      private readonly IEnumerator<KeyValuePair<TEnumeratorKey, TEnumeratorValue>> _e;
-
-      public DictionaryEnumerator(IEnumerator<KeyValuePair<TEnumeratorKey, TEnumeratorValue>> e)
-      {
-        ValidationUtils.ArgumentNotNull(e, "e");
-        _e = e;
-      }
-
-      public DictionaryEntry Entry
-      {
-        get { return (DictionaryEntry)Current; }
-      }
-
-      public object Key
-      {
-        get { return Entry.Key; }
-      }
-
-      public object Value
-      {
-        get { return Entry.Value; }
-      }
-
-      public object Current
-      {
-        get { return new DictionaryEntry(_e.Current.Key, _e.Current.Value); }
-      }
-
-      public bool MoveNext()
-      {
-        return _e.MoveNext();
-      }
-
-      public void Reset()
-      {
-        _e.Reset();
-      }
-    }
-
-    IDictionaryEnumerator IDictionary.GetEnumerator()
-    {
-      if (_genericDictionary != null)
-        return new DictionaryEnumerator<TKey, TValue>(_genericDictionary.GetEnumerator());
-      else
-        return _dictionary.GetEnumerator();
-    }
-
-    bool IDictionary.IsFixedSize
-    {
-      get
-      {
-        if (_genericDictionary != null)
-          return false;
-        else
-          return _dictionary.IsFixedSize;
-      }
-    }
-
-    ICollection IDictionary.Keys
-    {
-      get
-      {
-        if (_genericDictionary != null)
-          return _genericDictionary.Keys.ToList();
-        else
-          return _dictionary.Keys;
-      }
-    }
-
-    public void Remove(object key)
-    {
-      if (_genericDictionary != null)
-        _genericDictionary.Remove((TKey)key);
-      else
-        _dictionary.Remove(key);
-    }
-
-    ICollection IDictionary.Values
-    {
-      get
-      {
-        if (_genericDictionary != null)
-          return _genericDictionary.Values.ToList();
-        else
-          return _dictionary.Values;
-      }
-    }
-
-    object IDictionary.this[object key]
-    {
-      get
-      {
-        if (_genericDictionary != null)
-          return _genericDictionary[(TKey)key];
-        else
-          return _dictionary[key];
-      }
-      set
-      {
-        if (_genericDictionary != null)
-          _genericDictionary[(TKey)key] = (TValue)value;
-        else
-          _dictionary[key] = value;
-      }
-    }
-
-    void ICollection.CopyTo(Array array, int index)
-    {
-      if (_genericDictionary != null)
-        _genericDictionary.CopyTo((KeyValuePair<TKey, TValue>[])array, index);
-      else
-        _dictionary.CopyTo(array, index);
-    }
-
-    bool ICollection.IsSynchronized
-    {
-      get
-      {
-        if (_genericDictionary != null)
-          return false;
-        else
-          return _dictionary.IsSynchronized;
-      }
-    }
-
-    object ICollection.SyncRoot
-    {
-      get
-      {
-        if (_syncRoot == null)
-          Interlocked.CompareExchange(ref _syncRoot, new object(), null);
-
-        return _syncRoot;
-      }
-    }
-
-    public object UnderlyingDictionary
-    {
-      get
-      {
-        if (_genericDictionary != null)
-          return _genericDictionary;
-        else
-          return _dictionary;
-      }
-    }
-  }
-}
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Collections;
+using System.Threading;
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#else
+using System.Linq;
+#endif
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal interface IWrappedDictionary
+    : IDictionary
+  {
+    object UnderlyingDictionary { get; }
+  }
+
+  internal class DictionaryWrapper<TKey, TValue> : IDictionary<TKey, TValue>, IWrappedDictionary
+  {
+    private readonly IDictionary _dictionary;
+    private readonly IDictionary<TKey, TValue> _genericDictionary;
+    private object _syncRoot;
+
+    public DictionaryWrapper(IDictionary dictionary)
+    {
+      ValidationUtils.ArgumentNotNull(dictionary, "dictionary");
+
+      _dictionary = dictionary;
+    }
+
+    public DictionaryWrapper(IDictionary<TKey, TValue> dictionary)
+    {
+      ValidationUtils.ArgumentNotNull(dictionary, "dictionary");
+
+      _genericDictionary = dictionary;
+    }
+
+    public void Add(TKey key, TValue value)
+    {
+      if (_dictionary != null)
+        _dictionary.Add(key, value);
+      else
+        _genericDictionary.Add(key, value);
+    }
+
+    public bool ContainsKey(TKey key)
+    {
+      if (_dictionary != null)
+        return _dictionary.Contains(key);
+      else
+        return _genericDictionary.ContainsKey(key);
+    }
+
+    public ICollection<TKey> Keys
+    {
+      get
+      {
+        if (_dictionary != null)
+          return _dictionary.Keys.Cast<TKey>().ToList();
+        else
+          return _genericDictionary.Keys;
+      }
+    }
+
+    public bool Remove(TKey key)
+    {
+      if (_dictionary != null)
+      {
+        if (_dictionary.Contains(key))
+        {
+          _dictionary.Remove(key);
+          return true;
+        }
+        else
+        {
+          return false;
+        }
+      }
+
+      return _genericDictionary.Remove(key);
+    }
+
+    public bool TryGetValue(TKey key, out TValue value)
+    {
+      if (_dictionary != null)
+      {
+        if (!_dictionary.Contains(key))
+        {
+          value = default(TValue);
+          return false;
+        }
+        else
+        {
+          value = (TValue)_dictionary[key];
+          return true;
+        }
+      }
+
+      return _genericDictionary.TryGetValue(key, out value);
+    }
+
+    public ICollection<TValue> Values
+    {
+      get
+      {
+        if (_dictionary != null)
+          return _dictionary.Values.Cast<TValue>().ToList();
+        else
+          return _genericDictionary.Values;
+      }
+    }
+
+    public TValue this[TKey key]
+    {
+      get
+      {
+        if (_dictionary != null)
+          return (TValue)_dictionary[key];
+        return _genericDictionary[key];
+      }
+      set
+      {
+        if (_dictionary != null)
+          _dictionary[key] = value;
+        else
+          _genericDictionary[key] = value;
+      }
+    }
+
+    public void Add(KeyValuePair<TKey, TValue> item)
+    {
+      if (_dictionary != null)
+        ((IList)_dictionary).Add(item);
+      else
+        _genericDictionary.Add(item);
+    }
+
+    public void Clear()
+    {
+      if (_dictionary != null)
+        _dictionary.Clear();
+      else
+        _genericDictionary.Clear();
+    }
+
+    public bool Contains(KeyValuePair<TKey, TValue> item)
+    {
+      if (_dictionary != null)
+        return ((IList)_dictionary).Contains(item);
+      else
+        return _genericDictionary.Contains(item);
+    }
+
+    public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
+    {
+      if (_dictionary != null)
+      {
+        foreach (DictionaryEntry item in _dictionary)
+        {
+          array[arrayIndex++] = new KeyValuePair<TKey, TValue>((TKey)item.Key, (TValue)item.Value);
+        }
+      }
+      else
+      {
+        _genericDictionary.CopyTo(array, arrayIndex);
+      }
+    }
+
+    public int Count
+    {
+      get
+      {
+        if (_dictionary != null)
+          return _dictionary.Count;
+        else
+          return _genericDictionary.Count;
+      }
+    }
+
+    public bool IsReadOnly
+    {
+      get
+      {
+        if (_dictionary != null)
+          return _dictionary.IsReadOnly;
+        else
+          return _genericDictionary.IsReadOnly;
+      }
+    }
+
+    public bool Remove(KeyValuePair<TKey, TValue> item)
+    {
+      if (_dictionary != null)
+      {
+        if (_dictionary.Contains(item.Key))
+        {
+          object value = _dictionary[item.Key];
+
+          if (object.Equals(value, item.Value))
+          {
+            _dictionary.Remove(item.Key);
+            return true;
+          }
+          else
+          {
+            return false;
+          }
+        }
+        else
+        {
+          return true;
+        }
+      }
+      else
+      {
+        return _genericDictionary.Remove(item);
+      }
+    }
+
+    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
+    {
+      if (_dictionary != null)
+        return _dictionary.Cast<DictionaryEntry>().Select(de => new KeyValuePair<TKey, TValue>((TKey)de.Key, (TValue)de.Value)).GetEnumerator();
+      else
+        return _genericDictionary.GetEnumerator();
+    }
+
+    IEnumerator IEnumerable.GetEnumerator()
+    {
+      return GetEnumerator();
+    }
+
+    void IDictionary.Add(object key, object value)
+    {
+      if (_dictionary != null)
+        _dictionary.Add(key, value);
+      else
+        _genericDictionary.Add((TKey)key, (TValue)value);
+    }
+
+    object IDictionary.this[object key]
+    {
+      get
+      {
+        if (_dictionary != null)
+          return _dictionary[key];
+        else
+          return _genericDictionary[(TKey)key];
+      }
+      set
+      {
+        if (_dictionary != null)
+          _dictionary[key] = value;
+        else
+          _genericDictionary[(TKey)key] = (TValue)value;
+      }
+    }
+
+    private struct DictionaryEnumerator<TEnumeratorKey, TEnumeratorValue> : IDictionaryEnumerator
+    {
+      private readonly IEnumerator<KeyValuePair<TEnumeratorKey, TEnumeratorValue>> _e;
+
+      public DictionaryEnumerator(IEnumerator<KeyValuePair<TEnumeratorKey, TEnumeratorValue>> e)
+      {
+        ValidationUtils.ArgumentNotNull(e, "e");
+        _e = e;
+      }
+
+      public DictionaryEntry Entry
+      {
+        get { return (DictionaryEntry)Current; }
+      }
+
+      public object Key
+      {
+        get { return Entry.Key; }
+      }
+
+      public object Value
+      {
+        get { return Entry.Value; }
+      }
+
+      public object Current
+      {
+        get { return new DictionaryEntry(_e.Current.Key, _e.Current.Value); }
+      }
+
+      public bool MoveNext()
+      {
+        return _e.MoveNext();
+      }
+
+      public void Reset()
+      {
+        _e.Reset();
+      }
+    }
+
+    IDictionaryEnumerator IDictionary.GetEnumerator()
+    {
+      if (_dictionary != null)
+        return _dictionary.GetEnumerator();
+      else
+        return new DictionaryEnumerator<TKey, TValue>(_genericDictionary.GetEnumerator());
+    }
+
+    bool IDictionary.Contains(object key)
+    {
+      if (_genericDictionary != null)
+        return _genericDictionary.ContainsKey((TKey)key);
+      else
+        return _dictionary.Contains(key);
+    }
+
+    bool IDictionary.IsFixedSize
+    {
+      get
+      {
+        if (_genericDictionary != null)
+          return false;
+        else
+          return _dictionary.IsFixedSize;
+      }
+    }
+
+    ICollection IDictionary.Keys
+    {
+      get
+      {
+        if (_genericDictionary != null)
+          return _genericDictionary.Keys.ToList();
+        else
+          return _dictionary.Keys;
+      }
+    }
+
+    public void Remove(object key)
+    {
+      if (_dictionary != null)
+        _dictionary.Remove(key);
+      else
+        _genericDictionary.Remove((TKey)key);
+    }
+
+    ICollection IDictionary.Values
+    {
+      get
+      {
+        if (_genericDictionary != null)
+          return _genericDictionary.Values.ToList();
+        else
+          return _dictionary.Values;
+      }
+    }
+
+    void ICollection.CopyTo(Array array, int index)
+    {
+      if (_dictionary != null)
+        _dictionary.CopyTo(array, index);
+      else
+        _genericDictionary.CopyTo((KeyValuePair<TKey, TValue>[])array, index);
+    }
+
+    bool ICollection.IsSynchronized
+    {
+      get
+      {
+        if (_dictionary != null)
+          return _dictionary.IsSynchronized;
+        else
+          return false;
+      }
+    }
+
+    object ICollection.SyncRoot
+    {
+      get
+      {
+        if (_syncRoot == null)
+          Interlocked.CompareExchange(ref _syncRoot, new object(), null);
+
+        return _syncRoot;
+      }
+    }
+
+    public object UnderlyingDictionary
+    {
+      get
+      {
+        if (_dictionary != null)
+          return _dictionary;
+        else
+          return _genericDictionary;
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DynamicProxy.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DynamicProxy.cs
new file mode 100644
index 0000000..c52b1a4
--- /dev/null
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DynamicProxy.cs
@@ -0,0 +1,112 @@
+#region License
+// 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.
+#endregion
+
+#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
+using System;
+using System.Collections.Generic;
+using System.Dynamic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Text;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal class DynamicProxy<T>
+  {
+    public virtual IEnumerable<string> GetDynamicMemberNames(T instance)
+    {
+      return new string[0];
+    }
+
+    public virtual bool TryBinaryOperation(T instance, BinaryOperationBinder binder, object arg, out object result)
+    {
+      result = null;
+      return false;
+    }
+
+    public virtual bool TryConvert(T instance, ConvertBinder binder, out object result)
+    {
+      result = null;
+      return false;
+    }
+
+    public virtual bool TryCreateInstance(T instance, CreateInstanceBinder binder, object[] args, out object result)
+    {
+      result = null;
+      return false;
+    }
+
+    public virtual bool TryDeleteIndex(T instance, DeleteIndexBinder binder, object[] indexes)
+    {
+      return false;
+    }
+
+    public virtual bool TryDeleteMember(T instance, DeleteMemberBinder binder)
+    {
+      return false;
+    }
+
+    public virtual bool TryGetIndex(T instance, GetIndexBinder binder, object[] indexes, out object result)
+    {
+      result = null;
+      return false;
+    }
+
+    public virtual bool TryGetMember(T instance, GetMemberBinder binder, out object result)
+    {
+      result = null;
+      return false;
+    }
+
+    public virtual bool TryInvoke(T instance, InvokeBinder binder, object[] args, out object result)
+    {
+      result = null;
+      return false;
+    }
+
+    public virtual bool TryInvokeMember(T instance, InvokeMemberBinder binder, object[] args, out object result)
+    {
+      result = null;
+      return false;
+    }
+
+    public virtual bool TrySetIndex(T instance, SetIndexBinder binder, object[] indexes, object value)
+    {
+      return false;
+    }
+
+    public virtual bool TrySetMember(T instance, SetMemberBinder binder, object value)
+    {
+      return false;
+    }
+
+    public virtual bool TryUnaryOperation(T instance, UnaryOperationBinder binder, out object result)
+    {
+      result = null;
+      return false;
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DynamicProxyMetaObject.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DynamicProxyMetaObject.cs
new file mode 100644
index 0000000..61738c5
--- /dev/null
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DynamicProxyMetaObject.cs
@@ -0,0 +1,419 @@
+#region License
+// 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.
+#endregion
+
+#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
+using System;
+using System.Collections.Generic;
+using System.Dynamic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Reflection;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal sealed class DynamicProxyMetaObject<T> : DynamicMetaObject
+  {
+    private readonly DynamicProxy<T> _proxy;
+    private readonly bool _dontFallbackFirst;
+
+    internal DynamicProxyMetaObject(Expression expression, T value, DynamicProxy<T> proxy, bool dontFallbackFirst)
+      : base(expression, BindingRestrictions.Empty, value)
+    {
+      _proxy = proxy;
+      _dontFallbackFirst = dontFallbackFirst;
+    }
+
+    private new T Value { get { return (T)base.Value; } }
+
+    private bool IsOverridden(string method)
+    {
+      return ReflectionUtils.IsMethodOverridden(_proxy.GetType(), typeof (DynamicProxy<T>), method);
+    }
+
+    public override DynamicMetaObject BindGetMember(GetMemberBinder binder)
+    {
+      return IsOverridden("TryGetMember")
+           ? CallMethodWithResult("TryGetMember", binder, NoArgs, e => binder.FallbackGetMember(this, e))
+           : base.BindGetMember(binder);
+    }
+
+    public override DynamicMetaObject BindSetMember(SetMemberBinder binder, DynamicMetaObject value)
+    {
+      return IsOverridden("TrySetMember")
+           ? CallMethodReturnLast("TrySetMember", binder, GetArgs(value), e => binder.FallbackSetMember(this, value, e))
+           : base.BindSetMember(binder, value);
+    }
+
+    public override DynamicMetaObject BindDeleteMember(DeleteMemberBinder binder)
+    {
+      return IsOverridden("TryDeleteMember")
+           ? CallMethodNoResult("TryDeleteMember", binder, NoArgs, e => binder.FallbackDeleteMember(this, e))
+           : base.BindDeleteMember(binder);
+    }
+
+
+    public override DynamicMetaObject BindConvert(ConvertBinder binder)
+    {
+      return IsOverridden("TryConvert")
+           ? CallMethodWithResult("TryConvert", binder, NoArgs, e => binder.FallbackConvert(this, e))
+           : base.BindConvert(binder);
+    }
+
+    public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args)
+    {
+      if (!IsOverridden("TryInvokeMember"))
+        return base.BindInvokeMember(binder, args);
+
+      //
+      // Generate a tree like:
+      //
+      // {
+      //   object result;
+      //   TryInvokeMember(payload, out result)
+      //      ? result
+      //      : TryGetMember(payload, out result)
+      //          ? FallbackInvoke(result)
+      //          : fallbackResult
+      // }
+      //
+      // Then it calls FallbackInvokeMember with this tree as the
+      // "error", giving the language the option of using this
+      // tree or doing .NET binding.
+      //
+      Fallback fallback = e => binder.FallbackInvokeMember(this, args, e);
+
+      DynamicMetaObject call = BuildCallMethodWithResult(
+          "TryInvokeMember",
+          binder,
+          GetArgArray(args),
+          BuildCallMethodWithResult(
+              "TryGetMember",
+              new GetBinderAdapter(binder),
+              NoArgs,
+              fallback(null),
+              e => binder.FallbackInvoke(e, args, null)
+          ),
+          null
+      );
+
+      return _dontFallbackFirst ? call : fallback(call);
+    }
+
+
+    public override DynamicMetaObject BindCreateInstance(CreateInstanceBinder binder, DynamicMetaObject[] args)
+    {
+      return IsOverridden("TryCreateInstance")
+           ? CallMethodWithResult("TryCreateInstance", binder, GetArgArray(args), e => binder.FallbackCreateInstance(this, args, e))
+           : base.BindCreateInstance(binder, args);
+    }
+
+    public override DynamicMetaObject BindInvoke(InvokeBinder binder, DynamicMetaObject[] args)
+    {
+      return IsOverridden("TryInvoke")
+        ? CallMethodWithResult("TryInvoke", binder, GetArgArray(args), e => binder.FallbackInvoke(this, args, e))
+        : base.BindInvoke(binder, args);
+    }
+
+    public override DynamicMetaObject BindBinaryOperation(BinaryOperationBinder binder, DynamicMetaObject arg)
+    {
+      return IsOverridden("TryBinaryOperation")
+        ? CallMethodWithResult("TryBinaryOperation", binder, GetArgs(arg), e => binder.FallbackBinaryOperation(this, arg, e))
+        : base.BindBinaryOperation(binder, arg);
+    }
+
+    public override DynamicMetaObject BindUnaryOperation(UnaryOperationBinder binder)
+    {
+      return IsOverridden("TryUnaryOperation")
+           ? CallMethodWithResult("TryUnaryOperation", binder, NoArgs, e => binder.FallbackUnaryOperation(this, e))
+           : base.BindUnaryOperation(binder);
+    }
+
+    public override DynamicMetaObject BindGetIndex(GetIndexBinder binder, DynamicMetaObject[] indexes)
+    {
+      return IsOverridden("TryGetIndex")
+           ? CallMethodWithResult("TryGetIndex", binder, GetArgArray(indexes), e => binder.FallbackGetIndex(this, indexes, e))
+           : base.BindGetIndex(binder, indexes);
+    }
+
+    public override DynamicMetaObject BindSetIndex(SetIndexBinder binder, DynamicMetaObject[] indexes, DynamicMetaObject value)
+    {
+      return IsOverridden("TrySetIndex")
+           ? CallMethodReturnLast("TrySetIndex", binder, GetArgArray(indexes, value), e => binder.FallbackSetIndex(this, indexes, value, e))
+           : base.BindSetIndex(binder, indexes, value);
+    }
+
+    public override DynamicMetaObject BindDeleteIndex(DeleteIndexBinder binder, DynamicMetaObject[] indexes)
+    {
+      return IsOverridden("TryDeleteIndex")
+           ? CallMethodNoResult("TryDeleteIndex", binder, GetArgArray(indexes), e => binder.FallbackDeleteIndex(this, indexes, e))
+           : base.BindDeleteIndex(binder, indexes);
+    }
+
+    private delegate DynamicMetaObject Fallback(DynamicMetaObject errorSuggestion);
+
+    private readonly static Expression[] NoArgs = new Expression[0];
+
+    private static Expression[] GetArgs(params DynamicMetaObject[] args)
+    {
+      return args.Select(arg => Expression.Convert(arg.Expression, typeof(object))).ToArray();
+    }
+
+    private static Expression[] GetArgArray(DynamicMetaObject[] args)
+    {
+      return new[] { Expression.NewArrayInit(typeof(object), GetArgs(args)) };
+    }
+
+    private static Expression[] GetArgArray(DynamicMetaObject[] args, DynamicMetaObject value)
+    {
+      return new Expression[]
+            {
+                Expression.NewArrayInit(typeof(object), GetArgs(args)),
+                Expression.Convert(value.Expression, typeof(object))
+            };
+    }
+
+    private static ConstantExpression Constant(DynamicMetaObjectBinder binder)
+    {
+      Type t = binder.GetType();
+      while (!t.IsVisible())
+        t = t.BaseType();
+      return Expression.Constant(binder, t);
+    }
+
+    /// <summary>
+    /// Helper method for generating a MetaObject which calls a
+    /// specific method on Dynamic that returns a result
+    /// </summary>
+    private DynamicMetaObject CallMethodWithResult(string methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback, Fallback fallbackInvoke = null)
+    {
+      //
+      // First, call fallback to do default binding
+      // This produces either an error or a call to a .NET member
+      //
+      DynamicMetaObject fallbackResult = fallback(null);
+
+      DynamicMetaObject callDynamic = BuildCallMethodWithResult(methodName, binder, args, fallbackResult, fallbackInvoke);
+
+      //
+      // Now, call fallback again using our new MO as the error
+      // When we do this, one of two things can happen:
+      //   1. Binding will succeed, and it will ignore our call to
+      //      the dynamic method, OR
+      //   2. Binding will fail, and it will use the MO we created
+      //      above.
+      //
+
+      return _dontFallbackFirst ? callDynamic : fallback(callDynamic);
+    }
+
+    private DynamicMetaObject BuildCallMethodWithResult(string methodName, DynamicMetaObjectBinder binder, Expression[] args, DynamicMetaObject fallbackResult, Fallback fallbackInvoke)
+    {
+      //
+      // Build a new expression like:
+      // {
+      //   object result;
+      //   TryGetMember(payload, out result) ? fallbackInvoke(result) : fallbackResult
+      // }
+      //
+      ParameterExpression result = Expression.Parameter(typeof(object), null);
+
+      IList<Expression> callArgs = new List<Expression>();
+      callArgs.Add(Expression.Convert(Expression, typeof(T)));
+      callArgs.Add(Constant(binder));
+      callArgs.AddRange(args);
+      callArgs.Add(result);
+
+      DynamicMetaObject resultMetaObject = new DynamicMetaObject(result, BindingRestrictions.Empty);
+
+      // Need to add a conversion if calling TryConvert
+      if (binder.ReturnType != typeof (object))
+      {
+        UnaryExpression convert = Expression.Convert(resultMetaObject.Expression, binder.ReturnType);
+        // will always be a cast or unbox
+
+        resultMetaObject = new DynamicMetaObject(convert, resultMetaObject.Restrictions);
+      }
+
+      if (fallbackInvoke != null)
+        resultMetaObject = fallbackInvoke(resultMetaObject);
+
+      DynamicMetaObject callDynamic = new DynamicMetaObject(
+        Expression.Block(
+          new[] {result},
+          Expression.Condition(
+            Expression.Call(
+              Expression.Constant(_proxy),
+              typeof(DynamicProxy<T>).GetMethod(methodName),
+              callArgs
+              ),
+            resultMetaObject.Expression,
+            fallbackResult.Expression,
+            binder.ReturnType
+            )
+          ),
+        GetRestrictions().Merge(resultMetaObject.Restrictions).Merge(fallbackResult.Restrictions)
+        );
+
+      return callDynamic;
+    }
+
+    /// <summary>
+    /// Helper method for generating a MetaObject which calls a
+    /// specific method on Dynamic, but uses one of the arguments for
+    /// the result.
+    /// </summary>
+    private DynamicMetaObject CallMethodReturnLast(string methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback)
+    {
+      //
+      // First, call fallback to do default binding
+      // This produces either an error or a call to a .NET member
+      //
+      DynamicMetaObject fallbackResult = fallback(null);
+
+      //
+      // Build a new expression like:
+      // {
+      //   object result;
+      //   TrySetMember(payload, result = value) ? result : fallbackResult
+      // }
+      //
+      ParameterExpression result = Expression.Parameter(typeof(object), null);
+
+      IList<Expression> callArgs = new List<Expression>();
+      callArgs.Add(Expression.Convert(Expression, typeof (T)));
+      callArgs.Add(Constant(binder));
+      callArgs.AddRange(args);
+      callArgs[args.Length + 1] = Expression.Assign(result, callArgs[args.Length + 1]);
+
+      DynamicMetaObject callDynamic = new DynamicMetaObject(
+          Expression.Block(
+              new[] { result },
+              Expression.Condition(
+                  Expression.Call(
+                      Expression.Constant(_proxy),
+                      typeof(DynamicProxy<T>).GetMethod(methodName),
+                      callArgs
+                  ),
+                  result,
+                  fallbackResult.Expression,
+                  typeof(object)
+              )
+          ),
+          GetRestrictions().Merge(fallbackResult.Restrictions)
+      );
+
+      //
+      // Now, call fallback again using our new MO as the error
+      // When we do this, one of two things can happen:
+      //   1. Binding will succeed, and it will ignore our call to
+      //      the dynamic method, OR
+      //   2. Binding will fail, and it will use the MO we created
+      //      above.
+      //
+      return _dontFallbackFirst ? callDynamic : fallback(callDynamic);
+    }
+
+    /// <summary>
+    /// Helper method for generating a MetaObject which calls a
+    /// specific method on Dynamic, but uses one of the arguments for
+    /// the result.
+    /// </summary>
+    private DynamicMetaObject CallMethodNoResult(string methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback)
+    {
+      //
+      // First, call fallback to do default binding
+      // This produces either an error or a call to a .NET member
+      //
+      DynamicMetaObject fallbackResult = fallback(null);
+
+      IList<Expression> callArgs = new List<Expression>();
+      callArgs.Add(Expression.Convert(Expression, typeof(T)));
+      callArgs.Add(Constant(binder));
+      callArgs.AddRange(args);
+
+      //
+      // Build a new expression like:
+      //   if (TryDeleteMember(payload)) { } else { fallbackResult }
+      //
+      DynamicMetaObject callDynamic = new DynamicMetaObject(
+        Expression.Condition(
+          Expression.Call(
+            Expression.Constant(_proxy),
+            typeof(DynamicProxy<T>).GetMethod(methodName),
+            callArgs
+            ),
+          Expression.Empty(),
+          fallbackResult.Expression,
+          typeof (void)
+          ),
+        GetRestrictions().Merge(fallbackResult.Restrictions)
+        );
+
+      //
+      // Now, call fallback again using our new MO as the error
+      // When we do this, one of two things can happen:
+      //   1. Binding will succeed, and it will ignore our call to
+      //      the dynamic method, OR
+      //   2. Binding will fail, and it will use the MO we created
+      //      above.
+      //
+      return _dontFallbackFirst ? callDynamic : fallback(callDynamic);
+    }
+
+    /// <summary>
+    /// Returns a Restrictions object which includes our current restrictions merged
+    /// with a restriction limiting our type
+    /// </summary>
+    private BindingRestrictions GetRestrictions()
+    {
+      return (Value == null && HasValue)
+           ? BindingRestrictions.GetInstanceRestriction(Expression, null)
+           : BindingRestrictions.GetTypeRestriction(Expression, LimitType);
+    }
+
+    public override IEnumerable<string> GetDynamicMemberNames()
+    {
+      return _proxy.GetDynamicMemberNames(Value);
+    }
+
+    // It is okay to throw NotSupported from this binder. This object
+    // is only used by DynamicObject.GetMember--it is not expected to
+    // (and cannot) implement binding semantics. It is just so the DO
+    // can use the Name and IgnoreCase properties.
+    private sealed class GetBinderAdapter : GetMemberBinder
+    {
+      internal GetBinderAdapter(InvokeMemberBinder binder) :
+        base(binder.Name, binder.IgnoreCase)
+      {
+      }
+
+      public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
+      {
+        throw new NotSupportedException();
+      }
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DynamicReflectionDelegateFactory.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DynamicReflectionDelegateFactory.cs
index e1e6b91..8648d83 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DynamicReflectionDelegateFactory.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DynamicReflectionDelegateFactory.cs
@@ -1,200 +1,229 @@
-#region License
-// 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.
-#endregion
-
-#if !PocketPC && !SILVERLIGHT
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using System.Reflection.Emit;
-using System.Text;
-using System.Globalization;
-
-namespace Newtonsoft.Json.Utilities
-{
-  internal class DynamicReflectionDelegateFactory : ReflectionDelegateFactory
-  {
-    public static DynamicReflectionDelegateFactory Instance = new DynamicReflectionDelegateFactory();
-
-    private static DynamicMethod CreateDynamicMethod(string name, Type returnType, Type[] parameterTypes, Type owner)
-    {
-      DynamicMethod dynamicMethod = !owner.IsInterface
-        ? new DynamicMethod(name, returnType, parameterTypes, owner, true)
-        : new DynamicMethod(name, returnType, parameterTypes, (Module)null, true);
-
-      return dynamicMethod;
-    }
-
-    public override MethodCall<T, object> CreateMethodCall<T>(MethodBase method)
-    {
-      DynamicMethod dynamicMethod = CreateDynamicMethod(method.ToString(), typeof(object), new[] { typeof(object), typeof(object[]) }, method.DeclaringType);
-      ILGenerator generator = dynamicMethod.GetILGenerator();
-
-      ParameterInfo[] args = method.GetParameters();
-
-      Label argsOk = generator.DefineLabel();
-
-      generator.Emit(OpCodes.Ldarg_1);
-      generator.Emit(OpCodes.Ldlen);
-      generator.Emit(OpCodes.Ldc_I4, args.Length);
-      generator.Emit(OpCodes.Beq, argsOk);
-
-      generator.Emit(OpCodes.Newobj, typeof(TargetParameterCountException).GetConstructor(Type.EmptyTypes));
-      generator.Emit(OpCodes.Throw);
-
-      generator.MarkLabel(argsOk);
-
-      if (!method.IsConstructor && !method.IsStatic)
-        generator.PushInstance(method.DeclaringType);
-
-      for (int i = 0; i < args.Length; i++)
-      {
-        generator.Emit(OpCodes.Ldarg_1);
-        generator.Emit(OpCodes.Ldc_I4, i);
-        generator.Emit(OpCodes.Ldelem_Ref);
-
-        generator.UnboxIfNeeded(args[i].ParameterType);
-      }
-
-      if (method.IsConstructor)
-        generator.Emit(OpCodes.Newobj, (ConstructorInfo)method);
-      else if (method.IsFinal || !method.IsVirtual)
-        generator.CallMethod((MethodInfo)method);
-
-      Type returnType = method.IsConstructor
-        ? method.DeclaringType
-        : ((MethodInfo)method).ReturnType;
-
-      if (returnType != typeof(void))
-        generator.BoxIfNeeded(returnType);
-      else
-        generator.Emit(OpCodes.Ldnull);
-
-      generator.Return();
-
-      return (MethodCall<T, object>)dynamicMethod.CreateDelegate(typeof(MethodCall<T, object>));
-    }
-
-    public override Func<T> CreateDefaultConstructor<T>(Type type)
-    {
-      DynamicMethod dynamicMethod = CreateDynamicMethod("Create" + type.FullName, typeof(object), Type.EmptyTypes, type);
-      dynamicMethod.InitLocals = true;
-      ILGenerator generator = dynamicMethod.GetILGenerator();
-
-      if (type.IsValueType)
-      {
-        generator.DeclareLocal(type);
-        generator.Emit(OpCodes.Ldloc_0);
-        generator.Emit(OpCodes.Box, type);
-      }
-      else
-      {
-        ConstructorInfo constructorInfo =
-          type.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null,
-                              Type.EmptyTypes, null);
-
-        if (constructorInfo == null)
-          throw new Exception("Could not get constructor for {0}.".FormatWith(CultureInfo.InvariantCulture, type));
-
-        generator.Emit(OpCodes.Newobj, constructorInfo);
-      }
-
-      generator.Return();
-
-      return (Func<T>)dynamicMethod.CreateDelegate(typeof(Func<T>));
-    }
-
-    public override Func<T, object> CreateGet<T>(PropertyInfo propertyInfo)
-    {
-      MethodInfo getMethod = propertyInfo.GetGetMethod(true);
-      if (getMethod == null)
-        throw new Exception("Property '{0}' does not have a getter.".FormatWith(CultureInfo.InvariantCulture,
-                                                                                propertyInfo.Name));
-
-      DynamicMethod dynamicMethod = CreateDynamicMethod("Get" + propertyInfo.Name, typeof(T), new[] { typeof(object) }, propertyInfo.DeclaringType);
-
-      ILGenerator generator = dynamicMethod.GetILGenerator();
-
-      if (!getMethod.IsStatic)
-        generator.PushInstance(propertyInfo.DeclaringType);
-
-      generator.CallMethod(getMethod);
-      generator.BoxIfNeeded(propertyInfo.PropertyType);
-      generator.Return();
-
-      return (Func<T, object>)dynamicMethod.CreateDelegate(typeof(Func<T, object>));
-    }
-
-    public override Func<T, object> CreateGet<T>(FieldInfo fieldInfo)
-    {
-      DynamicMethod dynamicMethod = CreateDynamicMethod("Get" + fieldInfo.Name, typeof(T), new[] { typeof(object) }, fieldInfo.DeclaringType);
-
-      ILGenerator generator = dynamicMethod.GetILGenerator();
-
-      if (!fieldInfo.IsStatic)
-        generator.PushInstance(fieldInfo.DeclaringType);
-
-      generator.Emit(OpCodes.Ldfld, fieldInfo);
-      generator.BoxIfNeeded(fieldInfo.FieldType);
-      generator.Return();
-
-      return (Func<T, object>)dynamicMethod.CreateDelegate(typeof(Func<T, object>));
-    }
-
-    public override Action<T, object> CreateSet<T>(FieldInfo fieldInfo)
-    {
-      DynamicMethod dynamicMethod = CreateDynamicMethod("Set" + fieldInfo.Name, null, new[] { typeof(object), typeof(object) }, fieldInfo.DeclaringType);
-      ILGenerator generator = dynamicMethod.GetILGenerator();
-
-      if (!fieldInfo.IsStatic)
-        generator.PushInstance(fieldInfo.DeclaringType);
-
-      generator.Emit(OpCodes.Ldarg_1);
-      generator.UnboxIfNeeded(fieldInfo.FieldType);
-      generator.Emit(OpCodes.Stfld, fieldInfo);
-      generator.Return();
-
-      return (Action<T, object>)dynamicMethod.CreateDelegate(typeof(Action<T, object>));
-    }
-
-    public override Action<T, object> CreateSet<T>(PropertyInfo propertyInfo)
-    {
-      MethodInfo setMethod = propertyInfo.GetSetMethod(true);
-      DynamicMethod dynamicMethod = CreateDynamicMethod("Set" + propertyInfo.Name, null, new[] { typeof(object), typeof(object) }, propertyInfo.DeclaringType);
-      ILGenerator generator = dynamicMethod.GetILGenerator();
-
-      if (!setMethod.IsStatic)
-        generator.PushInstance(propertyInfo.DeclaringType);
-
-      generator.Emit(OpCodes.Ldarg_1);
-      generator.UnboxIfNeeded(propertyInfo.PropertyType);
-      generator.CallMethod(setMethod);
-      generator.Return();
-
-      return (Action<T, object>)dynamicMethod.CreateDelegate(typeof(Action<T, object>));
-    }
-  }
-}
+#region License
+// 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.
+#endregion
+
+#if !(SILVERLIGHT || PORTABLE || NETFX_CORE)
+using System;
+using System.Collections.Generic;
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#endif
+using System.Reflection;
+using System.Reflection.Emit;
+using Newtonsoft.Json.Serialization;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal class DynamicReflectionDelegateFactory : ReflectionDelegateFactory
+  {
+    public static DynamicReflectionDelegateFactory Instance = new DynamicReflectionDelegateFactory();
+
+    private static DynamicMethod CreateDynamicMethod(string name, Type returnType, Type[] parameterTypes, Type owner)
+    {
+      DynamicMethod dynamicMethod = !owner.IsInterface()
+        ? new DynamicMethod(name, returnType, parameterTypes, owner, true)
+        : new DynamicMethod(name, returnType, parameterTypes, owner.Module, true);
+
+      return dynamicMethod;
+    }
+
+    public override MethodCall<T, object> CreateMethodCall<T>(MethodBase method)
+    {
+      DynamicMethod dynamicMethod = CreateDynamicMethod(method.ToString(), typeof(object), new[] { typeof(object), typeof(object[]) }, method.DeclaringType);
+      ILGenerator generator = dynamicMethod.GetILGenerator();
+
+      GenerateCreateMethodCallIL(method, generator);
+
+      return (MethodCall<T, object>)dynamicMethod.CreateDelegate(typeof(MethodCall<T, object>));
+    }
+
+    private void GenerateCreateMethodCallIL(MethodBase method, ILGenerator generator)
+    {
+      ParameterInfo[] args = method.GetParameters();
+
+      Label argsOk = generator.DefineLabel();
+
+      generator.Emit(OpCodes.Ldarg_1);
+      generator.Emit(OpCodes.Ldlen);
+      generator.Emit(OpCodes.Ldc_I4, args.Length);
+      generator.Emit(OpCodes.Beq, argsOk);
+
+      generator.Emit(OpCodes.Newobj, typeof(TargetParameterCountException).GetConstructor(ReflectionUtils.EmptyTypes));
+      generator.Emit(OpCodes.Throw);
+
+      generator.MarkLabel(argsOk);
+
+      if (!method.IsConstructor && !method.IsStatic)
+        generator.PushInstance(method.DeclaringType);
+
+      for (int i = 0; i < args.Length; i++)
+      {
+        generator.Emit(OpCodes.Ldarg_1);
+        generator.Emit(OpCodes.Ldc_I4, i);
+        generator.Emit(OpCodes.Ldelem_Ref);
+
+        generator.UnboxIfNeeded(args[i].ParameterType);
+      }
+
+      if (method.IsConstructor)
+        generator.Emit(OpCodes.Newobj, (ConstructorInfo)method);
+      else if (method.IsFinal || !method.IsVirtual)
+        generator.CallMethod((MethodInfo)method);
+
+      Type returnType = method.IsConstructor
+                          ? method.DeclaringType
+                          : ((MethodInfo)method).ReturnType;
+
+      if (returnType != typeof(void))
+        generator.BoxIfNeeded(returnType);
+      else
+        generator.Emit(OpCodes.Ldnull);
+
+      generator.Return();
+    }
+
+    public override Func<T> CreateDefaultConstructor<T>(Type type)
+    {
+      DynamicMethod dynamicMethod = CreateDynamicMethod("Create" + type.FullName, typeof(T), ReflectionUtils.EmptyTypes, type);
+      dynamicMethod.InitLocals = true;
+      ILGenerator generator = dynamicMethod.GetILGenerator();
+
+      GenerateCreateDefaultConstructorIL(type, generator);
+
+      return (Func<T>)dynamicMethod.CreateDelegate(typeof(Func<T>));
+    }
+
+    private void GenerateCreateDefaultConstructorIL(Type type, ILGenerator generator)
+    {
+      if (type.IsValueType())
+      {
+        generator.DeclareLocal(type);
+        generator.Emit(OpCodes.Ldloc_0);
+        generator.Emit(OpCodes.Box, type);
+      }
+      else
+      {
+        ConstructorInfo constructorInfo =
+          type.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null,
+                              ReflectionUtils.EmptyTypes, null);
+
+        if (constructorInfo == null)
+          throw new ArgumentException("Could not get constructor for {0}.".FormatWith(CultureInfo.InvariantCulture, type));
+
+        generator.Emit(OpCodes.Newobj, constructorInfo);
+      }
+
+      generator.Return();
+    }
+
+    public override Func<T, object> CreateGet<T>(PropertyInfo propertyInfo)
+    {
+      DynamicMethod dynamicMethod = CreateDynamicMethod("Get" + propertyInfo.Name, typeof(T), new[] { typeof(object) }, propertyInfo.DeclaringType);
+      ILGenerator generator = dynamicMethod.GetILGenerator();
+
+      GenerateCreateGetPropertyIL(propertyInfo, generator);
+
+      return (Func<T, object>)dynamicMethod.CreateDelegate(typeof(Func<T, object>));
+    }
+
+    private void GenerateCreateGetPropertyIL(PropertyInfo propertyInfo, ILGenerator generator)
+    {
+      MethodInfo getMethod = propertyInfo.GetGetMethod(true);
+      if (getMethod == null)
+        throw new ArgumentException("Property '{0}' does not have a getter.".FormatWith(CultureInfo.InvariantCulture, propertyInfo.Name));
+
+      if (!getMethod.IsStatic)
+        generator.PushInstance(propertyInfo.DeclaringType);
+
+      generator.CallMethod(getMethod);
+      generator.BoxIfNeeded(propertyInfo.PropertyType);
+      generator.Return();
+    }
+
+    public override Func<T, object> CreateGet<T>(FieldInfo fieldInfo)
+    {
+      DynamicMethod dynamicMethod = CreateDynamicMethod("Get" + fieldInfo.Name, typeof(T), new[] { typeof(object) }, fieldInfo.DeclaringType);
+      ILGenerator generator = dynamicMethod.GetILGenerator();
+
+      GenerateCreateGetFieldIL(fieldInfo, generator);
+
+      return (Func<T, object>)dynamicMethod.CreateDelegate(typeof(Func<T, object>));
+    }
+
+    private void GenerateCreateGetFieldIL(FieldInfo fieldInfo, ILGenerator generator)
+    {
+      if (!fieldInfo.IsStatic)
+        generator.PushInstance(fieldInfo.DeclaringType);
+
+      generator.Emit(OpCodes.Ldfld, fieldInfo);
+      generator.BoxIfNeeded(fieldInfo.FieldType);
+      generator.Return();
+    }
+
+    public override Action<T, object> CreateSet<T>(FieldInfo fieldInfo)
+    {
+      DynamicMethod dynamicMethod = CreateDynamicMethod("Set" + fieldInfo.Name, null, new[] { typeof(T), typeof(object) }, fieldInfo.DeclaringType);
+      ILGenerator generator = dynamicMethod.GetILGenerator();
+
+      GenerateCreateSetFieldIL(fieldInfo, generator);
+
+      return (Action<T, object>)dynamicMethod.CreateDelegate(typeof(Action<T, object>));
+    }
+
+    internal static void GenerateCreateSetFieldIL(FieldInfo fieldInfo, ILGenerator generator)
+    {
+      if (!fieldInfo.IsStatic)
+        generator.PushInstance(fieldInfo.DeclaringType);
+
+      generator.Emit(OpCodes.Ldarg_1);
+      generator.UnboxIfNeeded(fieldInfo.FieldType);
+      generator.Emit(OpCodes.Stfld, fieldInfo);
+      generator.Return();
+    }
+
+    public override Action<T, object> CreateSet<T>(PropertyInfo propertyInfo)
+    {
+      DynamicMethod dynamicMethod = CreateDynamicMethod("Set" + propertyInfo.Name, null, new[] { typeof(T), typeof(object) }, propertyInfo.DeclaringType);
+      ILGenerator generator = dynamicMethod.GetILGenerator();
+
+      GenerateCreateSetPropertyIL(propertyInfo, generator);
+
+      return (Action<T, object>)dynamicMethod.CreateDelegate(typeof(Action<T, object>));
+    }
+
+    internal static void GenerateCreateSetPropertyIL(PropertyInfo propertyInfo, ILGenerator generator)
+    {
+      MethodInfo setMethod = propertyInfo.GetSetMethod(true);
+      if (!setMethod.IsStatic)
+        generator.PushInstance(propertyInfo.DeclaringType);
+
+      generator.Emit(OpCodes.Ldarg_1);
+      generator.UnboxIfNeeded(propertyInfo.PropertyType);
+      generator.CallMethod(setMethod);
+      generator.Return();
+    }
+  }
+}
 #endif
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DynamicUtils.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DynamicUtils.cs
new file mode 100644
index 0000000..a72312f
--- /dev/null
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DynamicUtils.cs
@@ -0,0 +1,225 @@
+#region License
+// 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.
+#endregion
+
+#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
+using System;
+using System.Collections.Generic;
+using System.Dynamic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Globalization;
+using Newtonsoft.Json.Serialization;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal static class DynamicUtils
+  {
+    internal static class BinderWrapper
+    {
+#if !SILVERLIGHT
+      public const string CSharpAssemblyName = "Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
+#else
+      public const string CSharpAssemblyName = "Microsoft.CSharp, Version=2.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";
+#endif
+
+      private const string BinderTypeName = "Microsoft.CSharp.RuntimeBinder.Binder, " + CSharpAssemblyName;
+      private const string CSharpArgumentInfoTypeName = "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo, " + CSharpAssemblyName;
+      private const string CSharpArgumentInfoFlagsTypeName = "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, " + CSharpAssemblyName;
+      private const string CSharpBinderFlagsTypeName = "Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, " + CSharpAssemblyName;
+
+      private static object _getCSharpArgumentInfoArray;
+      private static object _setCSharpArgumentInfoArray;
+      private static MethodCall<object, object> _getMemberCall;
+      private static MethodCall<object, object> _setMemberCall;
+      private static bool _init;
+
+      private static void Init()
+      {
+        if (!_init)
+        {
+          Type binderType = Type.GetType(BinderTypeName, false);
+          if (binderType == null)
+            throw new InvalidOperationException("Could not resolve type '{0}'. You may need to add a reference to Microsoft.CSharp.dll to work with dynamic types.".FormatWith(CultureInfo.InvariantCulture, BinderTypeName));
+
+          // None
+          _getCSharpArgumentInfoArray = CreateSharpArgumentInfoArray(0);
+          // None, Constant | UseCompileTimeType
+          _setCSharpArgumentInfoArray = CreateSharpArgumentInfoArray(0, 3);
+          CreateMemberCalls();
+
+          _init = true;
+        }
+      }
+
+      private static object CreateSharpArgumentInfoArray(params int[] values)
+      {
+        Type csharpArgumentInfoType = Type.GetType(CSharpArgumentInfoTypeName);
+        Type csharpArgumentInfoFlags = Type.GetType(CSharpArgumentInfoFlagsTypeName);
+
+        Array a = Array.CreateInstance(csharpArgumentInfoType, values.Length);
+
+        for (int i = 0; i < values.Length; i++)
+        {
+          MethodInfo createArgumentInfoMethod = csharpArgumentInfoType.GetMethod("Create", BindingFlags.Public | BindingFlags.Static, null, new[] { csharpArgumentInfoFlags, typeof(string) }, null);
+          object arg = createArgumentInfoMethod.Invoke(null, new object[] { 0, null });
+          a.SetValue(arg, i);
+        }
+
+        return a;
+      }
+
+      private static void CreateMemberCalls()
+      {
+        Type csharpArgumentInfoType = Type.GetType(CSharpArgumentInfoTypeName);
+        Type csharpBinderFlagsType = Type.GetType(CSharpBinderFlagsTypeName);
+        Type binderType = Type.GetType(BinderTypeName);
+
+        Type csharpArgumentInfoTypeEnumerableType = typeof(IEnumerable<>).MakeGenericType(csharpArgumentInfoType);
+
+        MethodInfo getMemberMethod = binderType.GetMethod("GetMember", BindingFlags.Public | BindingFlags.Static, null, new[] { csharpBinderFlagsType, typeof(string), typeof(Type), csharpArgumentInfoTypeEnumerableType }, null);
+        _getMemberCall = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall<object>(getMemberMethod);
+
+        MethodInfo setMemberMethod = binderType.GetMethod("SetMember", BindingFlags.Public | BindingFlags.Static, null, new[] { csharpBinderFlagsType, typeof(string), typeof(Type), csharpArgumentInfoTypeEnumerableType }, null);
+        _setMemberCall = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall<object>(setMemberMethod);
+      }
+
+      public static CallSiteBinder GetMember(string name, Type context)
+      {
+        Init();
+        return (CallSiteBinder)_getMemberCall(null, 0, name, context, _getCSharpArgumentInfoArray);
+      }
+
+      public static CallSiteBinder SetMember(string name, Type context)
+      {
+        Init();
+        return (CallSiteBinder)_setMemberCall(null, 0, name, context, _setCSharpArgumentInfoArray);
+      }
+    }
+
+    public static bool TryGetMember(this IDynamicMetaObjectProvider dynamicProvider, string name, out object value)
+    {
+      ValidationUtils.ArgumentNotNull(dynamicProvider, "dynamicProvider");
+
+      GetMemberBinder getMemberBinder = (GetMemberBinder) BinderWrapper.GetMember(name, typeof (DynamicUtils));
+
+      CallSite<Func<CallSite, object, object>> callSite = CallSite<Func<CallSite, object, object>>.Create(new NoThrowGetBinderMember(getMemberBinder));
+
+      object result = callSite.Target(callSite, dynamicProvider);
+
+      if (!ReferenceEquals(result, NoThrowExpressionVisitor.ErrorResult))
+      {
+        value = result;
+        return true;
+      }
+      else
+      {
+        value = null;
+        return false;
+      }
+    }
+
+    public static bool TrySetMember(this IDynamicMetaObjectProvider dynamicProvider, string name, object value)
+    {
+      ValidationUtils.ArgumentNotNull(dynamicProvider, "dynamicProvider");
+
+      SetMemberBinder binder = (SetMemberBinder)BinderWrapper.SetMember(name, typeof(DynamicUtils));
+
+      var setterSite = CallSite<Func<CallSite, object, object, object>>.Create(new NoThrowSetBinderMember(binder));
+
+      object result = setterSite.Target(setterSite, dynamicProvider, value);
+
+      return !ReferenceEquals(result, NoThrowExpressionVisitor.ErrorResult);
+    }
+
+    public static IEnumerable<string> GetDynamicMemberNames(this IDynamicMetaObjectProvider dynamicProvider)
+    {
+      DynamicMetaObject metaObject = dynamicProvider.GetMetaObject(Expression.Constant(dynamicProvider));
+      return metaObject.GetDynamicMemberNames();
+    }
+
+    internal class NoThrowGetBinderMember : GetMemberBinder
+    {
+      private readonly GetMemberBinder _innerBinder;
+
+      public NoThrowGetBinderMember(GetMemberBinder innerBinder)
+        : base(innerBinder.Name, innerBinder.IgnoreCase)
+      {
+        _innerBinder = innerBinder;
+      }
+
+      public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
+      {
+        DynamicMetaObject retMetaObject = _innerBinder.Bind(target, new DynamicMetaObject[] { });
+
+        NoThrowExpressionVisitor noThrowVisitor = new NoThrowExpressionVisitor();
+        Expression resultExpression = noThrowVisitor.Visit(retMetaObject.Expression);
+
+        DynamicMetaObject finalMetaObject = new DynamicMetaObject(resultExpression, retMetaObject.Restrictions);
+        return finalMetaObject;
+      }
+    }
+
+    internal class NoThrowSetBinderMember : SetMemberBinder
+    {
+      private readonly SetMemberBinder _innerBinder;
+
+      public NoThrowSetBinderMember(SetMemberBinder innerBinder)
+        : base(innerBinder.Name, innerBinder.IgnoreCase)
+      {
+        _innerBinder = innerBinder;
+      }
+
+      public override DynamicMetaObject FallbackSetMember(DynamicMetaObject target, DynamicMetaObject value, DynamicMetaObject errorSuggestion)
+      {
+        DynamicMetaObject retMetaObject = _innerBinder.Bind(target, new DynamicMetaObject[] { value });
+
+        NoThrowExpressionVisitor noThrowVisitor = new NoThrowExpressionVisitor();
+        Expression resultExpression = noThrowVisitor.Visit(retMetaObject.Expression);
+
+        DynamicMetaObject finalMetaObject = new DynamicMetaObject(resultExpression, retMetaObject.Restrictions);
+        return finalMetaObject;
+      }
+    }
+
+
+    internal class NoThrowExpressionVisitor : ExpressionVisitor
+    {
+      internal static readonly object ErrorResult = new object();
+
+      protected override Expression VisitConditional(ConditionalExpression node)
+      {
+        // if the result of a test is to throw an error, rewrite to result an error result value
+        if (node.IfFalse.NodeType == ExpressionType.Throw)
+          return Expression.Condition(node.Test, node.IfTrue, Expression.Constant(ErrorResult));
+
+        return base.VisitConditional(node);
+      }
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DynamicWrapper.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DynamicWrapper.cs
index 6c80c65..9b9c384 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DynamicWrapper.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DynamicWrapper.cs
@@ -1,279 +1,264 @@
-#if !SILVERLIGHT && !PocketPC
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-using System.Reflection.Emit;
-using System.Resources;
-using System.Text;
-using System.Threading;
-using System.Globalization;
-
-namespace Newtonsoft.Json.Utilities
-{
-  internal class DynamicWrapperBase
-  {
-    internal protected object UnderlyingObject;
-  }
-
-  internal static class DynamicWrapper
-  {
-    private static readonly object _lock = new object();
-    private static readonly WrapperDictionary _wrapperDictionary = new WrapperDictionary();
-
-    private static ModuleBuilder _moduleBuilder;
-
-    private static ModuleBuilder ModuleBuilder
-    {
-      get
-      {
-        Init();
-        return _moduleBuilder;
-      }
-    }
-
-    private static void Init()
-    {
-      if (_moduleBuilder == null)
-      {
-        lock (_lock)
-        {
-          if (_moduleBuilder == null)
-          {
-            AssemblyName assemblyName = new AssemblyName("Newtonsoft.Json.Dynamic");
-            assemblyName.KeyPair = new StrongNameKeyPair(GetStrongKey());
-
-            AssemblyBuilder assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
-            _moduleBuilder = assembly.DefineDynamicModule("Newtonsoft.Json.DynamicModule", false);
-          }
-        }
-      }
-    }
-
-    private static byte[] GetStrongKey()
-    {
-      using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Newtonsoft.Json.Dynamic.snk"))
-      {
-        if (stream == null)
-          throw new MissingManifestResourceException("Should have a Newtonsoft.Json.Dynamic.snk as an embedded resource.");
-
-        int length = (int)stream.Length;
-        byte[] buffer = new byte[length];
-        stream.Read(buffer, 0, length);
-
-        return buffer;
-      }
-    }
-
-    public static Type GetWrapper(Type interfaceType, Type realObjectType)
-    {
-      Type wrapperType = _wrapperDictionary.GetType(interfaceType, realObjectType);
-
-      if (wrapperType == null)
-      {
-        wrapperType = GenerateWrapperType(interfaceType, realObjectType);
-        _wrapperDictionary.SetType(interfaceType, realObjectType, wrapperType);
-      }
-
-      return wrapperType;
-    }
-
-    public static object GetUnderlyingObject(object wrapper)
-    {
-      DynamicWrapperBase wrapperBase = wrapper as DynamicWrapperBase;
-      if (wrapperBase == null)
-        throw new ArgumentException("Object is not a wrapper.", "wrapper");
-
-      return wrapperBase.UnderlyingObject;
-    }
-
-    private static Type GenerateWrapperType(Type interfaceType, Type underlyingType)
-    {
-      TypeBuilder wrapperBuilder = ModuleBuilder.DefineType(
-          "{0}_{1}_Wrapper".FormatWith(CultureInfo.InvariantCulture, interfaceType.Name, underlyingType.Name),
-          TypeAttributes.NotPublic | TypeAttributes.Sealed,
-          typeof(DynamicWrapperBase),
-          new[] { interfaceType });
-
-      WrapperMethodBuilder wrapperMethod = new WrapperMethodBuilder(underlyingType, wrapperBuilder);
-
-      foreach (MethodInfo method in interfaceType.AllMethods())
-      {
-        wrapperMethod.Generate(method);
-      }
-
-      return wrapperBuilder.CreateType();
-    }
-
-    public static T CreateWrapper<T>(object realObject) where T : class
-    {
-      var dynamicType = GetWrapper(typeof(T), realObject.GetType());
-      var dynamicWrapper = (DynamicWrapperBase)Activator.CreateInstance(dynamicType);
-
-      dynamicWrapper.UnderlyingObject = realObject;
-
-      return dynamicWrapper as T;
-    }
-  }
-
-  internal class WrapperMethodBuilder
-  {
-    private readonly Type _realObjectType;
-    private readonly TypeBuilder _wrapperBuilder;
-
-    public WrapperMethodBuilder(Type realObjectType, TypeBuilder proxyBuilder)
-    {
-      _realObjectType = realObjectType;
-      _wrapperBuilder = proxyBuilder;
-    }
-
-    public void Generate(MethodInfo newMethod)
-    {
-      if (newMethod.IsGenericMethod)
-        newMethod = newMethod.GetGenericMethodDefinition();
-
-      FieldInfo srcField = typeof(DynamicWrapperBase).GetField("UnderlyingObject", BindingFlags.Instance | BindingFlags.NonPublic);
-
-      var parameters = newMethod.GetParameters();
-      var parameterTypes = parameters.Select(parameter => parameter.ParameterType).ToArray();
-
-      MethodBuilder methodBuilder = _wrapperBuilder.DefineMethod(
-          newMethod.Name,
-          MethodAttributes.Public | MethodAttributes.Virtual,
-          newMethod.ReturnType,
-          parameterTypes);
-
-      if (newMethod.IsGenericMethod)
-      {
-        methodBuilder.DefineGenericParameters(
-            newMethod.GetGenericArguments().Select(arg => arg.Name).ToArray());
-      }
-
-      ILGenerator ilGenerator = methodBuilder.GetILGenerator();
-
-      LoadUnderlyingObject(ilGenerator, srcField);
-      PushParameters(parameters, ilGenerator);
-      ExecuteMethod(newMethod, parameterTypes, ilGenerator);
-      Return(ilGenerator);
-    }
-
-    private static void Return(ILGenerator ilGenerator)
-    {
-      ilGenerator.Emit(OpCodes.Ret);
-    }
-
-    private void ExecuteMethod(MethodBase newMethod, Type[] parameterTypes, ILGenerator ilGenerator)
-    {
-      MethodInfo srcMethod = GetMethod(newMethod, parameterTypes);
-
-      if (srcMethod == null)
-        throw new MissingMethodException("Unable to find method " + newMethod.Name + " on " + _realObjectType.FullName);
-
-      ilGenerator.Emit(OpCodes.Call, srcMethod);
-    }
-
-    private MethodInfo GetMethod(MethodBase realMethod, Type[] parameterTypes)
-    {
-      if (realMethod.IsGenericMethod)
-        return _realObjectType.GetGenericMethod(realMethod.Name, parameterTypes);
-
-      return _realObjectType.GetMethod(realMethod.Name, parameterTypes);
-    }
-
-    private static void PushParameters(ICollection<ParameterInfo> parameters, ILGenerator ilGenerator)
-    {
-      for (int i = 1; i < parameters.Count + 1; i++)
-        ilGenerator.Emit(OpCodes.Ldarg, i);
-    }
-
-    private static void LoadUnderlyingObject(ILGenerator ilGenerator, FieldInfo srcField)
-    {
-      ilGenerator.Emit(OpCodes.Ldarg_0);
-      ilGenerator.Emit(OpCodes.Ldfld, srcField);
-    }
-  }
-
-  internal class WrapperDictionary
-  {
-    private readonly Dictionary<string, Type> _wrapperTypes = new Dictionary<string, Type>();
-
-    private static string GenerateKey(Type interfaceType, Type realObjectType)
-    {
-      return interfaceType.Name + "_" + realObjectType.Name;
-    }
-
-    public Type GetType(Type interfaceType, Type realObjectType)
-    {
-      string key = GenerateKey(interfaceType, realObjectType);
-
-      if (_wrapperTypes.ContainsKey(key))
-        return _wrapperTypes[key];
-
-      return null;
-    }
-
-    public void SetType(Type interfaceType, Type realObjectType, Type wrapperType)
-    {
-      string key = GenerateKey(interfaceType, realObjectType);
-
-      if (_wrapperTypes.ContainsKey(key))
-        _wrapperTypes[key] = wrapperType;
-      else
-        _wrapperTypes.Add(key, wrapperType);
-    }
-  }
-
-  internal static class TypeExtensions
-  {
-    public static MethodInfo GetGenericMethod(this Type type, string name, params Type[] parameterTypes)
-    {
-      var methods = type.GetMethods().Where(method => method.Name == name);
-
-      foreach (var method in methods)
-      {
-        if (method.HasParameters(parameterTypes))
-          return method;
-      }
-
-      return null;
-    }
-
-    public static bool HasParameters(this MethodInfo method, params Type[] parameterTypes)
-    {
-      var methodParameters = method.GetParameters().Select(parameter => parameter.ParameterType).ToArray();
-
-      if (methodParameters.Length != parameterTypes.Length)
-        return false;
-
-      for (int i = 0; i < methodParameters.Length; i++)
-        if (methodParameters[i].ToString() != parameterTypes[i].ToString())
-          return false;
-
-      return true;
-    }
-
-    public static IEnumerable<Type> AllInterfaces(this Type target)
-    {
-      foreach (var IF in target.GetInterfaces())
-      {
-        yield return IF;
-        foreach (var childIF in IF.AllInterfaces())
-        {
-          yield return childIF;
-        }
-      }
-    }
-
-    public static IEnumerable<MethodInfo> AllMethods(this Type target)
-    {
-      var allTypes = target.AllInterfaces().ToList();
-      allTypes.Add(target);
-
-      return from type in allTypes
-             from method in type.GetMethods()
-             select method;
-    }
-  }
-}
+#region License
+// 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.
+#endregion
+
+#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Resources;
+using System.Globalization;
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#else
+using System.Linq;
+#endif
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal class DynamicWrapperBase
+  {
+    internal protected object UnderlyingObject;
+  }
+
+  internal static class DynamicWrapper
+  {
+    private static readonly object _lock = new object();
+    private static readonly WrapperDictionary _wrapperDictionary = new WrapperDictionary();
+
+    private static ModuleBuilder _moduleBuilder;
+
+    private static ModuleBuilder ModuleBuilder
+    {
+      get
+      {
+        Init();
+        return _moduleBuilder;
+      }
+    }
+
+    private static void Init()
+    {
+      if (_moduleBuilder == null)
+      {
+        lock (_lock)
+        {
+          if (_moduleBuilder == null)
+          {
+            AssemblyName assemblyName = new AssemblyName("Newtonsoft.Json.Dynamic");
+            assemblyName.KeyPair = new StrongNameKeyPair(GetStrongKey());
+
+            AssemblyBuilder assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
+            _moduleBuilder = assembly.DefineDynamicModule("Newtonsoft.Json.DynamicModule", false);
+          }
+        }
+      }
+    }
+
+    private static byte[] GetStrongKey()
+    {
+      const string name = "Newtonsoft.Json.Dynamic.snk";
+
+      using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name))
+      {
+        if (stream == null)
+          throw new MissingManifestResourceException("Should have " + name + " as an embedded resource.");
+
+        int length = (int)stream.Length;
+        byte[] buffer = new byte[length];
+        stream.Read(buffer, 0, length);
+
+        return buffer;
+      }
+    }
+
+    public static Type GetWrapper(Type interfaceType, Type realObjectType)
+    {
+      Type wrapperType = _wrapperDictionary.GetType(interfaceType, realObjectType);
+
+      if (wrapperType == null)
+      {
+        lock (_lock)
+        {
+          wrapperType = _wrapperDictionary.GetType(interfaceType, realObjectType);
+
+          if (wrapperType == null)
+          {
+            wrapperType = GenerateWrapperType(interfaceType, realObjectType);
+            _wrapperDictionary.SetType(interfaceType, realObjectType, wrapperType);
+          }
+        }
+      }
+
+      return wrapperType;
+    }
+
+    public static object GetUnderlyingObject(object wrapper)
+    {
+      DynamicWrapperBase wrapperBase = wrapper as DynamicWrapperBase;
+      if (wrapperBase == null)
+        throw new ArgumentException("Object is not a wrapper.", "wrapper");
+
+      return wrapperBase.UnderlyingObject;
+    }
+
+    private static Type GenerateWrapperType(Type interfaceType, Type underlyingType)
+    {
+      TypeBuilder wrapperBuilder = ModuleBuilder.DefineType(
+          "{0}_{1}_Wrapper".FormatWith(CultureInfo.InvariantCulture, interfaceType.Name, underlyingType.Name),
+          TypeAttributes.NotPublic | TypeAttributes.Sealed,
+          typeof(DynamicWrapperBase),
+          new[] { interfaceType });
+
+      WrapperMethodBuilder wrapperMethod = new WrapperMethodBuilder(underlyingType, wrapperBuilder);
+
+      foreach (MethodInfo method in interfaceType.GetAllMethods())
+      {
+        wrapperMethod.Generate(method);
+      }
+
+      return wrapperBuilder.CreateType();
+    }
+
+    public static T CreateWrapper<T>(object realObject) where T : class
+    {
+      var dynamicType = GetWrapper(typeof(T), realObject.GetType());
+      var dynamicWrapper = (DynamicWrapperBase)Activator.CreateInstance(dynamicType);
+
+      dynamicWrapper.UnderlyingObject = realObject;
+
+      return dynamicWrapper as T;
+    }
+  }
+
+  internal class WrapperMethodBuilder
+  {
+    private readonly Type _realObjectType;
+    private readonly TypeBuilder _wrapperBuilder;
+
+    public WrapperMethodBuilder(Type realObjectType, TypeBuilder proxyBuilder)
+    {
+      _realObjectType = realObjectType;
+      _wrapperBuilder = proxyBuilder;
+    }
+
+    public void Generate(MethodInfo newMethod)
+    {
+      if (newMethod.IsGenericMethod)
+        newMethod = newMethod.GetGenericMethodDefinition();
+
+      FieldInfo srcField = typeof(DynamicWrapperBase).GetField("UnderlyingObject", BindingFlags.Instance | BindingFlags.NonPublic);
+
+      var parameters = newMethod.GetParameters();
+      var parameterTypes = parameters.Select(parameter => parameter.ParameterType).ToArray();
+
+      MethodBuilder methodBuilder = _wrapperBuilder.DefineMethod(
+          newMethod.Name,
+          MethodAttributes.Public | MethodAttributes.Virtual,
+          newMethod.ReturnType,
+          parameterTypes);
+
+      if (newMethod.IsGenericMethod)
+      {
+        methodBuilder.DefineGenericParameters(
+            newMethod.GetGenericArguments().Select(arg => arg.Name).ToArray());
+      }
+
+      ILGenerator ilGenerator = methodBuilder.GetILGenerator();
+
+      LoadUnderlyingObject(ilGenerator, srcField);
+      PushParameters(parameters, ilGenerator);
+      ExecuteMethod(newMethod, parameterTypes, ilGenerator);
+      Return(ilGenerator);
+    }
+
+    private static void Return(ILGenerator ilGenerator)
+    {
+      ilGenerator.Emit(OpCodes.Ret);
+    }
+
+    private void ExecuteMethod(MethodBase newMethod, Type[] parameterTypes, ILGenerator ilGenerator)
+    {
+      MethodInfo srcMethod = GetMethod(newMethod, parameterTypes);
+
+      if (srcMethod == null)
+        throw new MissingMethodException("Unable to find method " + newMethod.Name + " on " + _realObjectType.FullName);
+
+      ilGenerator.Emit(OpCodes.Call, srcMethod);
+    }
+
+    private MethodInfo GetMethod(MethodBase realMethod, Type[] parameterTypes)
+    {
+      if (realMethod.IsGenericMethod)
+        return _realObjectType.GetGenericMethod(realMethod.Name, parameterTypes);
+
+      return _realObjectType.GetMethod(realMethod.Name, parameterTypes);
+    }
+
+    private static void PushParameters(ICollection<ParameterInfo> parameters, ILGenerator ilGenerator)
+    {
+      for (int i = 1; i < parameters.Count + 1; i++)
+        ilGenerator.Emit(OpCodes.Ldarg, i);
+    }
+
+    private static void LoadUnderlyingObject(ILGenerator ilGenerator, FieldInfo srcField)
+    {
+      ilGenerator.Emit(OpCodes.Ldarg_0);
+      ilGenerator.Emit(OpCodes.Ldfld, srcField);
+    }
+  }
+
+  internal class WrapperDictionary
+  {
+    private readonly Dictionary<string, Type> _wrapperTypes = new Dictionary<string, Type>();
+
+    private static string GenerateKey(Type interfaceType, Type realObjectType)
+    {
+      return interfaceType.Name + "_" + realObjectType.Name;
+    }
+
+    public Type GetType(Type interfaceType, Type realObjectType)
+    {
+      string key = GenerateKey(interfaceType, realObjectType);
+
+      if (_wrapperTypes.ContainsKey(key))
+        return _wrapperTypes[key];
+
+      return null;
+    }
+
+    public void SetType(Type interfaceType, Type realObjectType, Type wrapperType)
+    {
+      string key = GenerateKey(interfaceType, realObjectType);
+
+      if (_wrapperTypes.ContainsKey(key))
+        _wrapperTypes[key] = wrapperType;
+      else
+        _wrapperTypes.Add(key, wrapperType);
+    }
+  }
+}
 #endif
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/EnumUtils.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/EnumUtils.cs
index e40c80e..bf4e7c6 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/EnumUtils.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/EnumUtils.cs
@@ -1,236 +1,147 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Reflection;
-
-namespace Newtonsoft.Json.Utilities
-{
-  internal static class EnumUtils
-  {
-    /// <summary>
-    /// Parses the specified enum member name, returning it's value.
-    /// </summary>
-    /// <param name="enumMemberName">Name of the enum member.</param>
-    /// <returns></returns>
-    public static T Parse<T>(string enumMemberName) where T : struct
-    {
-      return Parse<T>(enumMemberName, false);
-    }
-
-    /// <summary>
-    /// Parses the specified enum member name, returning it's value.
-    /// </summary>
-    /// <param name="enumMemberName">Name of the enum member.</param>
-    /// <param name="ignoreCase">If set to <c>true</c> ignore case.</param>
-    /// <returns></returns>
-    public static T Parse<T>(string enumMemberName, bool ignoreCase) where T : struct
-    {
-      ValidationUtils.ArgumentTypeIsEnum(typeof(T), "T");
-
-      return (T)Enum.Parse(typeof(T), enumMemberName, ignoreCase);
-    }
-
-    public static bool TryParse<T>(string enumMemberName, bool ignoreCase, out T value) where T : struct
-    {
-      ValidationUtils.ArgumentTypeIsEnum(typeof(T), "T");
-
-      return MiscellaneousUtils.TryAction(() => Parse<T>(enumMemberName, ignoreCase), out value);
-    }
-
-    public static IList<T> GetFlagsValues<T>(T value) where T : struct
-    {
-      Type enumType = typeof(T);
-
-      if (!enumType.IsDefined(typeof(FlagsAttribute), false))
-        throw new Exception("Enum type {0} is not a set of flags.".FormatWith(CultureInfo.InvariantCulture, enumType));
-
-      Type underlyingType = Enum.GetUnderlyingType(value.GetType());
-
-      ulong num = Convert.ToUInt64(value, CultureInfo.InvariantCulture);
-      EnumValues<ulong> enumNameValues = GetNamesAndValues<T>();
-      IList<T> selectedFlagsValues = new List<T>();
-
-      foreach (EnumValue<ulong> enumNameValue in enumNameValues)
-      {
-        if ((num & enumNameValue.Value) == enumNameValue.Value && enumNameValue.Value != 0)
-          selectedFlagsValues.Add((T)Convert.ChangeType(enumNameValue.Value, underlyingType, CultureInfo.CurrentCulture));
-      }
-
-      if (selectedFlagsValues.Count == 0 && enumNameValues.SingleOrDefault(v => v.Value == 0) != null)
-        selectedFlagsValues.Add(default(T));
-
-      return selectedFlagsValues;
-    }
-
-    /// <summary>
-    /// Gets a dictionary of the names and values of an Enum type.
-    /// </summary>
-    /// <returns></returns>
-    public static EnumValues<ulong> GetNamesAndValues<T>() where T : struct
-    {
-      return GetNamesAndValues<ulong>(typeof(T));
-    }
-
-    /// <summary>
-    /// Gets a dictionary of the names and values of an Enum type.
-    /// </summary>
-    /// <returns></returns>
-    public static EnumValues<TUnderlyingType> GetNamesAndValues<TEnum, TUnderlyingType>()
-      where TEnum : struct
-      where TUnderlyingType : struct
-    {
-      return GetNamesAndValues<TUnderlyingType>(typeof(TEnum));
-    }
-
-    /// <summary>
-    /// Gets a dictionary of the names and values of an Enum type.
-    /// </summary>
-    /// <param name="enumType">The enum type to get names and values for.</param>
-    /// <returns></returns>
-    public static EnumValues<TUnderlyingType> GetNamesAndValues<TUnderlyingType>(Type enumType) where TUnderlyingType : struct
-    {
-      if (enumType == null)
-        throw new ArgumentNullException("enumType");
-
-      ValidationUtils.ArgumentTypeIsEnum(enumType, "enumType");
-
-      IList<object> enumValues = GetValues(enumType);
-      IList<string> enumNames = GetNames(enumType);
-
-      EnumValues<TUnderlyingType> nameValues = new EnumValues<TUnderlyingType>();
-
-      for (int i = 0; i < enumValues.Count; i++)
-      {
-        try
-        {
-          nameValues.Add(new EnumValue<TUnderlyingType>(enumNames[i], (TUnderlyingType)Convert.ChangeType(enumValues[i], typeof(TUnderlyingType), CultureInfo.CurrentCulture)));
-        }
-        catch (OverflowException e)
-        {
-          throw new Exception(
-            string.Format(CultureInfo.InvariantCulture, "Value from enum with the underlying type of {0} cannot be added to dictionary with a value type of {1}. Value was too large: {2}",
-              Enum.GetUnderlyingType(enumType), typeof(TUnderlyingType), Convert.ToUInt64(enumValues[i], CultureInfo.InvariantCulture)), e);
-        }
-      }
-
-      return nameValues;
-    }
-
-    public static IList<T> GetValues<T>()
-    {
-      return GetValues(typeof(T)).Cast<T>().ToList();
-    }
-
-    public static IList<object> GetValues(Type enumType)
-    {
-      if (!enumType.IsEnum)
-        throw new ArgumentException("Type '" + enumType.Name + "' is not an enum.");
-
-      List<object> values = new List<object>();
-
-      var fields = from field in enumType.GetFields()
-                   where field.IsLiteral
-                   select field;
-
-      foreach (FieldInfo field in fields)
-      {
-        object value = field.GetValue(enumType);
-        values.Add(value);
-      }
-
-      return values;
-    }
-
-    public static IList<string> GetNames<T>()
-    {
-      return GetNames(typeof(T));
-    }
-
-    public static IList<string> GetNames(Type enumType)
-    {
-      if (!enumType.IsEnum)
-        throw new ArgumentException("Type '" + enumType.Name + "' is not an enum.");
-
-      List<string> values = new List<string>();
-
-      var fields = from field in enumType.GetFields()
-                   where field.IsLiteral
-                   select field;
-
-      foreach (FieldInfo field in fields)
-      {
-        values.Add(field.Name);
-      }
-
-      return values;
-    }
-
-
-    /// <summary>
-    /// Gets the maximum valid value of an Enum type. Flags enums are ORed.
-    /// </summary>
-    /// <typeparam name="TEnumType">The type of the returned value. Must be assignable from the enum's underlying value type.</typeparam>
-    /// <param name="enumType">The enum type to get the maximum value for.</param>
-    /// <returns></returns>
-    public static TEnumType GetMaximumValue<TEnumType>(Type enumType) where TEnumType : IConvertible, IComparable<TEnumType>
-    {
-      if (enumType == null)
-        throw new ArgumentNullException("enumType");
-
-      Type enumUnderlyingType = Enum.GetUnderlyingType(enumType);
-
-      if (!typeof(TEnumType).IsAssignableFrom(enumUnderlyingType))
-        throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "TEnumType is not assignable from the enum's underlying type of {0}.", enumUnderlyingType.Name));
-
-      ulong maximumValue = 0;
-      IList<object> enumValues = GetValues(enumType);
-
-      if (enumType.IsDefined(typeof(FlagsAttribute), false))
-      {
-        foreach (TEnumType value in enumValues)
-        {
-          maximumValue = maximumValue | value.ToUInt64(CultureInfo.InvariantCulture);
-        }
-      }
-      else
-      {
-        foreach (TEnumType value in enumValues)
-        {
-          ulong tempValue = value.ToUInt64(CultureInfo.InvariantCulture);
-
-          // maximumValue is smaller than the enum value
-          if (maximumValue.CompareTo(tempValue) == -1)
-            maximumValue = tempValue;
-        }
-      }
-
-      return (TEnumType)Convert.ChangeType(maximumValue, typeof(TEnumType), CultureInfo.InvariantCulture);
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#else
+using System.Linq;
+#endif
+using System.Reflection;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal static class EnumUtils
+  {
+    public static IList<T> GetFlagsValues<T>(T value) where T : struct
+    {
+      Type enumType = typeof(T);
+
+      if (!enumType.IsDefined(typeof(FlagsAttribute), false))
+        throw new ArgumentException("Enum type {0} is not a set of flags.".FormatWith(CultureInfo.InvariantCulture, enumType));
+
+      Type underlyingType = Enum.GetUnderlyingType(value.GetType());
+
+      ulong num = Convert.ToUInt64(value, CultureInfo.InvariantCulture);
+      EnumValues<ulong> enumNameValues = GetNamesAndValues<T>();
+      IList<T> selectedFlagsValues = new List<T>();
+
+      foreach (EnumValue<ulong> enumNameValue in enumNameValues)
+      {
+        if ((num & enumNameValue.Value) == enumNameValue.Value && enumNameValue.Value != 0)
+          selectedFlagsValues.Add((T)Convert.ChangeType(enumNameValue.Value, underlyingType, CultureInfo.CurrentCulture));
+      }
+
+      if (selectedFlagsValues.Count == 0 && enumNameValues.SingleOrDefault(v => v.Value == 0) != null)
+        selectedFlagsValues.Add(default(T));
+
+      return selectedFlagsValues;
+    }
+
+    /// <summary>
+    /// Gets a dictionary of the names and values of an Enum type.
+    /// </summary>
+    /// <returns></returns>
+    public static EnumValues<ulong> GetNamesAndValues<T>() where T : struct
+    {
+      return GetNamesAndValues<ulong>(typeof(T));
+    }
+
+    /// <summary>
+    /// Gets a dictionary of the names and values of an Enum type.
+    /// </summary>
+    /// <param name="enumType">The enum type to get names and values for.</param>
+    /// <returns></returns>
+    public static EnumValues<TUnderlyingType> GetNamesAndValues<TUnderlyingType>(Type enumType) where TUnderlyingType : struct
+    {
+      if (enumType == null)
+        throw new ArgumentNullException("enumType");
+
+      ValidationUtils.ArgumentTypeIsEnum(enumType, "enumType");
+
+      IList<object> enumValues = GetValues(enumType);
+      IList<string> enumNames = GetNames(enumType);
+
+      EnumValues<TUnderlyingType> nameValues = new EnumValues<TUnderlyingType>();
+
+      for (int i = 0; i < enumValues.Count; i++)
+      {
+        try
+        {
+          nameValues.Add(new EnumValue<TUnderlyingType>(enumNames[i], (TUnderlyingType)Convert.ChangeType(enumValues[i], typeof(TUnderlyingType), CultureInfo.CurrentCulture)));
+        }
+        catch (OverflowException e)
+        {
+          throw new InvalidOperationException(
+            string.Format(CultureInfo.InvariantCulture, "Value from enum with the underlying type of {0} cannot be added to dictionary with a value type of {1}. Value was too large: {2}",
+              Enum.GetUnderlyingType(enumType), typeof(TUnderlyingType), Convert.ToUInt64(enumValues[i], CultureInfo.InvariantCulture)), e);
+        }
+      }
+
+      return nameValues;
+    }
+
+    public static IList<object> GetValues(Type enumType)
+    {
+      if (!enumType.IsEnum())
+        throw new ArgumentException("Type '" + enumType.Name + "' is not an enum.");
+
+      List<object> values = new List<object>();
+
+      var fields = from field in enumType.GetFields()
+                   where field.IsLiteral
+                   select field;
+
+      foreach (FieldInfo field in fields)
+      {
+        object value = field.GetValue(enumType);
+        values.Add(value);
+      }
+
+      return values;
+    }
+
+    public static IList<string> GetNames(Type enumType)
+    {
+      if (!enumType.IsEnum())
+        throw new ArgumentException("Type '" + enumType.Name + "' is not an enum.");
+
+      List<string> values = new List<string>();
+
+      var fields = from field in enumType.GetFields()
+                   where field.IsLiteral
+                   select field;
+
+      foreach (FieldInfo field in fields)
+      {
+        values.Add(field.Name);
+      }
+
+      return values;
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/EnumValue.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/EnumValue.cs
index 0f199c3..51a9f39 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/EnumValue.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/EnumValue.cs
@@ -1,53 +1,48 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Newtonsoft.Json.Utilities
-{
-  internal class EnumValue<T> where T : struct
-  {
-    private string _name;
-    private T _value;
-
-    public string Name
-    {
-      get { return _name; }
-    }
-    public T Value
-    {
-      get { return _value; }
-    }
-
-    public EnumValue(string name, T value)
-    {
-      _name = name;
-      _value = value;
-    }
-  }
+#region License
+// 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.
+#endregion
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal class EnumValue<T> where T : struct
+  {
+    private readonly string _name;
+    private readonly T _value;
+
+    public string Name
+    {
+      get { return _name; }
+    }
+    public T Value
+    {
+      get { return _value; }
+    }
+
+    public EnumValue(string name, T value)
+    {
+      _name = name;
+      _value = value;
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/EnumValues.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/EnumValues.cs
index ae385c2..33e805f 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/EnumValues.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/EnumValues.cs
@@ -1,41 +1,37 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Linq;
-using System.Text;
-
-namespace Newtonsoft.Json.Utilities
-{
-  internal class EnumValues<T> : KeyedCollection<string, EnumValue<T>> where T : struct
-  {
-    protected override string GetKeyForItem(EnumValue<T> item)
-    {
-      return item.Name;
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System.Collections.ObjectModel;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal class EnumValues<T> : KeyedCollection<string, EnumValue<T>> where T : struct
+  {
+    protected override string GetKeyForItem(EnumValue<T> item)
+    {
+      return item.Name;
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ILGeneratorExtensions.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ILGeneratorExtensions.cs
index c508fc4..b27a28d 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ILGeneratorExtensions.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ILGeneratorExtensions.cs
@@ -1,77 +1,74 @@
-#region License
-// 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.
-#endregion
-
-#if !PocketPC && !SILVERLIGHT
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection.Emit;
-using System.Text;
-using System.Reflection;
-
-namespace Newtonsoft.Json.Utilities
-{
-  internal static class ILGeneratorExtensions
-  {
-    public static void PushInstance(this ILGenerator generator, Type type)
-    {
-      generator.Emit(OpCodes.Ldarg_0);
-      if (type.IsValueType)
-        generator.Emit(OpCodes.Unbox, type);
-      else
-        generator.Emit(OpCodes.Castclass, type);
-    }
-
-    public static void BoxIfNeeded(this ILGenerator generator, Type type)
-    {
-      if (type.IsValueType)
-        generator.Emit(OpCodes.Box, type);
-      else
-        generator.Emit(OpCodes.Castclass, type);
-    }
-
-    public static void UnboxIfNeeded(this ILGenerator generator, Type type)
-    {
-      if (type.IsValueType)
-        generator.Emit(OpCodes.Unbox_Any, type);
-      else
-        generator.Emit(OpCodes.Castclass, type);
-    }
-
-    public static void CallMethod(this ILGenerator generator, MethodInfo methodInfo)
-    {
-      if (methodInfo.IsFinal || !methodInfo.IsVirtual)
-        generator.Emit(OpCodes.Call, methodInfo);
-      else
-        generator.Emit(OpCodes.Callvirt, methodInfo);
-    }
-
-    public static void Return(this ILGenerator generator)
-    {
-      generator.Emit(OpCodes.Ret);
-    }
-  }
-}
+#region License
+// 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.
+#endregion
+
+#if !(SILVERLIGHT || PORTABLE || NETFX_CORE)
+using System;
+using System.Reflection.Emit;
+using System.Reflection;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal static class ILGeneratorExtensions
+  {
+    public static void PushInstance(this ILGenerator generator, Type type)
+    {
+      generator.Emit(OpCodes.Ldarg_0);
+      if (type.IsValueType())
+        generator.Emit(OpCodes.Unbox, type);
+      else
+        generator.Emit(OpCodes.Castclass, type);
+    }
+
+    public static void BoxIfNeeded(this ILGenerator generator, Type type)
+    {
+      if (type.IsValueType())
+        generator.Emit(OpCodes.Box, type);
+      else
+        generator.Emit(OpCodes.Castclass, type);
+    }
+
+    public static void UnboxIfNeeded(this ILGenerator generator, Type type)
+    {
+      if (type.IsValueType())
+        generator.Emit(OpCodes.Unbox_Any, type);
+      else
+        generator.Emit(OpCodes.Castclass, type);
+    }
+
+    public static void CallMethod(this ILGenerator generator, MethodInfo methodInfo)
+    {
+      if (methodInfo.IsFinal || !methodInfo.IsVirtual)
+        generator.Emit(OpCodes.Call, methodInfo);
+      else
+        generator.Emit(OpCodes.Callvirt, methodInfo);
+    }
+
+    public static void Return(this ILGenerator generator)
+    {
+      generator.Emit(OpCodes.Ret);
+    }
+  }
+}
 #endif
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/JavaScriptUtils.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/JavaScriptUtils.cs
index b502394..e17fc25 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/JavaScriptUtils.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/JavaScriptUtils.cs
@@ -1,148 +1,170 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections;
-using System.Globalization;
-using System.IO;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Collections.Generic;
-
-namespace Newtonsoft.Json.Utilities
-{
-  internal static class JavaScriptUtils
-  {
-    public static void WriteEscapedJavaScriptString(TextWriter writer, string value, char delimiter, bool appendDelimiters)
-    {
-      // leading delimiter
-      if (appendDelimiters)
-        writer.Write(delimiter);
-
-      if (value != null)
-      {
-        int lastWritePosition = 0;
-        int skipped = 0;
-        char[] chars = null;
-
-        for (int i = 0; i < value.Length; i++)
-        {
-          char c = value[i];
-          string escapedValue;
-
-          switch (c)
-          {
-            case '\t':
-              escapedValue = @"\t";
-              break;
-            case '\n':
-              escapedValue = @"\n";
-              break;
-            case '\r':
-              escapedValue = @"\r";
-              break;
-            case '\f':
-              escapedValue = @"\f";
-              break;
-            case '\b':
-              escapedValue = @"\b";
-              break;
-            case '\\':
-              escapedValue = @"\\";
-              break;
-            case '\u0085': // Next Line
-              escapedValue = @"\u0085";
-              break;
-            case '\u2028': // Line Separator
-              escapedValue = @"\u2028";
-              break;
-            case '\u2029': // Paragraph Separator
-              escapedValue = @"\u2029";
-              break;
-            case '\'':
-              // only escape if this charater is being used as the delimiter
-              escapedValue = (delimiter == '\'') ? @"\'" : null;
-              break;
-            case '"':
-              // only escape if this charater is being used as the delimiter
-              escapedValue = (delimiter == '"') ? "\\\"" : null;
-              break;
-            default:
-              escapedValue = (c <= '\u001f') ? StringUtils.ToCharAsUnicode(c) : null;
-              break;
-          }
-
-          if (escapedValue != null)
-          {
-            if (chars == null)
-              chars = value.ToCharArray();
-
-            // write skipped text
-            if (skipped > 0)
-            {
-              writer.Write(chars, lastWritePosition, skipped);
-              skipped = 0;
-            }
-
-            // write escaped value and note position
-            writer.Write(escapedValue);
-            lastWritePosition = i + 1;
-          }
-          else
-          {
-            skipped++;
-          }
-        }
-
-        // write any remaining skipped text
-        if (skipped > 0)
-        {
-          if (lastWritePosition == 0)
-            writer.Write(value);
-          else
-            writer.Write(chars, lastWritePosition, skipped);
-        }
-      }
-
-      // trailing delimiter
-      if (appendDelimiters)
-        writer.Write(delimiter);
-    }
-
-    public static string ToEscapedJavaScriptString(string value)
-    {
-      return ToEscapedJavaScriptString(value, '"', true);
-    }
-
-    public static string ToEscapedJavaScriptString(string value, char delimiter, bool appendDelimiters)
-    {
-      using (StringWriter w = StringUtils.CreateStringWriter(StringUtils.GetLength(value) ?? 16))
-      {
-        WriteEscapedJavaScriptString(w, value, delimiter, appendDelimiters);
-        return w.ToString();
-      }
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections;
+using System.Globalization;
+using System.IO;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Collections.Generic;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal static class JavaScriptUtils
+  {
+    private const string EscapedUnicodeText = "!";
+
+    public static void WriteEscapedJavaScriptString(TextWriter writer, string s, char delimiter, bool appendDelimiters)
+    {
+      // leading delimiter
+      if (appendDelimiters)
+        writer.Write(delimiter);
+
+      if (s != null)
+      {
+        char[] chars = null;
+        char[] unicodeBuffer = null;
+        int lastWritePosition = 0;
+
+        for (int i = 0; i < s.Length; i++)
+        {
+          var c = s[i];
+
+          // don't escape standard text/numbers except '\' and the text delimiter
+          if (c >= ' ' && c < 128 && c != '\\' && c != delimiter)
+            continue;
+
+          string escapedValue;
+
+          switch (c)
+          {
+            case '\t':
+              escapedValue = @"\t";
+              break;
+            case '\n':
+              escapedValue = @"\n";
+              break;
+            case '\r':
+              escapedValue = @"\r";
+              break;
+            case '\f':
+              escapedValue = @"\f";
+              break;
+            case '\b':
+              escapedValue = @"\b";
+              break;
+            case '\\':
+              escapedValue = @"\\";
+              break;
+            case '\u0085': // Next Line
+              escapedValue = @"\u0085";
+              break;
+            case '\u2028': // Line Separator
+              escapedValue = @"\u2028";
+              break;
+            case '\u2029': // Paragraph Separator
+              escapedValue = @"\u2029";
+              break;
+            case '\'':
+              // this charater is being used as the delimiter
+              escapedValue = @"\'";
+              break;
+            case '"':
+              // this charater is being used as the delimiter
+              escapedValue = "\\\"";
+              break;
+            default:
+              if (c <= '\u001f')
+              {
+                if (unicodeBuffer == null)
+                  unicodeBuffer = new char[6];
+
+                StringUtils.ToCharAsUnicode(c, unicodeBuffer);
+
+                // slightly hacky but it saves multiple conditions in if test
+                escapedValue = EscapedUnicodeText;
+              }
+              else
+              {
+                escapedValue = null;
+              }
+              break;
+          }
+
+          if (escapedValue == null)
+            continue;
+
+          if (i > lastWritePosition)
+          {
+            if (chars == null)
+              chars = s.ToCharArray();
+
+            // write unchanged chars before writing escaped text
+            writer.Write(chars, lastWritePosition, i - lastWritePosition);
+          }
+
+          lastWritePosition = i + 1;
+          if (!string.Equals(escapedValue, EscapedUnicodeText))
+            writer.Write(escapedValue);
+          else
+            writer.Write(unicodeBuffer);
+        }
+
+        if (lastWritePosition == 0)
+        {
+          // no escaped text, write entire string
+          writer.Write(s);
+        }
+        else
+        {
+          if (chars == null)
+            chars = s.ToCharArray();
+
+          // write remaining text
+          writer.Write(chars, lastWritePosition, s.Length - lastWritePosition);
+        }
+      }
+
+      // trailing delimiter
+      if (appendDelimiters)
+        writer.Write(delimiter);
+    }
+
+    public static string ToEscapedJavaScriptString(string value)
+    {
+      return ToEscapedJavaScriptString(value, '"', true);
+    }
+
+    public static string ToEscapedJavaScriptString(string value, char delimiter, bool appendDelimiters)
+    {
+      using (StringWriter w = StringUtils.CreateStringWriter(StringUtils.GetLength(value) ?? 16))
+      {
+        WriteEscapedJavaScriptString(w, value, delimiter, appendDelimiters);
+        return w.ToString();
+      }
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/LateBoundReflectionDelegateFactory.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/LateBoundReflectionDelegateFactory.cs
index e112ab4..0fd1c3e 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/LateBoundReflectionDelegateFactory.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/LateBoundReflectionDelegateFactory.cs
@@ -1,75 +1,95 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Globalization;
-using System.Reflection;
-
-namespace Newtonsoft.Json.Utilities
-{
-  internal class LateBoundReflectionDelegateFactory : ReflectionDelegateFactory
-  {
-    public static readonly LateBoundReflectionDelegateFactory Instance = new LateBoundReflectionDelegateFactory();
-
-    public override MethodCall<T, object> CreateMethodCall<T>(MethodBase method)
-    {
-      ConstructorInfo c = method as ConstructorInfo;
-      if (c != null)
-        return (o, a) => c.Invoke(a);
-
-      return (o, a) => method.Invoke(o, a);
-    }
-
-    public override Func<T> CreateDefaultConstructor<T>(Type type)
-    {
-      if (type.IsValueType)
-        return () => (T)ReflectionUtils.CreateInstance(type);
-
-      ConstructorInfo constructorInfo = ReflectionUtils.GetDefaultConstructor(type, true);
-
-      return () => (T)constructorInfo.Invoke(null);
-    }
-
-    public override Func<T, object> CreateGet<T>(PropertyInfo propertyInfo)
-    {
-      return o => propertyInfo.GetValue(o, null);
-    }
-
-    public override Func<T, object> CreateGet<T>(FieldInfo fieldInfo)
-    {
-      return o => fieldInfo.GetValue(o);
-    }
-
-    public override Action<T, object> CreateSet<T>(FieldInfo fieldInfo)
-    {
-      return (o, v) => fieldInfo.SetValue(o, v);
-    }
-
-    public override Action<T, object> CreateSet<T>(PropertyInfo propertyInfo)
-    {
-      return (o, v) => propertyInfo.SetValue(o, v, null);
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using Newtonsoft.Json.Serialization;
+using System.Reflection;
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#endif
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal class LateBoundReflectionDelegateFactory : ReflectionDelegateFactory
+  {
+    private static readonly LateBoundReflectionDelegateFactory _instance = new LateBoundReflectionDelegateFactory();
+
+    internal static ReflectionDelegateFactory Instance
+    {
+      get { return _instance; }
+    }
+
+    public override MethodCall<T, object> CreateMethodCall<T>(MethodBase method)
+    {
+      ValidationUtils.ArgumentNotNull(method, "method");
+
+      ConstructorInfo c = method as ConstructorInfo;
+      if (c != null)
+        return (o, a) => c.Invoke(a);
+
+      return (o, a) => method.Invoke(o, a);
+    }
+
+    public override Func<T> CreateDefaultConstructor<T>(Type type)
+    {
+      ValidationUtils.ArgumentNotNull(type, "type");
+
+      if (type.IsValueType())
+        return () => (T)ReflectionUtils.CreateInstance(type);
+
+      ConstructorInfo constructorInfo = ReflectionUtils.GetDefaultConstructor(type, true);
+
+      return () => (T)constructorInfo.Invoke(null);
+    }
+
+    public override Func<T, object> CreateGet<T>(PropertyInfo propertyInfo)
+    {
+      ValidationUtils.ArgumentNotNull(propertyInfo, "propertyInfo");
+
+      return o => propertyInfo.GetValue(o, null);
+    }
+
+    public override Func<T, object> CreateGet<T>(FieldInfo fieldInfo)
+    {
+      ValidationUtils.ArgumentNotNull(fieldInfo, "fieldInfo");
+
+      return o => fieldInfo.GetValue(o);
+    }
+
+    public override Action<T, object> CreateSet<T>(FieldInfo fieldInfo)
+    {
+      ValidationUtils.ArgumentNotNull(fieldInfo, "fieldInfo");
+
+      return (o, v) => fieldInfo.SetValue(o, v);
+    }
+
+    public override Action<T, object> CreateSet<T>(PropertyInfo propertyInfo)
+    {
+      ValidationUtils.ArgumentNotNull(propertyInfo, "propertyInfo");
+
+      return (o, v) => propertyInfo.SetValue(o, v, null);
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/LinqBridge.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/LinqBridge.cs
new file mode 100644
index 0000000..9237352
--- /dev/null
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/LinqBridge.cs
@@ -0,0 +1,3010 @@
+#if NET20
+
+#region License, Terms and Author(s)
+//
+// LINQBridge
+// Copyright (c) 2007-9 Atif Aziz, Joseph Albahari. All rights reserved.
+//
+//  Author(s):
+//
+//      Atif Aziz, http://www.raboof.com
+//
+// This library is free software; you can redistribute it and/or modify it 
+// under the terms of the New BSD License, a copy of which should have 
+// been delivered along with this distribution.
+//
+// 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.
+//
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using Newtonsoft.Json.Serialization;
+
+namespace Newtonsoft.Json.Utilities.LinqBridge
+{
+  /// <summary>
+  /// Provides a set of static (Shared in Visual Basic) methods for 
+  /// querying objects that implement <see cref="IEnumerable{T}" />.
+  /// </summary>
+  internal static partial class Enumerable
+  {
+    /// <summary>
+    /// Returns the input typed as <see cref="IEnumerable{T}"/>.
+    /// </summary>
+
+    public static IEnumerable<TSource> AsEnumerable<TSource>(IEnumerable<TSource> source)
+    {
+      return source;
+    }
+
+    /// <summary>
+    /// Returns an empty <see cref="IEnumerable{T}"/> that has the 
+    /// specified type argument.
+    /// </summary>
+
+    public static IEnumerable<TResult> Empty<TResult>()
+    {
+      return Sequence<TResult>.Empty;
+    }
+
+    /// <summary>
+    /// Converts the elements of an <see cref="IEnumerable"/> to the 
+    /// specified type.
+    /// </summary>
+
+    public static IEnumerable<TResult> Cast<TResult>(
+      this IEnumerable source)
+    {
+      CheckNotNull(source, "source");
+
+      return CastYield<TResult>(source);
+    }
+
+    private static IEnumerable<TResult> CastYield<TResult>(
+      IEnumerable source)
+    {
+      foreach (var item in source)
+        yield return (TResult) item;
+    }
+
+    /// <summary>
+    /// Filters the elements of an <see cref="IEnumerable"/> based on a specified type.
+    /// </summary>
+
+    public static IEnumerable<TResult> OfType<TResult>(
+      this IEnumerable source)
+    {
+      CheckNotNull(source, "source");
+
+      return OfTypeYield<TResult>(source);
+    }
+
+    private static IEnumerable<TResult> OfTypeYield<TResult>(
+      IEnumerable source)
+    {
+      foreach (var item in source)
+        if (item is TResult)
+          yield return (TResult) item;
+    }
+
+    /// <summary>
+    /// Generates a sequence of integral numbers within a specified range.
+    /// </summary>
+    /// <param name="start">The value of the first integer in the sequence.</param>
+    /// <param name="count">The number of sequential integers to generate.</param>
+
+    public static IEnumerable<int> Range(int start, int count)
+    {
+      if (count < 0)
+        throw new ArgumentOutOfRangeException("count", count, null);
+
+      var end = (long) start + count;
+      if (end - 1 >= int.MaxValue)
+        throw new ArgumentOutOfRangeException("count", count, null);
+
+      return RangeYield(start, end);
+    }
+
+    private static IEnumerable<int> RangeYield(int start, long end)
+    {
+      for (var i = start; i < end; i++)
+        yield return i;
+    }
+
+    /// <summary>
+    /// Generates a sequence that contains one repeated value.
+    /// </summary>
+
+    public static IEnumerable<TResult> Repeat<TResult>(TResult element, int count)
+    {
+      if (count < 0) throw new ArgumentOutOfRangeException("count", count, null);
+
+      return RepeatYield(element, count);
+    }
+
+    private static IEnumerable<TResult> RepeatYield<TResult>(TResult element, int count)
+    {
+      for (var i = 0; i < count; i++)
+        yield return element;
+    }
+
+    /// <summary>
+    /// Filters a sequence of values based on a predicate.
+    /// </summary>
+
+    public static IEnumerable<TSource> Where<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, bool> predicate)
+    {
+      CheckNotNull(predicate, "predicate");
+
+      return source.Where((item, i) => predicate(item));
+    }
+
+    /// <summary>
+    /// Filters a sequence of values based on a predicate. 
+    /// Each element's index is used in the logic of the predicate function.
+    /// </summary>
+
+    public static IEnumerable<TSource> Where<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, int, bool> predicate)
+    {
+      CheckNotNull(source, "source");
+      CheckNotNull(predicate, "predicate");
+
+      return WhereYield(source, predicate);
+    }
+
+    private static IEnumerable<TSource> WhereYield<TSource>(
+      IEnumerable<TSource> source,
+      Func<TSource, int, bool> predicate)
+    {
+      var i = 0;
+      foreach (var item in source)
+        if (predicate(item, i++))
+          yield return item;
+    }
+
+    /// <summary>
+    /// Projects each element of a sequence into a new form.
+    /// </summary>
+
+    public static IEnumerable<TResult> Select<TSource, TResult>(
+      this IEnumerable<TSource> source,
+      Func<TSource, TResult> selector)
+    {
+      CheckNotNull(selector, "selector");
+
+      return source.Select((item, i) => selector(item));
+    }
+
+    /// <summary>
+    /// Projects each element of a sequence into a new form by 
+    /// incorporating the element's index.
+    /// </summary>
+
+    public static IEnumerable<TResult> Select<TSource, TResult>(
+      this IEnumerable<TSource> source,
+      Func<TSource, int, TResult> selector)
+    {
+      CheckNotNull(source, "source");
+      CheckNotNull(selector, "selector");
+
+      return SelectYield(source, selector);
+    }
+
+    private static IEnumerable<TResult> SelectYield<TSource, TResult>(
+      IEnumerable<TSource> source,
+      Func<TSource, int, TResult> selector)
+    {
+      var i = 0;
+      foreach (var item in source)
+        yield return selector(item, i++);
+    }
+
+    /// <summary>
+    /// Projects each element of a sequence to an <see cref="IEnumerable{T}" /> 
+    /// and flattens the resulting sequences into one sequence.
+    /// </summary>
+
+    public static IEnumerable<TResult> SelectMany<TSource, TResult>(
+      this IEnumerable<TSource> source,
+      Func<TSource, IEnumerable<TResult>> selector)
+    {
+      CheckNotNull(selector, "selector");
+
+      return source.SelectMany((item, i) => selector(item));
+    }
+
+    /// <summary>
+    /// Projects each element of a sequence to an <see cref="IEnumerable{T}" />, 
+    /// and flattens the resulting sequences into one sequence. The 
+    /// index of each source element is used in the projected form of 
+    /// that element.
+    /// </summary>
+
+    public static IEnumerable<TResult> SelectMany<TSource, TResult>(
+      this IEnumerable<TSource> source,
+      Func<TSource, int, IEnumerable<TResult>> selector)
+    {
+      CheckNotNull(selector, "selector");
+
+      return source.SelectMany(selector, (item, subitem) => subitem);
+    }
+
+    /// <summary>
+    /// Projects each element of a sequence to an <see cref="IEnumerable{T}" />, 
+    /// flattens the resulting sequences into one sequence, and invokes 
+    /// a result selector function on each element therein.
+    /// </summary>
+
+    public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(
+      this IEnumerable<TSource> source,
+      Func<TSource, IEnumerable<TCollection>> collectionSelector,
+      Func<TSource, TCollection, TResult> resultSelector)
+    {
+      CheckNotNull(collectionSelector, "collectionSelector");
+
+      return source.SelectMany((item, i) => collectionSelector(item), resultSelector);
+    }
+
+    /// <summary>
+    /// Projects each element of a sequence to an <see cref="IEnumerable{T}" />, 
+    /// flattens the resulting sequences into one sequence, and invokes 
+    /// a result selector function on each element therein. The index of 
+    /// each source element is used in the intermediate projected form 
+    /// of that element.
+    /// </summary>
+
+    public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(
+      this IEnumerable<TSource> source,
+      Func<TSource, int, IEnumerable<TCollection>> collectionSelector,
+      Func<TSource, TCollection, TResult> resultSelector)
+    {
+      CheckNotNull(source, "source");
+      CheckNotNull(collectionSelector, "collectionSelector");
+      CheckNotNull(resultSelector, "resultSelector");
+
+      return SelectManyYield(source, collectionSelector, resultSelector);
+    }
+
+    private static IEnumerable<TResult> SelectManyYield<TSource, TCollection, TResult>(
+      this IEnumerable<TSource> source,
+      Func<TSource, int, IEnumerable<TCollection>> collectionSelector,
+      Func<TSource, TCollection, TResult> resultSelector)
+    {
+      var i = 0;
+      foreach (var item in source)
+        foreach (var subitem in collectionSelector(item, i++))
+          yield return resultSelector(item, subitem);
+    }
+
+    /// <summary>
+    /// Returns elements from a sequence as long as a specified condition is true.
+    /// </summary>
+
+    public static IEnumerable<TSource> TakeWhile<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, bool> predicate)
+    {
+      CheckNotNull(predicate, "predicate");
+
+      return source.TakeWhile((item, i) => predicate(item));
+    }
+
+    /// <summary>
+    /// Returns elements from a sequence as long as a specified condition is true.
+    /// The element's index is used in the logic of the predicate function.
+    /// </summary>
+
+    public static IEnumerable<TSource> TakeWhile<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, int, bool> predicate)
+    {
+      CheckNotNull(source, "source");
+      CheckNotNull(predicate, "predicate");
+
+      return TakeWhileYield(source, predicate);
+    }
+
+    private static IEnumerable<TSource> TakeWhileYield<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, int, bool> predicate)
+    {
+      var i = 0;
+      foreach (var item in source)
+        if (predicate(item, i++))
+          yield return item;
+        else
+          break;
+    }
+
+    private static class Futures<T>
+    {
+      public static readonly Func<T> Default = () => default(T);
+      public static readonly Func<T> Undefined = () => { throw new InvalidOperationException(); };
+    }
+
+    /// <summary>
+    /// Base implementation of First operator.
+    /// </summary>
+
+    private static TSource FirstImpl<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource> empty)
+    {
+      CheckNotNull(source, "source");
+      Debug.Assert(empty != null);
+
+      var list = source as IList<TSource>; // optimized case for lists
+      if (list != null)
+        return list.Count > 0 ? list[0] : empty();
+
+      using (var e = source.GetEnumerator()) // fallback for enumeration
+        return e.MoveNext() ? e.Current : empty();
+    }
+
+    /// <summary>
+    /// Returns the first element of a sequence.
+    /// </summary>
+
+    public static TSource First<TSource>(
+      this IEnumerable<TSource> source)
+    {
+      return source.FirstImpl(Futures<TSource>.Undefined);
+    }
+
+    /// <summary>
+    /// Returns the first element in a sequence that satisfies a specified condition.
+    /// </summary>
+
+    public static TSource First<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, bool> predicate)
+    {
+      return First(source.Where(predicate));
+    }
+
+    /// <summary>
+    /// Returns the first element of a sequence, or a default value if 
+    /// the sequence contains no elements.
+    /// </summary>
+
+    public static TSource FirstOrDefault<TSource>(
+      this IEnumerable<TSource> source)
+    {
+      return source.FirstImpl(Futures<TSource>.Default);
+    }
+
+    /// <summary>
+    /// Returns the first element of the sequence that satisfies a 
+    /// condition or a default value if no such element is found.
+    /// </summary>
+
+    public static TSource FirstOrDefault<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, bool> predicate)
+    {
+      return FirstOrDefault(source.Where(predicate));
+    }
+
+    /// <summary>
+    /// Base implementation of Last operator.
+    /// </summary>
+
+    private static TSource LastImpl<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource> empty)
+    {
+      CheckNotNull(source, "source");
+
+      var list = source as IList<TSource>; // optimized case for lists
+      if (list != null)
+        return list.Count > 0 ? list[list.Count - 1] : empty();
+
+      using (var e = source.GetEnumerator())
+      {
+        if (!e.MoveNext())
+          return empty();
+
+        var last = e.Current;
+        while (e.MoveNext())
+          last = e.Current;
+
+        return last;
+      }
+    }
+
+    /// <summary>
+    /// Returns the last element of a sequence.
+    /// </summary>
+    public static TSource Last<TSource>(
+      this IEnumerable<TSource> source)
+    {
+      return source.LastImpl(Futures<TSource>.Undefined);
+    }
+
+    /// <summary>
+    /// Returns the last element of a sequence that satisfies a 
+    /// specified condition.
+    /// </summary>
+
+    public static TSource Last<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, bool> predicate)
+    {
+      return Last(source.Where(predicate));
+    }
+
+    /// <summary>
+    /// Returns the last element of a sequence, or a default value if 
+    /// the sequence contains no elements.
+    /// </summary>
+
+    public static TSource LastOrDefault<TSource>(
+      this IEnumerable<TSource> source)
+    {
+      return source.LastImpl(Futures<TSource>.Default);
+    }
+
+    /// <summary>
+    /// Returns the last element of a sequence that satisfies a 
+    /// condition or a default value if no such element is found.
+    /// </summary>
+
+    public static TSource LastOrDefault<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, bool> predicate)
+    {
+      return LastOrDefault(source.Where(predicate));
+    }
+
+    /// <summary>
+    /// Base implementation of Single operator.
+    /// </summary>
+
+    private static TSource SingleImpl<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource> empty)
+    {
+      CheckNotNull(source, "source");
+
+      using (var e = source.GetEnumerator())
+      {
+        if (e.MoveNext())
+        {
+          var single = e.Current;
+          if (!e.MoveNext())
+            return single;
+
+          throw new InvalidOperationException();
+        }
+
+        return empty();
+      }
+    }
+
+    /// <summary>
+    /// Returns the only element of a sequence, and throws an exception 
+    /// if there is not exactly one element in the sequence.
+    /// </summary>
+
+    public static TSource Single<TSource>(
+      this IEnumerable<TSource> source)
+    {
+      return source.SingleImpl(Futures<TSource>.Undefined);
+    }
+
+    /// <summary>
+    /// Returns the only element of a sequence that satisfies a 
+    /// specified condition, and throws an exception if more than one 
+    /// such element exists.
+    /// </summary>
+
+    public static TSource Single<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, bool> predicate)
+    {
+      return Single(source.Where(predicate));
+    }
+
+    /// <summary>
+    /// Returns the only element of a sequence, or a default value if 
+    /// the sequence is empty; this method throws an exception if there 
+    /// is more than one element in the sequence.
+    /// </summary>
+
+    public static TSource SingleOrDefault<TSource>(
+      this IEnumerable<TSource> source)
+    {
+      return source.SingleImpl(Futures<TSource>.Default);
+    }
+
+    /// <summary>
+    /// Returns the only element of a sequence that satisfies a 
+    /// specified condition or a default value if no such element 
+    /// exists; this method throws an exception if more than one element 
+    /// satisfies the condition.
+    /// </summary>
+
+    public static TSource SingleOrDefault<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, bool> predicate)
+    {
+      return SingleOrDefault(source.Where(predicate));
+    }
+
+    /// <summary>
+    /// Returns the element at a specified index in a sequence.
+    /// </summary>
+
+    public static TSource ElementAt<TSource>(
+      this IEnumerable<TSource> source,
+      int index)
+    {
+      CheckNotNull(source, "source");
+
+      if (index < 0)
+        throw new ArgumentOutOfRangeException("index", index, null);
+
+      var list = source as IList<TSource>;
+      if (list != null)
+        return list[index];
+
+      try
+      {
+        return source.SkipWhile((item, i) => i < index).First();
+      }
+      catch (InvalidOperationException) // if thrown by First
+      {
+        throw new ArgumentOutOfRangeException("index", index, null);
+      }
+    }
+
+    /// <summary>
+    /// Returns the element at a specified index in a sequence or a 
+    /// default value if the index is out of range.
+    /// </summary>
+
+    public static TSource ElementAtOrDefault<TSource>(
+      this IEnumerable<TSource> source,
+      int index)
+    {
+      CheckNotNull(source, "source");
+
+      if (index < 0)
+        return default(TSource);
+
+      var list = source as IList<TSource>;
+      if (list != null)
+        return index < list.Count ? list[index] : default(TSource);
+
+      return source.SkipWhile((item, i) => i < index).FirstOrDefault();
+    }
+
+    /// <summary>
+    /// Inverts the order of the elements in a sequence.
+    /// </summary>
+
+    public static IEnumerable<TSource> Reverse<TSource>(
+      this IEnumerable<TSource> source)
+    {
+      CheckNotNull(source, "source");
+
+      return ReverseYield(source);
+    }
+
+    private static IEnumerable<TSource> ReverseYield<TSource>(IEnumerable<TSource> source)
+    {
+      var stack = new Stack<TSource>();
+      foreach (var item in source)
+        stack.Push(item);
+
+      foreach (var item in stack)
+        yield return item;
+    }
+
+    /// <summary>
+    /// Returns a specified number of contiguous elements from the start 
+    /// of a sequence.
+    /// </summary>
+
+    public static IEnumerable<TSource> Take<TSource>(
+      this IEnumerable<TSource> source,
+      int count)
+    {
+      return source.Where((item, i) => i < count);
+    }
+
+    /// <summary>
+    /// Bypasses a specified number of elements in a sequence and then 
+    /// returns the remaining elements.
+    /// </summary>
+
+    public static IEnumerable<TSource> Skip<TSource>(
+      this IEnumerable<TSource> source,
+      int count)
+    {
+      return source.Where((item, i) => i >= count);
+    }
+
+    /// <summary>
+    /// Bypasses elements in a sequence as long as a specified condition 
+    /// is true and then returns the remaining elements.
+    /// </summary>
+
+    public static IEnumerable<TSource> SkipWhile<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, bool> predicate)
+    {
+      CheckNotNull(predicate, "predicate");
+
+      return source.SkipWhile((item, i) => predicate(item));
+    }
+
+    /// <summary>
+    /// Bypasses elements in a sequence as long as a specified condition 
+    /// is true and then returns the remaining elements. The element's 
+    /// index is used in the logic of the predicate function.
+    /// </summary>
+
+    public static IEnumerable<TSource> SkipWhile<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, int, bool> predicate)
+    {
+      CheckNotNull(source, "source");
+      CheckNotNull(predicate, "predicate");
+
+      return SkipWhileYield(source, predicate);
+    }
+
+    private static IEnumerable<TSource> SkipWhileYield<TSource>(
+      IEnumerable<TSource> source,
+      Func<TSource, int, bool> predicate)
+    {
+      using (var e = source.GetEnumerator())
+      {
+        for (var i = 0;; i++)
+        {
+          if (!e.MoveNext())
+            yield break;
+
+          if (!predicate(e.Current, i))
+            break;
+        }
+
+        do
+        {
+          yield return e.Current;
+        } while (e.MoveNext());
+      }
+    }
+
+    /// <summary>
+    /// Returns the number of elements in a sequence.
+    /// </summary>
+
+    public static int Count<TSource>(
+      this IEnumerable<TSource> source)
+    {
+      CheckNotNull(source, "source");
+
+      var collection = source as ICollection;
+      return collection != null
+               ? collection.Count
+               : source.Aggregate(0, (count, item) => checked(count + 1));
+    }
+
+    /// <summary>
+    /// Returns a number that represents how many elements in the 
+    /// specified sequence satisfy a condition.
+    /// </summary>
+
+    public static int Count<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, bool> predicate)
+    {
+      return Count(source.Where(predicate));
+    }
+
+    /// <summary>
+    /// Returns an <see cref="Int64"/> that represents the total number 
+    /// of elements in a sequence.
+    /// </summary>
+
+    public static long LongCount<TSource>(
+      this IEnumerable<TSource> source)
+    {
+      CheckNotNull(source, "source");
+
+      var array = source as Array;
+      return array != null
+               ? array.LongLength
+               : source.Aggregate(0L, (count, item) => count + 1);
+    }
+
+    /// <summary>
+    /// Returns an <see cref="Int64"/> that represents how many elements 
+    /// in a sequence satisfy a condition.
+    /// </summary>
+
+    public static long LongCount<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, bool> predicate)
+    {
+      return LongCount(source.Where(predicate));
+    }
+
+    /// <summary>
+    /// Concatenates two sequences.
+    /// </summary>
+
+    public static IEnumerable<TSource> Concat<TSource>(
+      this IEnumerable<TSource> first,
+      IEnumerable<TSource> second)
+    {
+      CheckNotNull(first, "first");
+      CheckNotNull(second, "second");
+
+      return ConcatYield(first, second);
+    }
+
+    private static IEnumerable<TSource> ConcatYield<TSource>(
+      IEnumerable<TSource> first,
+      IEnumerable<TSource> second)
+    {
+      foreach (var item in first)
+        yield return item;
+
+      foreach (var item in second)
+        yield return item;
+    }
+
+    /// <summary>
+    /// Creates a <see cref="List{T}"/> from an <see cref="IEnumerable{T}"/>.
+    /// </summary>
+
+    public static List<TSource> ToList<TSource>(
+      this IEnumerable<TSource> source)
+    {
+      CheckNotNull(source, "source");
+
+      return new List<TSource>(source);
+    }
+
+    /// <summary>
+    /// Creates an array from an <see cref="IEnumerable{T}"/>.
+    /// </summary>
+
+    public static TSource[] ToArray<TSource>(
+      this IEnumerable<TSource> source)
+    {
+      return source.ToList().ToArray();
+    }
+
+    /// <summary>
+    /// Returns distinct elements from a sequence by using the default 
+    /// equality comparer to compare values.
+    /// </summary>
+
+    public static IEnumerable<TSource> Distinct<TSource>(
+      this IEnumerable<TSource> source)
+    {
+      return Distinct(source, /* comparer */ null);
+    }
+
+    /// <summary>
+    /// Returns distinct elements from a sequence by using a specified 
+    /// <see cref="IEqualityComparer{T}"/> to compare values.
+    /// </summary>
+
+    public static IEnumerable<TSource> Distinct<TSource>(
+      this IEnumerable<TSource> source,
+      IEqualityComparer<TSource> comparer)
+    {
+      CheckNotNull(source, "source");
+
+      return DistinctYield(source, comparer);
+    }
+
+    private static IEnumerable<TSource> DistinctYield<TSource>(
+      IEnumerable<TSource> source,
+      IEqualityComparer<TSource> comparer)
+    {
+      var set = new Dictionary<TSource, object>(comparer);
+      var gotNull = false;
+
+      foreach (var item in source)
+      {
+        if (item == null)
+        {
+          if (gotNull)
+            continue;
+          gotNull = true;
+        }
+        else
+        {
+          if (set.ContainsKey(item))
+            continue;
+          set.Add(item, null);
+        }
+
+        yield return item;
+      }
+    }
+
+    /// <summary>
+    /// Creates a <see cref="Lookup{TKey,TElement}" /> from an 
+    /// <see cref="IEnumerable{T}" /> according to a specified key 
+    /// selector function.
+    /// </summary>
+
+    public static ILookup<TKey, TSource> ToLookup<TSource, TKey>(
+      this IEnumerable<TSource> source,
+      Func<TSource, TKey> keySelector)
+    {
+      return ToLookup(source, keySelector, e => e, /* comparer */ null);
+    }
+
+    /// <summary>
+    /// Creates a <see cref="Lookup{TKey,TElement}" /> from an 
+    /// <see cref="IEnumerable{T}" /> according to a specified key 
+    /// selector function and a key comparer.
+    /// </summary>
+
+    public static ILookup<TKey, TSource> ToLookup<TSource, TKey>(
+      this IEnumerable<TSource> source,
+      Func<TSource, TKey> keySelector,
+      IEqualityComparer<TKey> comparer)
+    {
+      return ToLookup(source, keySelector, e => e, comparer);
+    }
+
+    /// <summary>
+    /// Creates a <see cref="Lookup{TKey,TElement}" /> from an 
+    /// <see cref="IEnumerable{T}" /> according to specified key 
+    /// and element selector functions.
+    /// </summary>
+
+    public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement>(
+      this IEnumerable<TSource> source,
+      Func<TSource, TKey> keySelector,
+      Func<TSource, TElement> elementSelector)
+    {
+      return ToLookup(source, keySelector, elementSelector, /* comparer */ null);
+    }
+
+    /// <summary>
+    /// Creates a <see cref="Lookup{TKey,TElement}" /> from an 
+    /// <see cref="IEnumerable{T}" /> according to a specified key 
+    /// selector function, a comparer and an element selector function.
+    /// </summary>
+
+    public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement>(
+      this IEnumerable<TSource> source,
+      Func<TSource, TKey> keySelector,
+      Func<TSource, TElement> elementSelector,
+      IEqualityComparer<TKey> comparer)
+    {
+      CheckNotNull(source, "source");
+      CheckNotNull(keySelector, "keySelector");
+      CheckNotNull(elementSelector, "elementSelector");
+
+      var lookup = new Lookup<TKey, TElement>(comparer);
+
+      foreach (var item in source)
+      {
+        var key = keySelector(item);
+
+        var grouping = (Grouping<TKey, TElement>) lookup.Find(key);
+        if (grouping == null)
+        {
+          grouping = new Grouping<TKey, TElement>(key);
+          lookup.Add(grouping);
+        }
+
+        grouping.Add(elementSelector(item));
+      }
+
+      return lookup;
+    }
+
+    /// <summary>
+    /// Groups the elements of a sequence according to a specified key 
+    /// selector function.
+    /// </summary>
+
+    public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(
+      this IEnumerable<TSource> source,
+      Func<TSource, TKey> keySelector)
+    {
+      return GroupBy(source, keySelector, /* comparer */ null);
+    }
+
+    /// <summary>
+    /// Groups the elements of a sequence according to a specified key 
+    /// selector function and compares the keys by using a specified 
+    /// comparer.
+    /// </summary>
+
+    public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(
+      this IEnumerable<TSource> source,
+      Func<TSource, TKey> keySelector,
+      IEqualityComparer<TKey> comparer)
+    {
+      return GroupBy(source, keySelector, e => e, comparer);
+    }
+
+    /// <summary>
+    /// Groups the elements of a sequence according to a specified key 
+    /// selector function and projects the elements for each group by 
+    /// using a specified function.
+    /// </summary>
+
+    public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement>(
+      this IEnumerable<TSource> source,
+      Func<TSource, TKey> keySelector,
+      Func<TSource, TElement> elementSelector)
+    {
+      return GroupBy(source, keySelector, elementSelector, /* comparer */ null);
+    }
+
+    /// <summary>
+    /// Groups the elements of a sequence according to a specified key 
+    /// selector function and creates a result value from each group and 
+    /// its key.
+    /// </summary>
+
+    public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement>(
+      this IEnumerable<TSource> source,
+      Func<TSource, TKey> keySelector,
+      Func<TSource, TElement> elementSelector,
+      IEqualityComparer<TKey> comparer)
+    {
+      CheckNotNull(source, "source");
+      CheckNotNull(keySelector, "keySelector");
+      CheckNotNull(elementSelector, "elementSelector");
+
+      return ToLookup(source, keySelector, elementSelector, comparer);
+    }
+
+    /// <summary>
+    /// Groups the elements of a sequence according to a key selector 
+    /// function. The keys are compared by using a comparer and each 
+    /// group's elements are projected by using a specified function.
+    /// </summary>
+
+    public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult>(
+      this IEnumerable<TSource> source,
+      Func<TSource, TKey> keySelector,
+      Func<TKey, IEnumerable<TSource>, TResult> resultSelector)
+    {
+      return GroupBy(source, keySelector, resultSelector, /* comparer */ null);
+    }
+
+    /// <summary>
+    /// Groups the elements of a sequence according to a specified key 
+    /// selector function and creates a result value from each group and 
+    /// its key. The elements of each group are projected by using a 
+    /// specified function.
+    /// </summary>
+
+    public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult>(
+      this IEnumerable<TSource> source,
+      Func<TSource, TKey> keySelector,
+      Func<TKey, IEnumerable<TSource>, TResult> resultSelector,
+      IEqualityComparer<TKey> comparer)
+    {
+      CheckNotNull(source, "source");
+      CheckNotNull(keySelector, "keySelector");
+      CheckNotNull(resultSelector, "resultSelector");
+
+      return ToLookup(source, keySelector, comparer).Select(g => resultSelector(g.Key, g));
+    }
+
+    /// <summary>
+    /// Groups the elements of a sequence according to a specified key 
+    /// selector function and creates a result value from each group and 
+    /// its key. The keys are compared by using a specified comparer.
+    /// </summary>
+
+    public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult>(
+      this IEnumerable<TSource> source,
+      Func<TSource, TKey> keySelector,
+      Func<TSource, TElement> elementSelector,
+      Func<TKey, IEnumerable<TElement>, TResult> resultSelector)
+    {
+      return GroupBy(source, keySelector, elementSelector, resultSelector, /* comparer */ null);
+    }
+
+    /// <summary>
+    /// Groups the elements of a sequence according to a specified key 
+    /// selector function and creates a result value from each group and 
+    /// its key. Key values are compared by using a specified comparer, 
+    /// and the elements of each group are projected by using a 
+    /// specified function.
+    /// </summary>
+
+    public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult>(
+      this IEnumerable<TSource> source,
+      Func<TSource, TKey> keySelector,
+      Func<TSource, TElement> elementSelector,
+      Func<TKey, IEnumerable<TElement>, TResult> resultSelector,
+      IEqualityComparer<TKey> comparer)
+    {
+      CheckNotNull(source, "source");
+      CheckNotNull(keySelector, "keySelector");
+      CheckNotNull(elementSelector, "elementSelector");
+      CheckNotNull(resultSelector, "resultSelector");
+
+      return ToLookup(source, keySelector, elementSelector, comparer)
+        .Select(g => resultSelector(g.Key, g));
+    }
+
+    /// <summary>
+    /// Applies an accumulator function over a sequence.
+    /// </summary>
+
+    public static TSource Aggregate<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, TSource, TSource> func)
+    {
+      CheckNotNull(source, "source");
+      CheckNotNull(func, "func");
+
+      using (var e = source.GetEnumerator())
+      {
+        if (!e.MoveNext())
+          throw new InvalidOperationException();
+
+        return e.Renumerable().Skip(1).Aggregate(e.Current, func);
+      }
+    }
+
+    /// <summary>
+    /// Applies an accumulator function over a sequence. The specified 
+    /// seed value is used as the initial accumulator value.
+    /// </summary>
+
+    public static TAccumulate Aggregate<TSource, TAccumulate>(
+      this IEnumerable<TSource> source,
+      TAccumulate seed,
+      Func<TAccumulate, TSource, TAccumulate> func)
+    {
+      return Aggregate(source, seed, func, r => r);
+    }
+
+    /// <summary>
+    /// Applies an accumulator function over a sequence. The specified 
+    /// seed value is used as the initial accumulator value, and the 
+    /// specified function is used to select the result value.
+    /// </summary>
+
+    public static TResult Aggregate<TSource, TAccumulate, TResult>(
+      this IEnumerable<TSource> source,
+      TAccumulate seed,
+      Func<TAccumulate, TSource, TAccumulate> func,
+      Func<TAccumulate, TResult> resultSelector)
+    {
+      CheckNotNull(source, "source");
+      CheckNotNull(func, "func");
+      CheckNotNull(resultSelector, "resultSelector");
+
+      var result = seed;
+
+      foreach (var item in source)
+        result = func(result, item);
+
+      return resultSelector(result);
+    }
+
+    /// <summary>
+    /// Produces the set union of two sequences by using the default 
+    /// equality comparer.
+    /// </summary>
+
+    public static IEnumerable<TSource> Union<TSource>(
+      this IEnumerable<TSource> first,
+      IEnumerable<TSource> second)
+    {
+      return Union(first, second, /* comparer */ null);
+    }
+
+    /// <summary>
+    /// Produces the set union of two sequences by using a specified 
+    /// <see cref="IEqualityComparer{T}" />.
+    /// </summary>
+
+    public static IEnumerable<TSource> Union<TSource>(
+      this IEnumerable<TSource> first,
+      IEnumerable<TSource> second,
+      IEqualityComparer<TSource> comparer)
+    {
+      return first.Concat(second).Distinct(comparer);
+    }
+
+    /// <summary>
+    /// Returns the elements of the specified sequence or the type 
+    /// parameter's default value in a singleton collection if the 
+    /// sequence is empty.
+    /// </summary>
+
+    public static IEnumerable<TSource> DefaultIfEmpty<TSource>(
+      this IEnumerable<TSource> source)
+    {
+      return source.DefaultIfEmpty(default(TSource));
+    }
+
+    /// <summary>
+    /// Returns the elements of the specified sequence or the specified 
+    /// value in a singleton collection if the sequence is empty.
+    /// </summary>
+
+    public static IEnumerable<TSource> DefaultIfEmpty<TSource>(
+      this IEnumerable<TSource> source,
+      TSource defaultValue)
+    {
+      CheckNotNull(source, "source");
+
+      return DefaultIfEmptyYield(source, defaultValue);
+    }
+
+    private static IEnumerable<TSource> DefaultIfEmptyYield<TSource>(
+      IEnumerable<TSource> source,
+      TSource defaultValue)
+    {
+      using (var e = source.GetEnumerator())
+      {
+        if (!e.MoveNext())
+          yield return defaultValue;
+        else
+          do
+          {
+            yield return e.Current;
+          } while (e.MoveNext());
+      }
+    }
+
+    /// <summary>
+    /// Determines whether all elements of a sequence satisfy a condition.
+    /// </summary>
+
+    public static bool All<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, bool> predicate)
+    {
+      CheckNotNull(source, "source");
+      CheckNotNull(predicate, "predicate");
+
+      foreach (var item in source)
+        if (!predicate(item))
+          return false;
+
+      return true;
+    }
+
+    /// <summary>
+    /// Determines whether a sequence contains any elements.
+    /// </summary>
+
+    public static bool Any<TSource>(
+      this IEnumerable<TSource> source)
+    {
+      CheckNotNull(source, "source");
+
+      using (var e = source.GetEnumerator())
+        return e.MoveNext();
+    }
+
+    /// <summary>
+    /// Determines whether any element of a sequence satisfies a 
+    /// condition.
+    /// </summary>
+
+    public static bool Any<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, bool> predicate)
+    {
+      return source.Where(predicate).Any();
+    }
+
+    /// <summary>
+    /// Determines whether a sequence contains a specified element by 
+    /// using the default equality comparer.
+    /// </summary>
+
+    public static bool Contains<TSource>(
+      this IEnumerable<TSource> source,
+      TSource value)
+    {
+      return source.Contains(value, /* comparer */ null);
+    }
+
+    /// <summary>
+    /// Determines whether a sequence contains a specified element by 
+    /// using a specified <see cref="IEqualityComparer{T}" />.
+    /// </summary>
+
+    public static bool Contains<TSource>(
+      this IEnumerable<TSource> source,
+      TSource value,
+      IEqualityComparer<TSource> comparer)
+    {
+      CheckNotNull(source, "source");
+
+      if (comparer == null)
+      {
+        var collection = source as ICollection<TSource>;
+        if (collection != null)
+          return collection.Contains(value);
+      }
+
+      comparer = comparer ?? EqualityComparer<TSource>.Default;
+      return source.Any(item => comparer.Equals(item, value));
+    }
+
+    /// <summary>
+    /// Determines whether two sequences are equal by comparing the 
+    /// elements by using the default equality comparer for their type.
+    /// </summary>
+
+    public static bool SequenceEqual<TSource>(
+      this IEnumerable<TSource> first,
+      IEnumerable<TSource> second)
+    {
+      return first.SequenceEqual(second, /* comparer */ null);
+    }
+
+    /// <summary>
+    /// Determines whether two sequences are equal by comparing their 
+    /// elements by using a specified <see cref="IEqualityComparer{T}" />.
+    /// </summary>
+
+    public static bool SequenceEqual<TSource>(
+      this IEnumerable<TSource> first,
+      IEnumerable<TSource> second,
+      IEqualityComparer<TSource> comparer)
+    {
+      CheckNotNull(first, "frist");
+      CheckNotNull(second, "second");
+
+      comparer = comparer ?? EqualityComparer<TSource>.Default;
+
+      using (IEnumerator<TSource> lhs = first.GetEnumerator(),
+                                  rhs = second.GetEnumerator())
+      {
+        do
+        {
+          if (!lhs.MoveNext())
+            return !rhs.MoveNext();
+
+          if (!rhs.MoveNext())
+            return false;
+        } while (comparer.Equals(lhs.Current, rhs.Current));
+      }
+
+      return false;
+    }
+
+    /// <summary>
+    /// Base implementation for Min/Max operator.
+    /// </summary>
+
+    private static TSource MinMaxImpl<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, TSource, bool> lesser)
+    {
+      CheckNotNull(source, "source");
+      Debug.Assert(lesser != null);
+
+      return source.Aggregate((a, item) => lesser(a, item) ? a : item);
+    }
+
+    /// <summary>
+    /// Base implementation for Min/Max operator for nullable types.
+    /// </summary>
+
+    private static TSource? MinMaxImpl<TSource>(
+      this IEnumerable<TSource?> source,
+      TSource? seed, Func<TSource?, TSource?, bool> lesser) where TSource : struct
+    {
+      CheckNotNull(source, "source");
+      Debug.Assert(lesser != null);
+
+      return source.Aggregate(seed, (a, item) => lesser(a, item) ? a : item);
+      //  == MinMaxImpl(Repeat<TSource?>(null, 1).Concat(source), lesser);
+    }
+
+    /// <summary>
+    /// Returns the minimum value in a generic sequence.
+    /// </summary>
+
+    public static TSource Min<TSource>(
+      this IEnumerable<TSource> source)
+    {
+      var comparer = Comparer<TSource>.Default;
+      return source.MinMaxImpl((x, y) => comparer.Compare(x, y) < 0);
+    }
+
+    /// <summary>
+    /// Invokes a transform function on each element of a generic 
+    /// sequence and returns the minimum resulting value.
+    /// </summary>
+
+    public static TResult Min<TSource, TResult>(
+      this IEnumerable<TSource> source,
+      Func<TSource, TResult> selector)
+    {
+      return source.Select(selector).Min();
+    }
+
+    /// <summary>
+    /// Returns the maximum value in a generic sequence.
+    /// </summary>
+
+    public static TSource Max<TSource>(
+      this IEnumerable<TSource> source)
+    {
+      var comparer = Comparer<TSource>.Default;
+      return source.MinMaxImpl((x, y) => comparer.Compare(x, y) > 0);
+    }
+
+    /// <summary>
+    /// Invokes a transform function on each element of a generic 
+    /// sequence and returns the maximum resulting value.
+    /// </summary>
+
+    public static TResult Max<TSource, TResult>(
+      this IEnumerable<TSource> source,
+      Func<TSource, TResult> selector)
+    {
+      return source.Select(selector).Max();
+    }
+
+    /// <summary>
+    /// Makes an enumerator seen as enumerable once more.
+    /// </summary>
+    /// <remarks>
+    /// The supplied enumerator must have been started. The first element
+    /// returned is the element the enumerator was on when passed in.
+    /// DO NOT use this method if the caller must be a generator. It is
+    /// mostly safe among aggregate operations.
+    /// </remarks>
+
+    private static IEnumerable<T> Renumerable<T>(this IEnumerator<T> e)
+    {
+      Debug.Assert(e != null);
+
+      do
+      {
+        yield return e.Current;
+      } while (e.MoveNext());
+    }
+
+    /// <summary>
+    /// Sorts the elements of a sequence in ascending order according to a key.
+    /// </summary>
+
+    public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
+      this IEnumerable<TSource> source,
+      Func<TSource, TKey> keySelector)
+    {
+      return source.OrderBy(keySelector, /* comparer */ null);
+    }
+
+    /// <summary>
+    /// Sorts the elements of a sequence in ascending order by using a 
+    /// specified comparer.
+    /// </summary>
+
+    public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
+      this IEnumerable<TSource> source,
+      Func<TSource, TKey> keySelector,
+      IComparer<TKey> comparer)
+    {
+      CheckNotNull(source, "source");
+      CheckNotNull(keySelector, "keySelector");
+
+      return new OrderedEnumerable<TSource, TKey>(source, keySelector, comparer, /* descending */ false);
+    }
+
+    /// <summary>
+    /// Sorts the elements of a sequence in descending order according to a key.
+    /// </summary>
+
+    public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>(
+      this IEnumerable<TSource> source,
+      Func<TSource, TKey> keySelector)
+    {
+      return source.OrderByDescending(keySelector, /* comparer */ null);
+    }
+
+    /// <summary>
+    ///  Sorts the elements of a sequence in descending order by using a 
+    /// specified comparer. 
+    /// </summary>
+
+    public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>(
+      this IEnumerable<TSource> source,
+      Func<TSource, TKey> keySelector,
+      IComparer<TKey> comparer)
+    {
+      CheckNotNull(source, "source");
+      CheckNotNull(source, "keySelector");
+
+      return new OrderedEnumerable<TSource, TKey>(source, keySelector, comparer, /* descending */ true);
+    }
+
+    /// <summary>
+    /// Performs a subsequent ordering of the elements in a sequence in 
+    /// ascending order according to a key.
+    /// </summary>
+
+    public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey>(
+      this IOrderedEnumerable<TSource> source,
+      Func<TSource, TKey> keySelector)
+    {
+      return source.ThenBy(keySelector, /* comparer */ null);
+    }
+
+    /// <summary>
+    /// Performs a subsequent ordering of the elements in a sequence in 
+    /// ascending order by using a specified comparer.
+    /// </summary>
+
+    public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey>(
+      this IOrderedEnumerable<TSource> source,
+      Func<TSource, TKey> keySelector,
+      IComparer<TKey> comparer)
+    {
+      CheckNotNull(source, "source");
+
+      return source.CreateOrderedEnumerable(keySelector, comparer, /* descending */ false);
+    }
+
+    /// <summary>
+    /// Performs a subsequent ordering of the elements in a sequence in 
+    /// descending order, according to a key.
+    /// </summary>
+
+    public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey>(
+      this IOrderedEnumerable<TSource> source,
+      Func<TSource, TKey> keySelector)
+    {
+      return source.ThenByDescending(keySelector, /* comparer */ null);
+    }
+
+    /// <summary>
+    /// Performs a subsequent ordering of the elements in a sequence in 
+    /// descending order by using a specified comparer.
+    /// </summary>
+
+    public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey>(
+      this IOrderedEnumerable<TSource> source,
+      Func<TSource, TKey> keySelector,
+      IComparer<TKey> comparer)
+    {
+      CheckNotNull(source, "source");
+
+      return source.CreateOrderedEnumerable(keySelector, comparer, /* descending */ true);
+    }
+
+    /// <summary>
+    /// Base implementation for Intersect and Except operators.
+    /// </summary>
+
+    private static IEnumerable<TSource> IntersectExceptImpl<TSource>(
+      this IEnumerable<TSource> first,
+      IEnumerable<TSource> second,
+      IEqualityComparer<TSource> comparer,
+      bool flag)
+    {
+      CheckNotNull(first, "first");
+      CheckNotNull(second, "second");
+
+      var keys = new List<TSource>();
+      var flags = new Dictionary<TSource, bool>(comparer);
+
+      foreach (var item in first.Where(k => !flags.ContainsKey(k)))
+      {
+        flags.Add(item, !flag);
+        keys.Add(item);
+      }
+
+      foreach (var item in second.Where(flags.ContainsKey))
+        flags[item] = flag;
+
+      //
+      // As per docs, "the marked elements are yielded in the order in 
+      // which they were collected.
+      //
+
+      return keys.Where(item => flags[item]);
+    }
+
+    /// <summary>
+    /// Produces the set intersection of two sequences by using the 
+    /// default equality comparer to compare values.
+    /// </summary>
+
+    public static IEnumerable<TSource> Intersect<TSource>(
+      this IEnumerable<TSource> first,
+      IEnumerable<TSource> second)
+    {
+      return first.Intersect(second, /* comparer */ null);
+    }
+
+    /// <summary>
+    /// Produces the set intersection of two sequences by using the 
+    /// specified <see cref="IEqualityComparer{T}" /> to compare values.
+    /// </summary>
+
+    public static IEnumerable<TSource> Intersect<TSource>(
+      this IEnumerable<TSource> first,
+      IEnumerable<TSource> second,
+      IEqualityComparer<TSource> comparer)
+    {
+      return IntersectExceptImpl(first, second, comparer, /* flag */ true);
+    }
+
+    /// <summary>
+    /// Produces the set difference of two sequences by using the 
+    /// default equality comparer to compare values.
+    /// </summary>
+
+    public static IEnumerable<TSource> Except<TSource>(
+      this IEnumerable<TSource> first,
+      IEnumerable<TSource> second)
+    {
+      return first.Except(second, /* comparer */ null);
+    }
+
+    /// <summary>
+    /// Produces the set difference of two sequences by using the 
+    /// specified <see cref="IEqualityComparer{T}" /> to compare values.
+    /// </summary>
+
+    public static IEnumerable<TSource> Except<TSource>(
+      this IEnumerable<TSource> first,
+      IEnumerable<TSource> second,
+      IEqualityComparer<TSource> comparer)
+    {
+      return IntersectExceptImpl(first, second, comparer, /* flag */ false);
+    }
+
+    /// <summary>
+    /// Creates a <see cref="Dictionary{TKey,TValue}" /> from an 
+    /// <see cref="IEnumerable{T}" /> according to a specified key 
+    /// selector function.
+    /// </summary>
+
+    public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(
+      this IEnumerable<TSource> source,
+      Func<TSource, TKey> keySelector)
+    {
+      return source.ToDictionary(keySelector, /* comparer */ null);
+    }
+
+    /// <summary>
+    /// Creates a <see cref="Dictionary{TKey,TValue}" /> from an 
+    /// <see cref="IEnumerable{T}" /> according to a specified key 
+    /// selector function and key comparer.
+    /// </summary>
+
+    public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(
+      this IEnumerable<TSource> source,
+      Func<TSource, TKey> keySelector,
+      IEqualityComparer<TKey> comparer)
+    {
+      return source.ToDictionary(keySelector, e => e);
+    }
+
+    /// <summary>
+    /// Creates a <see cref="Dictionary{TKey,TValue}" /> from an 
+    /// <see cref="IEnumerable{T}" /> according to specified key 
+    /// selector and element selector functions.
+    /// </summary>
+
+    public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(
+      this IEnumerable<TSource> source,
+      Func<TSource, TKey> keySelector,
+      Func<TSource, TElement> elementSelector)
+    {
+      return source.ToDictionary(keySelector, elementSelector, /* comparer */ null);
+    }
+
+    /// <summary>
+    /// Creates a <see cref="Dictionary{TKey,TValue}" /> from an 
+    /// <see cref="IEnumerable{T}" /> according to a specified key 
+    /// selector function, a comparer, and an element selector function.
+    /// </summary>
+
+    public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(
+      this IEnumerable<TSource> source,
+      Func<TSource, TKey> keySelector,
+      Func<TSource, TElement> elementSelector,
+      IEqualityComparer<TKey> comparer)
+    {
+      CheckNotNull(source, "source");
+      CheckNotNull(keySelector, "keySelector");
+      CheckNotNull(elementSelector, "elementSelector");
+
+      var dict = new Dictionary<TKey, TElement>(comparer);
+
+      foreach (var item in source)
+      {
+        //
+        // ToDictionary is meant to throw ArgumentNullException if
+        // keySelector produces a key that is null and 
+        // Argument exception if keySelector produces duplicate keys 
+        // for two elements. Incidentally, the doucmentation for
+        // IDictionary<TKey, TValue>.Add says that the Add method
+        // throws the same exceptions under the same circumstances
+        // so we don't need to do any additional checking or work
+        // here and let the Add implementation do all the heavy
+        // lifting.
+        //
+
+        dict.Add(keySelector(item), elementSelector(item));
+      }
+
+      return dict;
+    }
+
+    /// <summary>
+    /// Correlates the elements of two sequences based on matching keys. 
+    /// The default equality comparer is used to compare keys.
+    /// </summary>
+
+    public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(
+      this IEnumerable<TOuter> outer,
+      IEnumerable<TInner> inner,
+      Func<TOuter, TKey> outerKeySelector,
+      Func<TInner, TKey> innerKeySelector,
+      Func<TOuter, TInner, TResult> resultSelector)
+    {
+      return outer.Join(inner, outerKeySelector, innerKeySelector, resultSelector, /* comparer */ null);
+    }
+
+    /// <summary>
+    /// Correlates the elements of two sequences based on matching keys. 
+    /// The default equality comparer is used to compare keys. A 
+    /// specified <see cref="IEqualityComparer{T}" /> is used to compare keys.
+    /// </summary>
+
+    public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(
+      this IEnumerable<TOuter> outer,
+      IEnumerable<TInner> inner,
+      Func<TOuter, TKey> outerKeySelector,
+      Func<TInner, TKey> innerKeySelector,
+      Func<TOuter, TInner, TResult> resultSelector,
+      IEqualityComparer<TKey> comparer)
+    {
+      CheckNotNull(outer, "outer");
+      CheckNotNull(inner, "inner");
+      CheckNotNull(outerKeySelector, "outerKeySelector");
+      CheckNotNull(innerKeySelector, "innerKeySelector");
+      CheckNotNull(resultSelector, "resultSelector");
+
+      var lookup = inner.ToLookup(innerKeySelector, comparer);
+
+      return
+        from o in outer
+        from i in lookup[outerKeySelector(o)]
+        select resultSelector(o, i);
+    }
+
+    /// <summary>
+    /// Correlates the elements of two sequences based on equality of 
+    /// keys and groups the results. The default equality comparer is 
+    /// used to compare keys.
+    /// </summary>
+
+    public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(
+      this IEnumerable<TOuter> outer,
+      IEnumerable<TInner> inner,
+      Func<TOuter, TKey> outerKeySelector,
+      Func<TInner, TKey> innerKeySelector,
+      Func<TOuter, IEnumerable<TInner>, TResult> resultSelector)
+    {
+      return outer.GroupJoin(inner, outerKeySelector, innerKeySelector, resultSelector, /* comparer */ null);
+    }
+
+    /// <summary>
+    /// Correlates the elements of two sequences based on equality of 
+    /// keys and groups the results. The default equality comparer is 
+    /// used to compare keys. A specified <see cref="IEqualityComparer{T}" /> 
+    /// is used to compare keys.
+    /// </summary>
+
+    public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(
+      this IEnumerable<TOuter> outer,
+      IEnumerable<TInner> inner,
+      Func<TOuter, TKey> outerKeySelector,
+      Func<TInner, TKey> innerKeySelector,
+      Func<TOuter, IEnumerable<TInner>, TResult> resultSelector,
+      IEqualityComparer<TKey> comparer)
+    {
+      CheckNotNull(outer, "outer");
+      CheckNotNull(inner, "inner");
+      CheckNotNull(outerKeySelector, "outerKeySelector");
+      CheckNotNull(innerKeySelector, "innerKeySelector");
+      CheckNotNull(resultSelector, "resultSelector");
+
+      var lookup = inner.ToLookup(innerKeySelector, comparer);
+      return outer.Select(o => resultSelector(o, lookup[outerKeySelector(o)]));
+    }
+
+    [DebuggerStepThrough]
+    private static void CheckNotNull<T>(T value, string name) where T : class
+    {
+      if (value == null)
+        throw new ArgumentNullException(name);
+    }
+
+    private static class Sequence<T>
+    {
+      public static readonly IEnumerable<T> Empty = new T[0];
+    }
+
+    private sealed class Grouping<K, V> : List<V>, IGrouping<K, V>
+    {
+      internal Grouping(K key)
+      {
+        Key = key;
+      }
+
+      public K Key { get; private set; }
+    }
+  }
+
+  internal partial class Enumerable
+  {
+    /// <summary>
+    /// Computes the sum of a sequence of nullable <see cref="System.Int32" /> values.
+    /// </summary>
+
+    public static int Sum(
+      this IEnumerable<int> source)
+    {
+      CheckNotNull(source, "source");
+
+      int sum = 0;
+      foreach (var num in source)
+        sum = checked(sum + num);
+
+      return sum;
+    }
+
+    /// <summary>
+    /// Computes the sum of a sequence of nullable <see cref="System.Int32" /> 
+    /// values that are obtained by invoking a transform function on 
+    /// each element of the input sequence.
+    /// </summary>
+
+    public static int Sum<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, int> selector)
+    {
+      return source.Select(selector).Sum();
+    }
+
+    /// <summary>
+    /// Computes the average of a sequence of nullable <see cref="System.Int32" /> values.
+    /// </summary>
+
+    public static double Average(
+      this IEnumerable<int> source)
+    {
+      CheckNotNull(source, "source");
+
+      long sum = 0;
+      long count = 0;
+
+      foreach (var num in source)
+        checked
+        {
+          sum += (int) num;
+          count++;
+        }
+
+      if (count == 0)
+        throw new InvalidOperationException();
+
+      return (double) sum/count;
+    }
+
+    /// <summary>
+    /// Computes the average of a sequence of nullable <see cref="System.Int32" /> values 
+    /// that are obtained by invoking a transform function on each 
+    /// element of the input sequence.
+    /// </summary>
+
+    public static double Average<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, int> selector)
+    {
+      return source.Select(selector).Average();
+    }
+
+
+    /// <summary>
+    /// Computes the sum of a sequence of <see cref="System.Int32" /> values.
+    /// </summary>
+
+    public static int? Sum(
+      this IEnumerable<int?> source)
+    {
+      CheckNotNull(source, "source");
+
+      int sum = 0;
+      foreach (var num in source)
+        sum = checked(sum + (num ?? 0));
+
+      return sum;
+    }
+
+    /// <summary>
+    /// Computes the sum of a sequence of <see cref="System.Int32" /> 
+    /// values that are obtained by invoking a transform function on 
+    /// each element of the input sequence.
+    /// </summary>
+
+    public static int? Sum<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, int?> selector)
+    {
+      return source.Select(selector).Sum();
+    }
+
+    /// <summary>
+    /// Computes the average of a sequence of <see cref="System.Int32" /> values.
+    /// </summary>
+
+    public static double? Average(
+      this IEnumerable<int?> source)
+    {
+      CheckNotNull(source, "source");
+
+      long sum = 0;
+      long count = 0;
+
+      foreach (var num in source.Where(n => n != null))
+        checked
+        {
+          sum += (int) num;
+          count++;
+        }
+
+      if (count == 0)
+        return null;
+
+      return (double?) sum/count;
+    }
+
+    /// <summary>
+    /// Computes the average of a sequence of <see cref="System.Int32" /> values 
+    /// that are obtained by invoking a transform function on each 
+    /// element of the input sequence.
+    /// </summary>
+
+    public static double? Average<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, int?> selector)
+    {
+      return source.Select(selector).Average();
+    }
+
+    /// <summary>
+    /// Returns the minimum value in a sequence of nullable 
+    /// <see cref="System.Int32" /> values.
+    /// </summary>
+
+    public static int? Min(
+      this IEnumerable<int?> source)
+    {
+      CheckNotNull(source, "source");
+
+      return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x);
+    }
+
+    /// <summary>
+    /// Invokes a transform function on each element of a sequence and 
+    /// returns the minimum nullable <see cref="System.Int32" /> value.
+    /// </summary>
+
+    public static int? Min<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, int?> selector)
+    {
+      return source.Select(selector).Min();
+    }
+
+    /// <summary>
+    /// Returns the maximum value in a sequence of nullable 
+    /// <see cref="System.Int32" /> values.
+    /// </summary>
+
+    public static int? Max(
+      this IEnumerable<int?> source)
+    {
+      CheckNotNull(source, "source");
+
+      return MinMaxImpl(source.Where(x => x != null),
+                        null, (max, x) => x == null || (max != null && x.Value < max.Value));
+    }
+
+    /// <summary>
+    /// Invokes a transform function on each element of a sequence and 
+    /// returns the maximum nullable <see cref="System.Int32" /> value.
+    /// </summary>
+
+    public static int? Max<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, int?> selector)
+    {
+      return source.Select(selector).Max();
+    }
+
+    /// <summary>
+    /// Computes the sum of a sequence of nullable <see cref="System.Int64" /> values.
+    /// </summary>
+
+    public static long Sum(
+      this IEnumerable<long> source)
+    {
+      CheckNotNull(source, "source");
+
+      long sum = 0;
+      foreach (var num in source)
+        sum = checked(sum + num);
+
+      return sum;
+    }
+
+    /// <summary>
+    /// Computes the sum of a sequence of nullable <see cref="System.Int64" /> 
+    /// values that are obtained by invoking a transform function on 
+    /// each element of the input sequence.
+    /// </summary>
+
+    public static long Sum<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, long> selector)
+    {
+      return source.Select(selector).Sum();
+    }
+
+    /// <summary>
+    /// Computes the average of a sequence of nullable <see cref="System.Int64" /> values.
+    /// </summary>
+
+    public static double Average(
+      this IEnumerable<long> source)
+    {
+      CheckNotNull(source, "source");
+
+      long sum = 0;
+      long count = 0;
+
+      foreach (var num in source)
+        checked
+        {
+          sum += (long) num;
+          count++;
+        }
+
+      if (count == 0)
+        throw new InvalidOperationException();
+
+      return (double) sum/count;
+    }
+
+    /// <summary>
+    /// Computes the average of a sequence of nullable <see cref="System.Int64" /> values 
+    /// that are obtained by invoking a transform function on each 
+    /// element of the input sequence.
+    /// </summary>
+
+    public static double Average<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, long> selector)
+    {
+      return source.Select(selector).Average();
+    }
+
+
+    /// <summary>
+    /// Computes the sum of a sequence of <see cref="System.Int64" /> values.
+    /// </summary>
+
+    public static long? Sum(
+      this IEnumerable<long?> source)
+    {
+      CheckNotNull(source, "source");
+
+      long sum = 0;
+      foreach (var num in source)
+        sum = checked(sum + (num ?? 0));
+
+      return sum;
+    }
+
+    /// <summary>
+    /// Computes the sum of a sequence of <see cref="System.Int64" /> 
+    /// values that are obtained by invoking a transform function on 
+    /// each element of the input sequence.
+    /// </summary>
+
+    public static long? Sum<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, long?> selector)
+    {
+      return source.Select(selector).Sum();
+    }
+
+    /// <summary>
+    /// Computes the average of a sequence of <see cref="System.Int64" /> values.
+    /// </summary>
+
+    public static double? Average(
+      this IEnumerable<long?> source)
+    {
+      CheckNotNull(source, "source");
+
+      long sum = 0;
+      long count = 0;
+
+      foreach (var num in source.Where(n => n != null))
+        checked
+        {
+          sum += (long) num;
+          count++;
+        }
+
+      if (count == 0)
+        return null;
+
+      return (double?) sum/count;
+    }
+
+    /// <summary>
+    /// Computes the average of a sequence of <see cref="System.Int64" /> values 
+    /// that are obtained by invoking a transform function on each 
+    /// element of the input sequence.
+    /// </summary>
+
+    public static double? Average<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, long?> selector)
+    {
+      return source.Select(selector).Average();
+    }
+
+    /// <summary>
+    /// Returns the minimum value in a sequence of nullable 
+    /// <see cref="System.Int64" /> values.
+    /// </summary>
+
+    public static long? Min(
+      this IEnumerable<long?> source)
+    {
+      CheckNotNull(source, "source");
+
+      return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x);
+    }
+
+    /// <summary>
+    /// Invokes a transform function on each element of a sequence and 
+    /// returns the minimum nullable <see cref="System.Int64" /> value.
+    /// </summary>
+
+    public static long? Min<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, long?> selector)
+    {
+      return source.Select(selector).Min();
+    }
+
+    /// <summary>
+    /// Returns the maximum value in a sequence of nullable 
+    /// <see cref="System.Int64" /> values.
+    /// </summary>
+
+    public static long? Max(
+      this IEnumerable<long?> source)
+    {
+      CheckNotNull(source, "source");
+
+      return MinMaxImpl(source.Where(x => x != null),
+                        null, (max, x) => x == null || (max != null && x.Value < max.Value));
+    }
+
+    /// <summary>
+    /// Invokes a transform function on each element of a sequence and 
+    /// returns the maximum nullable <see cref="System.Int64" /> value.
+    /// </summary>
+
+    public static long? Max<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, long?> selector)
+    {
+      return source.Select(selector).Max();
+    }
+
+    /// <summary>
+    /// Computes the sum of a sequence of nullable <see cref="System.Single" /> values.
+    /// </summary>
+
+    public static float Sum(
+      this IEnumerable<float> source)
+    {
+      CheckNotNull(source, "source");
+
+      float sum = 0;
+      foreach (var num in source)
+        sum = checked(sum + num);
+
+      return sum;
+    }
+
+    /// <summary>
+    /// Computes the sum of a sequence of nullable <see cref="System.Single" /> 
+    /// values that are obtained by invoking a transform function on 
+    /// each element of the input sequence.
+    /// </summary>
+
+    public static float Sum<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, float> selector)
+    {
+      return source.Select(selector).Sum();
+    }
+
+    /// <summary>
+    /// Computes the average of a sequence of nullable <see cref="System.Single" /> values.
+    /// </summary>
+
+    public static float Average(
+      this IEnumerable<float> source)
+    {
+      CheckNotNull(source, "source");
+
+      float sum = 0;
+      long count = 0;
+
+      foreach (var num in source)
+        checked
+        {
+          sum += (float) num;
+          count++;
+        }
+
+      if (count == 0)
+        throw new InvalidOperationException();
+
+      return (float) sum/count;
+    }
+
+    /// <summary>
+    /// Computes the average of a sequence of nullable <see cref="System.Single" /> values 
+    /// that are obtained by invoking a transform function on each 
+    /// element of the input sequence.
+    /// </summary>
+
+    public static float Average<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, float> selector)
+    {
+      return source.Select(selector).Average();
+    }
+
+
+    /// <summary>
+    /// Computes the sum of a sequence of <see cref="System.Single" /> values.
+    /// </summary>
+
+    public static float? Sum(
+      this IEnumerable<float?> source)
+    {
+      CheckNotNull(source, "source");
+
+      float sum = 0;
+      foreach (var num in source)
+        sum = checked(sum + (num ?? 0));
+
+      return sum;
+    }
+
+    /// <summary>
+    /// Computes the sum of a sequence of <see cref="System.Single" /> 
+    /// values that are obtained by invoking a transform function on 
+    /// each element of the input sequence.
+    /// </summary>
+
+    public static float? Sum<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, float?> selector)
+    {
+      return source.Select(selector).Sum();
+    }
+
+    /// <summary>
+    /// Computes the average of a sequence of <see cref="System.Single" /> values.
+    /// </summary>
+
+    public static float? Average(
+      this IEnumerable<float?> source)
+    {
+      CheckNotNull(source, "source");
+
+      float sum = 0;
+      long count = 0;
+
+      foreach (var num in source.Where(n => n != null))
+        checked
+        {
+          sum += (float) num;
+          count++;
+        }
+
+      if (count == 0)
+        return null;
+
+      return (float?) sum/count;
+    }
+
+    /// <summary>
+    /// Computes the average of a sequence of <see cref="System.Single" /> values 
+    /// that are obtained by invoking a transform function on each 
+    /// element of the input sequence.
+    /// </summary>
+
+    public static float? Average<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, float?> selector)
+    {
+      return source.Select(selector).Average();
+    }
+
+    /// <summary>
+    /// Returns the minimum value in a sequence of nullable 
+    /// <see cref="System.Single" /> values.
+    /// </summary>
+
+    public static float? Min(
+      this IEnumerable<float?> source)
+    {
+      CheckNotNull(source, "source");
+
+      return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x);
+    }
+
+    /// <summary>
+    /// Invokes a transform function on each element of a sequence and 
+    /// returns the minimum nullable <see cref="System.Single" /> value.
+    /// </summary>
+
+    public static float? Min<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, float?> selector)
+    {
+      return source.Select(selector).Min();
+    }
+
+    /// <summary>
+    /// Returns the maximum value in a sequence of nullable 
+    /// <see cref="System.Single" /> values.
+    /// </summary>
+
+    public static float? Max(
+      this IEnumerable<float?> source)
+    {
+      CheckNotNull(source, "source");
+
+      return MinMaxImpl(source.Where(x => x != null),
+                        null, (max, x) => x == null || (max != null && x.Value < max.Value));
+    }
+
+    /// <summary>
+    /// Invokes a transform function on each element of a sequence and 
+    /// returns the maximum nullable <see cref="System.Single" /> value.
+    /// </summary>
+
+    public static float? Max<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, float?> selector)
+    {
+      return source.Select(selector).Max();
+    }
+
+    /// <summary>
+    /// Computes the sum of a sequence of nullable <see cref="System.Double" /> values.
+    /// </summary>
+
+    public static double Sum(
+      this IEnumerable<double> source)
+    {
+      CheckNotNull(source, "source");
+
+      double sum = 0;
+      foreach (var num in source)
+        sum = checked(sum + num);
+
+      return sum;
+    }
+
+    /// <summary>
+    /// Computes the sum of a sequence of nullable <see cref="System.Double" /> 
+    /// values that are obtained by invoking a transform function on 
+    /// each element of the input sequence.
+    /// </summary>
+
+    public static double Sum<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, double> selector)
+    {
+      return source.Select(selector).Sum();
+    }
+
+    /// <summary>
+    /// Computes the average of a sequence of nullable <see cref="System.Double" /> values.
+    /// </summary>
+
+    public static double Average(
+      this IEnumerable<double> source)
+    {
+      CheckNotNull(source, "source");
+
+      double sum = 0;
+      long count = 0;
+
+      foreach (var num in source)
+        checked
+        {
+          sum += (double) num;
+          count++;
+        }
+
+      if (count == 0)
+        throw new InvalidOperationException();
+
+      return (double) sum/count;
+    }
+
+    /// <summary>
+    /// Computes the average of a sequence of nullable <see cref="System.Double" /> values 
+    /// that are obtained by invoking a transform function on each 
+    /// element of the input sequence.
+    /// </summary>
+
+    public static double Average<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, double> selector)
+    {
+      return source.Select(selector).Average();
+    }
+
+
+    /// <summary>
+    /// Computes the sum of a sequence of <see cref="System.Double" /> values.
+    /// </summary>
+
+    public static double? Sum(
+      this IEnumerable<double?> source)
+    {
+      CheckNotNull(source, "source");
+
+      double sum = 0;
+      foreach (var num in source)
+        sum = checked(sum + (num ?? 0));
+
+      return sum;
+    }
+
+    /// <summary>
+    /// Computes the sum of a sequence of <see cref="System.Double" /> 
+    /// values that are obtained by invoking a transform function on 
+    /// each element of the input sequence.
+    /// </summary>
+
+    public static double? Sum<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, double?> selector)
+    {
+      return source.Select(selector).Sum();
+    }
+
+    /// <summary>
+    /// Computes the average of a sequence of <see cref="System.Double" /> values.
+    /// </summary>
+
+    public static double? Average(
+      this IEnumerable<double?> source)
+    {
+      CheckNotNull(source, "source");
+
+      double sum = 0;
+      long count = 0;
+
+      foreach (var num in source.Where(n => n != null))
+        checked
+        {
+          sum += (double) num;
+          count++;
+        }
+
+      if (count == 0)
+        return null;
+
+      return (double?) sum/count;
+    }
+
+    /// <summary>
+    /// Computes the average of a sequence of <see cref="System.Double" /> values 
+    /// that are obtained by invoking a transform function on each 
+    /// element of the input sequence.
+    /// </summary>
+
+    public static double? Average<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, double?> selector)
+    {
+      return source.Select(selector).Average();
+    }
+
+    /// <summary>
+    /// Returns the minimum value in a sequence of nullable 
+    /// <see cref="System.Double" /> values.
+    /// </summary>
+
+    public static double? Min(
+      this IEnumerable<double?> source)
+    {
+      CheckNotNull(source, "source");
+
+      return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x);
+    }
+
+    /// <summary>
+    /// Invokes a transform function on each element of a sequence and 
+    /// returns the minimum nullable <see cref="System.Double" /> value.
+    /// </summary>
+
+    public static double? Min<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, double?> selector)
+    {
+      return source.Select(selector).Min();
+    }
+
+    /// <summary>
+    /// Returns the maximum value in a sequence of nullable 
+    /// <see cref="System.Double" /> values.
+    /// </summary>
+
+    public static double? Max(
+      this IEnumerable<double?> source)
+    {
+      CheckNotNull(source, "source");
+
+      return MinMaxImpl(source.Where(x => x != null),
+                        null, (max, x) => x == null || (max != null && x.Value < max.Value));
+    }
+
+    /// <summary>
+    /// Invokes a transform function on each element of a sequence and 
+    /// returns the maximum nullable <see cref="System.Double" /> value.
+    /// </summary>
+
+    public static double? Max<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, double?> selector)
+    {
+      return source.Select(selector).Max();
+    }
+
+    /// <summary>
+    /// Computes the sum of a sequence of nullable <see cref="System.Decimal" /> values.
+    /// </summary>
+
+    public static decimal Sum(
+      this IEnumerable<decimal> source)
+    {
+      CheckNotNull(source, "source");
+
+      decimal sum = 0;
+      foreach (var num in source)
+        sum = checked(sum + num);
+
+      return sum;
+    }
+
+    /// <summary>
+    /// Computes the sum of a sequence of nullable <see cref="System.Decimal" /> 
+    /// values that are obtained by invoking a transform function on 
+    /// each element of the input sequence.
+    /// </summary>
+
+    public static decimal Sum<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, decimal> selector)
+    {
+      return source.Select(selector).Sum();
+    }
+
+    /// <summary>
+    /// Computes the average of a sequence of nullable <see cref="System.Decimal" /> values.
+    /// </summary>
+
+    public static decimal Average(
+      this IEnumerable<decimal> source)
+    {
+      CheckNotNull(source, "source");
+
+      decimal sum = 0;
+      long count = 0;
+
+      foreach (var num in source)
+        checked
+        {
+          sum += (decimal) num;
+          count++;
+        }
+
+      if (count == 0)
+        throw new InvalidOperationException();
+
+      return (decimal) sum/count;
+    }
+
+    /// <summary>
+    /// Computes the average of a sequence of nullable <see cref="System.Decimal" /> values 
+    /// that are obtained by invoking a transform function on each 
+    /// element of the input sequence.
+    /// </summary>
+
+    public static decimal Average<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, decimal> selector)
+    {
+      return source.Select(selector).Average();
+    }
+
+
+    /// <summary>
+    /// Computes the sum of a sequence of <see cref="System.Decimal" /> values.
+    /// </summary>
+
+    public static decimal? Sum(
+      this IEnumerable<decimal?> source)
+    {
+      CheckNotNull(source, "source");
+
+      decimal sum = 0;
+      foreach (var num in source)
+        sum = checked(sum + (num ?? 0));
+
+      return sum;
+    }
+
+    /// <summary>
+    /// Computes the sum of a sequence of <see cref="System.Decimal" /> 
+    /// values that are obtained by invoking a transform function on 
+    /// each element of the input sequence.
+    /// </summary>
+
+    public static decimal? Sum<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, decimal?> selector)
+    {
+      return source.Select(selector).Sum();
+    }
+
+    /// <summary>
+    /// Computes the average of a sequence of <see cref="System.Decimal" /> values.
+    /// </summary>
+
+    public static decimal? Average(
+      this IEnumerable<decimal?> source)
+    {
+      CheckNotNull(source, "source");
+
+      decimal sum = 0;
+      long count = 0;
+
+      foreach (var num in source.Where(n => n != null))
+        checked
+        {
+          sum += (decimal) num;
+          count++;
+        }
+
+      if (count == 0)
+        return null;
+
+      return (decimal?) sum/count;
+    }
+
+    /// <summary>
+    /// Computes the average of a sequence of <see cref="System.Decimal" /> values 
+    /// that are obtained by invoking a transform function on each 
+    /// element of the input sequence.
+    /// </summary>
+
+    public static decimal? Average<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, decimal?> selector)
+    {
+      return source.Select(selector).Average();
+    }
+
+    /// <summary>
+    /// Returns the minimum value in a sequence of nullable 
+    /// <see cref="System.Decimal" /> values.
+    /// </summary>
+
+    public static decimal? Min(
+      this IEnumerable<decimal?> source)
+    {
+      CheckNotNull(source, "source");
+
+      return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x);
+    }
+
+    /// <summary>
+    /// Invokes a transform function on each element of a sequence and 
+    /// returns the minimum nullable <see cref="System.Decimal" /> value.
+    /// </summary>
+
+    public static decimal? Min<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, decimal?> selector)
+    {
+      return source.Select(selector).Min();
+    }
+
+    /// <summary>
+    /// Returns the maximum value in a sequence of nullable 
+    /// <see cref="System.Decimal" /> values.
+    /// </summary>
+
+    public static decimal? Max(
+      this IEnumerable<decimal?> source)
+    {
+      CheckNotNull(source, "source");
+
+      return MinMaxImpl(source.Where(x => x != null),
+                        null, (max, x) => x == null || (max != null && x.Value < max.Value));
+    }
+
+    /// <summary>
+    /// Invokes a transform function on each element of a sequence and 
+    /// returns the maximum nullable <see cref="System.Decimal" /> value.
+    /// </summary>
+
+    public static decimal? Max<TSource>(
+      this IEnumerable<TSource> source,
+      Func<TSource, decimal?> selector)
+    {
+      return source.Select(selector).Max();
+    }
+  }
+
+  /// <summary>
+  /// Represents a collection of objects that have a common key.
+  /// </summary>
+  internal partial interface IGrouping<TKey, TElement> : IEnumerable<TElement>
+  {
+    /// <summary>
+    /// Gets the key of the <see cref="IGrouping{TKey,TElement}" />.
+    /// </summary>
+
+    TKey Key { get; }
+  }
+
+  /// <summary>
+  /// Defines an indexer, size property, and Boolean search method for 
+  /// data structures that map keys to <see cref="IEnumerable{T}"/> 
+  /// sequences of values.
+  /// </summary>
+  internal partial interface ILookup<TKey, TElement> : IEnumerable<IGrouping<TKey, TElement>>
+  {
+    bool Contains(TKey key);
+    int Count { get; }
+    IEnumerable<TElement> this[TKey key] { get; }
+  }
+
+  /// <summary>
+  /// Represents a sorted sequence.
+  /// </summary>
+  internal partial interface IOrderedEnumerable<TElement> : IEnumerable<TElement>
+  {
+    /// <summary>
+    /// Performs a subsequent ordering on the elements of an 
+    /// <see cref="IOrderedEnumerable{T}"/> according to a key.
+    /// </summary>
+
+    IOrderedEnumerable<TElement> CreateOrderedEnumerable<TKey>(
+      Func<TElement, TKey> keySelector, IComparer<TKey> comparer, bool descending);
+  }
+
+  /// <summary>
+  /// Represents a collection of keys each mapped to one or more values.
+  /// </summary>
+  internal sealed class Lookup<TKey, TElement> : ILookup<TKey, TElement>
+  {
+    private readonly Dictionary<TKey, IGrouping<TKey, TElement>> _map;
+
+    internal Lookup(IEqualityComparer<TKey> comparer)
+    {
+      _map = new Dictionary<TKey, IGrouping<TKey, TElement>>(comparer);
+    }
+
+    internal void Add(IGrouping<TKey, TElement> item)
+    {
+      _map.Add(item.Key, item);
+    }
+
+    internal IEnumerable<TElement> Find(TKey key)
+    {
+      IGrouping<TKey, TElement> grouping;
+      return _map.TryGetValue(key, out grouping) ? grouping : null;
+    }
+
+    /// <summary>
+    /// Gets the number of key/value collection pairs in the <see cref="Lookup{TKey,TElement}" />.
+    /// </summary>
+
+    public int Count
+    {
+      get { return _map.Count; }
+    }
+
+    /// <summary>
+    /// Gets the collection of values indexed by the specified key.
+    /// </summary>
+
+    public IEnumerable<TElement> this[TKey key]
+    {
+      get
+      {
+        IGrouping<TKey, TElement> result;
+        return _map.TryGetValue(key, out result) ? result : Enumerable.Empty<TElement>();
+      }
+    }
+
+    /// <summary>
+    /// Determines whether a specified key is in the <see cref="Lookup{TKey,TElement}" />.
+    /// </summary>
+
+    public bool Contains(TKey key)
+    {
+      return _map.ContainsKey(key);
+    }
+
+    /// <summary>
+    /// Applies a transform function to each key and its associated 
+    /// values and returns the results.
+    /// </summary>
+
+    public IEnumerable<TResult> ApplyResultSelector<TResult>(
+      Func<TKey, IEnumerable<TElement>, TResult> resultSelector)
+    {
+      if (resultSelector == null)
+        throw new ArgumentNullException("resultSelector");
+
+      foreach (var pair in _map)
+        yield return resultSelector(pair.Key, pair.Value);
+    }
+
+    /// <summary>
+    /// Returns a generic enumerator that iterates through the <see cref="Lookup{TKey,TElement}" />.
+    /// </summary>
+
+    public IEnumerator<IGrouping<TKey, TElement>> GetEnumerator()
+    {
+      return _map.Values.GetEnumerator();
+    }
+
+    IEnumerator IEnumerable.GetEnumerator()
+    {
+      return GetEnumerator();
+    }
+  }
+
+  internal sealed class OrderedEnumerable<T, K> : IOrderedEnumerable<T>
+  {
+    private readonly IEnumerable<T> _source;
+    private readonly List<Comparison<T>> _comparisons;
+
+    public OrderedEnumerable(IEnumerable<T> source,
+                             Func<T, K> keySelector, IComparer<K> comparer, bool descending) :
+                               this(source, null, keySelector, comparer, descending)
+    {
+    }
+
+    private OrderedEnumerable(IEnumerable<T> source, List<Comparison<T>> comparisons,
+                              Func<T, K> keySelector, IComparer<K> comparer, bool descending)
+    {
+      if (source == null) throw new ArgumentNullException("source");
+      if (keySelector == null) throw new ArgumentNullException("keySelector");
+
+      _source = source;
+
+      comparer = comparer ?? Comparer<K>.Default;
+
+      if (comparisons == null)
+        comparisons = new List<Comparison<T>>( /* capacity */ 4);
+
+      comparisons.Add((x, y)
+                      => (descending ? -1 : 1)*comparer.Compare(keySelector(x), keySelector(y)));
+
+      _comparisons = comparisons;
+    }
+
+    public IOrderedEnumerable<T> CreateOrderedEnumerable<KK>(
+      Func<T, KK> keySelector, IComparer<KK> comparer, bool descending)
+    {
+      return new OrderedEnumerable<T, KK>(_source, _comparisons, keySelector, comparer, descending);
+    }
+
+    public IEnumerator<T> GetEnumerator()
+    {
+      //
+      // We sort using List<T>.Sort, but docs say that it performs an 
+      // unstable sort. LINQ, on the other hand, says OrderBy performs 
+      // a stable sort. So convert the source sequence into a sequence 
+      // of tuples where the second element tags the position of the 
+      // element from the source sequence (First). The position is 
+      // then used as a tie breaker when all keys compare equal,
+      // thus making the sort stable.
+      //
+
+      var list = _source.Select(new Func<T, int, Tuple<T, int>>(TagPosition)).ToList();
+
+      list.Sort((x, y) =>
+        {
+          //
+          // Compare keys from left to right.
+          //
+
+          var comparisons = _comparisons;
+          for (var i = 0; i < comparisons.Count; i++)
+          {
+            var result = comparisons[i](x.First, y.First);
+            if (result != 0)
+              return result;
+          }
+
+          //
+          // All keys compared equal so now break the tie by their
+          // position in the original sequence, making the sort stable.
+          //
+
+          return x.Second.CompareTo(y.Second);
+        });
+
+      return list.Select(new Func<Tuple<T, int>, T>(GetFirst)).GetEnumerator();
+
+    }
+
+    /// <remarks>
+    /// See <a href="http://code.google.com/p/linqbridge/issues/detail?id=11">issue #11</a>
+    /// for why this method is needed and cannot be expressed as a 
+    /// lambda at the call site.
+    /// </remarks>
+
+    private static Tuple<T, int> TagPosition(T e, int i)
+    {
+      return new Tuple<T, int>(e, i);
+    }
+
+    /// <remarks>
+    /// See <a href="http://code.google.com/p/linqbridge/issues/detail?id=11">issue #11</a>
+    /// for why this method is needed and cannot be expressed as a 
+    /// lambda at the call site.
+    /// </remarks>
+
+    private static T GetFirst(Tuple<T, int> pv)
+    {
+      return pv.First;
+    }
+
+    IEnumerator IEnumerable.GetEnumerator()
+    {
+      return GetEnumerator();
+    }
+  }
+
+  [Serializable]
+  internal struct Tuple<TFirst, TSecond> : IEquatable<Tuple<TFirst, TSecond>>
+  {
+    public TFirst First { get; private set; }
+    public TSecond Second { get; private set; }
+
+    public Tuple(TFirst first, TSecond second)
+      : this()
+    {
+      First = first;
+      Second = second;
+    }
+
+    public override bool Equals(object obj)
+    {
+      return obj != null
+             && obj is Tuple<TFirst, TSecond>
+             && base.Equals((Tuple<TFirst, TSecond>) obj);
+    }
+
+    public bool Equals(Tuple<TFirst, TSecond> other)
+    {
+      return EqualityComparer<TFirst>.Default.Equals(other.First, First)
+             && EqualityComparer<TSecond>.Default.Equals(other.Second, Second);
+    }
+
+    public override int GetHashCode()
+    {
+      var num = 0x7a2f0b42;
+      num = (-1521134295*num) + EqualityComparer<TFirst>.Default.GetHashCode(First);
+      return (-1521134295*num) + EqualityComparer<TSecond>.Default.GetHashCode(Second);
+    }
+
+    public override string ToString()
+    {
+      return string.Format(@"{{ First = {0}, Second = {1} }}", First, Second);
+    }
+  }
+}
+
+namespace Newtonsoft.Json.Serialization
+{
+  public delegate TResult Func<TResult>();
+
+  public delegate TResult Func<T, TResult>(T a);
+
+  public delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);
+
+  public delegate TResult Func<T1, T2, T3, TResult>(T1 arg1, T2 arg2, T3 arg3);
+
+  public delegate TResult Func<T1, T2, T3, T4, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
+
+  public delegate void Action();
+
+  public delegate void Action<T1, T2>(T1 arg1, T2 arg2);
+
+  public delegate void Action<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3);
+
+  public delegate void Action<T1, T2, T3, T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
+}
+
+namespace System.Runtime.CompilerServices
+{
+  /// <remarks>
+  /// This attribute allows us to define extension methods without 
+  /// requiring .NET Framework 3.5. For more information, see the section,
+  /// <a href="http://msdn.microsoft.com/en-us/magazine/cc163317.aspx#S7">Extension Methods in .NET Framework 2.0 Apps</a>,
+  /// of <a href="http://msdn.microsoft.com/en-us/magazine/cc163317.aspx">Basic Instincts: Extension Methods</a>
+  /// column in <a href="http://msdn.microsoft.com/msdnmag/">MSDN Magazine</a>, 
+  /// issue <a href="http://msdn.microsoft.com/en-us/magazine/cc135410.aspx">Nov 2007</a>.
+  /// </remarks>
+
+  [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly)]
+  internal sealed class ExtensionAttribute : Attribute { }
+}
+
+#endif
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ListWrapper.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ListWrapper.cs
index a485fab..b21b81c 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ListWrapper.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ListWrapper.cs
@@ -1,290 +1,189 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Threading;
-using Newtonsoft.Json.Utilities;
-using System.Linq;
-using System.Globalization;
-
-namespace Newtonsoft.Json.Utilities
-{
-  internal interface IWrappedList : IList
-  {
-    object UnderlyingList { get; }
-  }
-
-  internal class ListWrapper<T> : IList<T>, IWrappedList
-  {
-    private readonly IList _list;
-    private readonly IList<T> _genericList;
-    private object _syncRoot;
-
-    public ListWrapper(IList list)
-    {
-      ValidationUtils.ArgumentNotNull(list, "list");
-
-      if (list is IList<T>)
-        _genericList = (IList<T>) list;
-      else
-        _list = list;
-    }
-
-    public ListWrapper(IList<T> list)
-    {
-      ValidationUtils.ArgumentNotNull(list, "list");
-
-      _genericList = list;
-    }
-
-    public int IndexOf(T item)
-    {
-      if (_genericList != null)
-        return _genericList.IndexOf(item);
-      else
-        return _list.IndexOf(item);
-    }
-
-    public void Insert(int index, T item)
-    {
-      if (_genericList != null)
-        _genericList.Insert(index, item);
-      else
-        _list.Insert(index, item);
-    }
-
-    public void RemoveAt(int index)
-    {
-      if (_genericList != null)
-        _genericList.RemoveAt(index);
-      else
-        _list.RemoveAt(index);
-    }
-
-    public T this[int index]
-    {
-      get
-      {
-        if (_genericList != null)
-          return _genericList[index];
-        else
-          return (T)_list[index];
-      }
-      set
-      {
-        if (_genericList != null)
-          _genericList[index] = value;
-        else
-          _list[index] = value;
-      }
-    }
-
-    public void Add(T item)
-    {
-      if (_genericList != null)
-        _genericList.Add(item);
-      else
-        _list.Add(item);
-    }
-
-    public void Clear()
-    {
-      if (_genericList != null)
-        _genericList.Clear();
-      else
-        _list.Clear();
-    }
-
-    public bool Contains(T item)
-    {
-      if (_genericList != null)
-        return _genericList.Contains(item);
-      else
-        return _list.Contains(item);
-    }
-
-    public void CopyTo(T[] array, int arrayIndex)
-    {
-      if (_genericList != null)
-        _genericList.CopyTo(array, arrayIndex);
-      else
-        _list.CopyTo(array, arrayIndex);
-    }
-
-    public int Count
-    {
-      get
-      {
-        if (_genericList != null)
-          return _genericList.Count;
-        else
-          return _list.Count;
-      }
-    }
-
-    public bool IsReadOnly
-    {
-      get
-      {
-        if (_genericList != null)
-          return _genericList.IsReadOnly;
-        else
-          return _list.IsReadOnly;
-      }
-    }
-
-    public bool Remove(T item)
-    {
-      if (_genericList != null)
-      {
-        return _genericList.Remove(item);
-      }
-      else
-      {
-        bool contains = _list.Contains(item);
-
-        if (contains)
-          _list.Remove(item);
-
-        return contains;
-      }
-    }
-
-    public IEnumerator<T> GetEnumerator()
-    {
-      if (_genericList != null)
-        return _genericList.GetEnumerator();
-
-      return _list.Cast<T>().GetEnumerator();
-    }
-
-    IEnumerator IEnumerable.GetEnumerator()
-    {
-      if (_genericList != null)
-        return _genericList.GetEnumerator();
-      else
-        return _list.GetEnumerator();
-    }
-
-    int IList.Add(object value)
-    {
-      VerifyValueType(value);
-      Add((T)value);
-
-      return (Count - 1);
-    }
-
-    bool IList.Contains(object value)
-    {
-      if (IsCompatibleObject(value))
-        return Contains((T)value);
-
-      return false;
-    }
-
-    int IList.IndexOf(object value)
-    {
-      if (IsCompatibleObject(value))
-        return IndexOf((T)value);
-
-      return -1;
-    }
-
-    void IList.Insert(int index, object value)
-    {
-      VerifyValueType(value);
-      Insert(index, (T)value);
-    }
-
-    bool IList.IsFixedSize
-    {
-      get { return false; }
-    }
-
-    void IList.Remove(object value)
-    {
-      if (IsCompatibleObject(value))
-        Remove((T)value);
-    }
-
-    object IList.this[int index]
-    {
-      get { return this[index]; }
-      set
-      {
-        VerifyValueType(value);
-        this[index] = (T)value;
-      }
-    }
-
-    void ICollection.CopyTo(Array array, int arrayIndex)
-    {
-      CopyTo((T[])array, arrayIndex);
-    }
-
-    bool ICollection.IsSynchronized
-    {
-      get { return false; }
-    }
-
-    object ICollection.SyncRoot
-    {
-      get
-      {
-        if (_syncRoot == null)
-          Interlocked.CompareExchange(ref _syncRoot, new object(), null);
-
-        return _syncRoot;
-      }
-    }
-
-    private static void VerifyValueType(object value)
-    {
-      if (!IsCompatibleObject(value))
-        throw new ArgumentException("The value '{0}' is not of type '{1}' and cannot be used in this generic collection.".FormatWith(CultureInfo.InvariantCulture, value, typeof(T)), "value");
-    }
-
-    private static bool IsCompatibleObject(object value)
-    {
-      if (!(value is T) && (value != null || (typeof(T).IsValueType && !ReflectionUtils.IsNullableType(typeof(T)))))
-        return false;
-
-      return true;
-    }
-
-    public object UnderlyingList
-    {
-      get
-      {
-        if (_genericList != null)
-          return _genericList;
-        else
-          return _list;
-      }
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System.Collections;
+using System.Collections.Generic;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal interface IWrappedList : IList
+  {
+    object UnderlyingList { get; }
+  }
+
+  internal class ListWrapper<T> : CollectionWrapper<T>, IList<T>, IWrappedList
+  {
+    private readonly IList<T> _genericList;
+
+    public ListWrapper(IList list)
+      : base(list)
+    {
+      ValidationUtils.ArgumentNotNull(list, "list");
+
+      if (list is IList<T>)
+        _genericList = (IList<T>) list;
+    }
+
+    public ListWrapper(IList<T> list)
+      : base(list)
+    {
+      ValidationUtils.ArgumentNotNull(list, "list");
+
+      _genericList = list;
+    }
+
+    public int IndexOf(T item)
+    {
+      if (_genericList != null)
+        return _genericList.IndexOf(item);
+      else
+        return ((IList)this).IndexOf(item);
+    }
+
+    public void Insert(int index, T item)
+    {
+      if (_genericList != null)
+        _genericList.Insert(index, item);
+      else
+        ((IList)this).Insert(index, item);
+    }
+
+    public void RemoveAt(int index)
+    {
+      if (_genericList != null)
+        _genericList.RemoveAt(index);
+      else
+        ((IList)this).RemoveAt(index);
+    }
+
+    public T this[int index]
+    {
+      get
+      {
+        if (_genericList != null)
+          return _genericList[index];
+        else
+          return (T)((IList)this)[index];
+      }
+      set
+      {
+        if (_genericList != null)
+          _genericList[index] = value;
+        else
+          ((IList)this)[index] = value;
+      }
+    }
+
+    public override void Add(T item)
+    {
+      if (_genericList != null)
+        _genericList.Add(item);
+      else
+        base.Add(item);
+    }
+
+    public override void Clear()
+    {
+      if (_genericList != null)
+        _genericList.Clear();
+      else
+        base.Clear();
+    }
+
+    public override bool Contains(T item)
+    {
+      if (_genericList != null)
+        return _genericList.Contains(item);
+      else
+        return base.Contains(item);
+    }
+
+    public override void CopyTo(T[] array, int arrayIndex)
+    {
+      if (_genericList != null)
+        _genericList.CopyTo(array, arrayIndex);
+      else
+        base.CopyTo(array, arrayIndex);
+    }
+
+    public override int Count
+    {
+      get
+      {
+        if (_genericList != null)
+          return _genericList.Count;
+        else
+          return base.Count;
+      }
+    }
+
+    public override bool IsReadOnly
+    {
+      get
+      {
+        if (_genericList != null)
+          return _genericList.IsReadOnly;
+        else
+          return base.IsReadOnly;
+      }
+    }
+
+    public override bool Remove(T item)
+    {
+      if (_genericList != null)
+      {
+        return _genericList.Remove(item);
+      }
+      else
+      {
+        bool contains = base.Contains(item);
+
+        if (contains)
+          base.Remove(item);
+
+        return contains;
+      }
+    }
+
+    public override IEnumerator<T> GetEnumerator()
+    {
+      if (_genericList != null)
+        return _genericList.GetEnumerator();
+
+      return base.GetEnumerator();
+    }
+
+    public object UnderlyingList
+    {
+      get
+      {
+        if (_genericList != null)
+          return _genericList;
+        else
+          return UnderlyingCollection;
+      }
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/MathUtils.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/MathUtils.cs
index db489eb..c109de7 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/MathUtils.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/MathUtils.cs
@@ -1,128 +1,96 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace Newtonsoft.Json.Utilities
-{
-  internal class MathUtils
-  {
-    public static int IntLength(int i)
-    {
-      if (i < 0)
-        throw new ArgumentOutOfRangeException();
-
-      if (i == 0)
-        return 1;
-
-      return (int)Math.Floor(Math.Log10(i)) + 1;
-    }
-
-    public static int HexToInt(char h)
-    {
-      if ((h >= '0') && (h <= '9'))
-      {
-        return (h - '0');
-      }
-      if ((h >= 'a') && (h <= 'f'))
-      {
-        return ((h - 'a') + 10);
-      }
-      if ((h >= 'A') && (h <= 'F'))
-      {
-        return ((h - 'A') + 10);
-      }
-      return -1;
-    }
-
-    public static char IntToHex(int n)
-    {
-      if (n <= 9)
-      {
-        return (char)(n + 48);
-      }
-      return (char)((n - 10) + 97);
-    }
-
-    public static int GetDecimalPlaces(double value)
-    {
-      // increasing max decimal places above 10 produces weirdness
-      int maxDecimalPlaces = 10;
-      double threshold = Math.Pow(0.1d, maxDecimalPlaces);
-
-      if (value == 0.0)
-        return 0;
-      int decimalPlaces = 0;
-      while (value - Math.Floor(value) > threshold && decimalPlaces < maxDecimalPlaces)
-      {
-        value *= 10.0;
-        decimalPlaces++;
-      }
-      return decimalPlaces;
-    }
-
-    public static int? Min(int? val1, int? val2)
-    {
-      if (val1 == null)
-        return val2;
-      if (val2 == null)
-        return val1;
-
-      return Math.Min(val1.Value, val2.Value);
-    }
-
-    public static int? Max(int? val1, int? val2)
-    {
-      if (val1 == null)
-        return val2;
-      if (val2 == null)
-        return val1;
-
-      return Math.Max(val1.Value, val2.Value);
-    }
-
-    public static double? Min(double? val1, double? val2)
-    {
-      if (val1 == null)
-        return val2;
-      if (val2 == null)
-        return val1;
-
-      return Math.Min(val1.Value, val2.Value);
-    }
-
-    public static double? Max(double? val1, double? val2)
-    {
-      if (val1 == null)
-        return val2;
-      if (val2 == null)
-        return val1;
-
-      return Math.Max(val1.Value, val2.Value);
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal class MathUtils
+  {
+    public static int IntLength(int i)
+    {
+      if (i < 0)
+        throw new ArgumentOutOfRangeException();
+
+      if (i == 0)
+        return 1;
+
+      return (int)Math.Floor(Math.Log10(i)) + 1;
+    }
+
+    public static char IntToHex(int n)
+    {
+      if (n <= 9)
+        return (char)(n + 48);
+
+      return (char)((n - 10) + 97);
+    }
+
+    public static int? Min(int? val1, int? val2)
+    {
+      if (val1 == null)
+        return val2;
+      if (val2 == null)
+        return val1;
+
+      return Math.Min(val1.Value, val2.Value);
+    }
+
+    public static int? Max(int? val1, int? val2)
+    {
+      if (val1 == null)
+        return val2;
+      if (val2 == null)
+        return val1;
+
+      return Math.Max(val1.Value, val2.Value);
+    }
+
+    public static double? Max(double? val1, double? val2)
+    {
+      if (val1 == null)
+        return val2;
+      if (val2 == null)
+        return val1;
+
+      return Math.Max(val1.Value, val2.Value);
+    }
+
+    public static bool ApproxEquals(double d1, double d2)
+    {
+      const double epsilon = 2.2204460492503131E-16;
+
+      if (d1 == d2)
+        return true;
+
+      double tolerance = ((Math.Abs(d1) + Math.Abs(d2)) + 10.0) * epsilon;
+      double difference = d1 - d2;
+
+      return (-tolerance < difference && tolerance > difference);
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/MethodCall.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/MethodCall.cs
index 93abb87..6305dca 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/MethodCall.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/MethodCall.cs
@@ -1,29 +1,29 @@
-#region License
-// 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.
-#endregion
-
-namespace Newtonsoft.Json.Utilities
-{
-  internal delegate TResult MethodCall<T, TResult>(T target, params object[] args);
+#region License
+// 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.
+#endregion
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal delegate TResult MethodCall<T, TResult>(T target, params object[] args);
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/MiscellaneousUtils.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/MiscellaneousUtils.cs
index b6665c9..5b84bec 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/MiscellaneousUtils.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/MiscellaneousUtils.cs
@@ -1,136 +1,187 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Reflection;
-using System.Text;
-using System.Globalization;
-
-namespace Newtonsoft.Json.Utilities
-{
-  internal delegate T Creator<T>();
-
-  internal static class MiscellaneousUtils
-  {
-    public static ArgumentOutOfRangeException CreateArgumentOutOfRangeException(string paramName, object actualValue, string message)
-    {
-      string newMessage = message + Environment.NewLine + @"Actual value was {0}.".FormatWith(CultureInfo.InvariantCulture, actualValue);
-
-      return new ArgumentOutOfRangeException(paramName, newMessage);
-    }
-
-    public static bool TryAction<T>(Creator<T> creator, out T output)
-    {
-      ValidationUtils.ArgumentNotNull(creator, "creator");
-
-      try
-      {
-        output = creator();
-        return true;
-      }
-      catch
-      {
-        output = default(T);
-        return false;
-      }
-    }
-
-    public static string ToString(object value)
-    {
-      if (value == null)
-        return "{null}";
-
-      return (value is string) ? @"""" + value.ToString() + @"""" : value.ToString();
-    }
-
-    public static byte[] HexToBytes(string hex)
-    {
-      string fixedHex = hex.Replace("-", string.Empty);
-
-      // array to put the result in
-      byte[] bytes = new byte[fixedHex.Length / 2];
-      // variable to determine shift of high/low nibble
-      int shift = 4;
-      // offset of the current byte in the array
-      int offset = 0;
-      // loop the characters in the string
-      foreach (char c in fixedHex)
-      {
-        // get character code in range 0-9, 17-22
-        // the % 32 handles lower case characters
-        int b = (c - '0') % 32;
-        // correction for a-f
-        if (b > 9) b -= 7;
-        // store nibble (4 bits) in byte array
-        bytes[offset] |= (byte)(b << shift);
-        // toggle the shift variable between 0 and 4
-        shift ^= 4;
-        // move to next byte
-        if (shift != 0) offset++;
-      }
-      return bytes;
-    }
-
-    public static string BytesToHex(byte[] bytes)
-    {
-      return BytesToHex(bytes, false);
-    }
-
-    public static string BytesToHex(byte[] bytes, bool removeDashes)
-    {
-      string hex = BitConverter.ToString(bytes);
-      if (removeDashes)
-        hex = hex.Replace("-", "");
-
-      return hex;
-    }
-
-    public static bool ByteArrayCompare(byte[] a1, byte[] a2)
-    {
-      if (a1.Length != a2.Length)
-        return false;
-
-      for (int i = 0; i < a1.Length; i++)
-      {
-        if (a1[i] != a2[i])
-          return false;
-      }
-
-      return true;
-    }
-
-    public static string GetPrefix(string qualifiedName)
-    {
-      string prefix;
-      string localName;
-      GetQualifiedNameParts(qualifiedName, out prefix, out localName);
-
-      return prefix;
-    }
-
-    public static string GetLocalName(string qualifiedName)
-    {
-      string prefix;
-      string localName;
-      GetQualifiedNameParts(qualifiedName, out prefix, out localName);
-
-      return localName;
-    }
-
-    public static void GetQualifiedNameParts(string qualifiedName, out string prefix, out string localName)
-    {
-      int colonPosition = qualifiedName.IndexOf(':');
-
-      if ((colonPosition == -1 || colonPosition == 0) || (qualifiedName.Length - 1) == colonPosition)
-      {
-        prefix = null;
-        localName = qualifiedName;
-      }
-      else
-      {
-        prefix = qualifiedName.Substring(0, colonPosition);
-        localName = qualifiedName.Substring(colonPosition + 1);
-      }
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Reflection;
+using System.Text;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal delegate T Creator<T>();
+
+  internal static class MiscellaneousUtils
+  {
+    public static bool ValueEquals(object objA, object objB)
+    {
+      if (objA == null && objB == null)
+        return true;
+      if (objA != null && objB == null)
+        return false;
+      if (objA == null && objB != null)
+        return false;
+
+      // comparing an Int32 and Int64 both of the same value returns false
+      // make types the same then compare
+      if (objA.GetType() != objB.GetType())
+      {
+        if (ConvertUtils.IsInteger(objA) && ConvertUtils.IsInteger(objB))
+          return Convert.ToDecimal(objA, CultureInfo.CurrentCulture).Equals(Convert.ToDecimal(objB, CultureInfo.CurrentCulture));
+        else if ((objA is double || objA is float || objA is decimal) && (objB is double || objB is float || objB is decimal))
+          return MathUtils.ApproxEquals(Convert.ToDouble(objA, CultureInfo.CurrentCulture), Convert.ToDouble(objB, CultureInfo.CurrentCulture));
+        else
+          return false;
+      }
+
+      return objA.Equals(objB);
+    }
+
+    public static ArgumentOutOfRangeException CreateArgumentOutOfRangeException(string paramName, object actualValue, string message)
+    {
+      string newMessage = message + Environment.NewLine + @"Actual value was {0}.".FormatWith(CultureInfo.InvariantCulture, actualValue);
+
+      return new ArgumentOutOfRangeException(paramName, newMessage);
+    }
+
+    public static bool TryAction<T>(Creator<T> creator, out T output)
+    {
+      ValidationUtils.ArgumentNotNull(creator, "creator");
+
+      try
+      {
+        output = creator();
+        return true;
+      }
+      catch
+      {
+        output = default(T);
+        return false;
+      }
+    }
+
+    public static string ToString(object value)
+    {
+      if (value == null)
+        return "{null}";
+
+      return (value is string) ? @"""" + value.ToString() + @"""" : value.ToString();
+    }
+
+    public static byte[] HexToBytes(string hex)
+    {
+      string fixedHex = hex.Replace("-", string.Empty);
+
+      // array to put the result in
+      byte[] bytes = new byte[fixedHex.Length / 2];
+      // variable to determine shift of high/low nibble
+      int shift = 4;
+      // offset of the current byte in the array
+      int offset = 0;
+      // loop the characters in the string
+      foreach (char c in fixedHex)
+      {
+        // get character code in range 0-9, 17-22
+        // the % 32 handles lower case characters
+        int b = (c - '0') % 32;
+        // correction for a-f
+        if (b > 9) b -= 7;
+        // store nibble (4 bits) in byte array
+        bytes[offset] |= (byte)(b << shift);
+        // toggle the shift variable between 0 and 4
+        shift ^= 4;
+        // move to next byte
+        if (shift != 0) offset++;
+      }
+      return bytes;
+    }
+
+    public static string BytesToHex(byte[] bytes)
+    {
+      return BytesToHex(bytes, false);
+    }
+
+    public static string BytesToHex(byte[] bytes, bool removeDashes)
+    {
+      string hex = BitConverter.ToString(bytes);
+      if (removeDashes)
+        hex = hex.Replace("-", "");
+
+      return hex;
+    }
+
+    public static int ByteArrayCompare(byte[] a1, byte[] a2)
+    {
+      int lengthCompare = a1.Length.CompareTo(a2.Length);
+      if (lengthCompare != 0)
+        return lengthCompare;
+
+      for (int i = 0; i < a1.Length; i++)
+      {
+        int valueCompare = a1[i].CompareTo(a2[i]);
+        if (valueCompare != 0)
+          return valueCompare;
+      }
+
+      return 0;
+    }
+
+    public static string GetPrefix(string qualifiedName)
+    {
+      string prefix;
+      string localName;
+      GetQualifiedNameParts(qualifiedName, out prefix, out localName);
+
+      return prefix;
+    }
+
+    public static string GetLocalName(string qualifiedName)
+    {
+      string prefix;
+      string localName;
+      GetQualifiedNameParts(qualifiedName, out prefix, out localName);
+
+      return localName;
+    }
+
+    public static void GetQualifiedNameParts(string qualifiedName, out string prefix, out string localName)
+    {
+      int colonPosition = qualifiedName.IndexOf(':');
+
+      if ((colonPosition == -1 || colonPosition == 0) || (qualifiedName.Length - 1) == colonPosition)
+      {
+        prefix = null;
+        localName = qualifiedName;
+      }
+      else
+      {
+        prefix = qualifiedName.Substring(0, colonPosition);
+        localName = qualifiedName.Substring(colonPosition + 1);
+      }
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ReflectionDelegateFactory.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ReflectionDelegateFactory.cs
index 1fcb762..47f1cf3 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ReflectionDelegateFactory.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ReflectionDelegateFactory.cs
@@ -1,67 +1,71 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Globalization;
-using System.Reflection;
-
-namespace Newtonsoft.Json.Utilities
-{
-  internal abstract class ReflectionDelegateFactory
-  {
-    public Func<T, object> CreateGet<T>(MemberInfo memberInfo)
-    {
-      PropertyInfo propertyInfo = memberInfo as PropertyInfo;
-      if (propertyInfo != null)
-        return CreateGet<T>(propertyInfo);
-
-      FieldInfo fieldInfo = memberInfo as FieldInfo;
-      if (fieldInfo != null)
-        return CreateGet<T>(fieldInfo);
-
-      throw new Exception("Could not create getter for {0}.".FormatWith(CultureInfo.InvariantCulture, memberInfo));
-    }
-
-    public Action<T, object> CreateSet<T>(MemberInfo memberInfo)
-    {
-      PropertyInfo propertyInfo = memberInfo as PropertyInfo;
-      if (propertyInfo != null)
-        return CreateSet<T>(propertyInfo);
-
-      FieldInfo fieldInfo = memberInfo as FieldInfo;
-      if (fieldInfo != null)
-        return CreateSet<T>(fieldInfo);
-
-      throw new Exception("Could not create setter for {0}.".FormatWith(CultureInfo.InvariantCulture, memberInfo));
-    }
-
-    public abstract MethodCall<T, object> CreateMethodCall<T>(MethodBase method);
-    public abstract Func<T> CreateDefaultConstructor<T>(Type type);
-    public abstract Func<T, object> CreateGet<T>(PropertyInfo propertyInfo);
-    public abstract Func<T, object> CreateGet<T>(FieldInfo fieldInfo);
-    public abstract Action<T, object> CreateSet<T>(FieldInfo fieldInfo);
-    public abstract Action<T, object> CreateSet<T>(PropertyInfo propertyInfo);
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Globalization;
+using System.Reflection;
+using Newtonsoft.Json.Serialization;
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#endif
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal abstract class ReflectionDelegateFactory
+  {
+    public Func<T, object> CreateGet<T>(MemberInfo memberInfo)
+    {
+      PropertyInfo propertyInfo = memberInfo as PropertyInfo;
+      if (propertyInfo != null)
+        return CreateGet<T>(propertyInfo);
+
+      FieldInfo fieldInfo = memberInfo as FieldInfo;
+      if (fieldInfo != null)
+        return CreateGet<T>(fieldInfo);
+
+      throw new Exception("Could not create getter for {0}.".FormatWith(CultureInfo.InvariantCulture, memberInfo));
+    }
+
+    public Action<T, object> CreateSet<T>(MemberInfo memberInfo)
+    {
+      PropertyInfo propertyInfo = memberInfo as PropertyInfo;
+      if (propertyInfo != null)
+        return CreateSet<T>(propertyInfo);
+
+      FieldInfo fieldInfo = memberInfo as FieldInfo;
+      if (fieldInfo != null)
+        return CreateSet<T>(fieldInfo);
+
+      throw new Exception("Could not create setter for {0}.".FormatWith(CultureInfo.InvariantCulture, memberInfo));
+    }
+
+    public abstract MethodCall<T, object> CreateMethodCall<T>(MethodBase method);
+    public abstract Func<T> CreateDefaultConstructor<T>(Type type);
+    public abstract Func<T, object> CreateGet<T>(PropertyInfo propertyInfo);
+    public abstract Func<T, object> CreateGet<T>(FieldInfo fieldInfo);
+    public abstract Action<T, object> CreateSet<T>(FieldInfo fieldInfo);
+    public abstract Action<T, object> CreateSet<T>(PropertyInfo propertyInfo);
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs
index 7419ba8..950e733 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs
@@ -1,930 +1,1019 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Reflection;
-using System.Collections;
-using System.Linq;
-using System.Globalization;
-using System.Runtime.Serialization.Formatters;
-using System.Text;
-using System.Text.RegularExpressions;
-
-namespace Newtonsoft.Json.Utilities
-{
-  internal static class ReflectionUtils
-  {
-    public static Type GetObjectType(object v)
-    {
-      return (v != null) ? v.GetType() : null;
-    }
-
-    public static string GetTypeName(Type t, FormatterAssemblyStyle assemblyFormat)
-    {
-      switch (assemblyFormat)
-      {
-        case FormatterAssemblyStyle.Simple:
-          return GetSimpleTypeName(t);
-        case FormatterAssemblyStyle.Full:
-          return t.AssemblyQualifiedName;
-        default:
-          throw new ArgumentOutOfRangeException();
-      }
-    }
-
-    private static string GetSimpleTypeName(Type type)
-    {
-#if !SILVERLIGHT
-      string fullyQualifiedTypeName = type.FullName + ", " + type.Assembly.GetName().Name;
-
-      // for type names with no nested type names then return
-      if (!type.IsGenericType || type.IsGenericTypeDefinition)
-        return fullyQualifiedTypeName;
-#else
-      // Assembly.GetName() is marked SecurityCritical
-      string fullyQualifiedTypeName = type.AssemblyQualifiedName;
-#endif
-
-      StringBuilder builder = new StringBuilder();
-
-      // loop through the type name and filter out qualified assembly details from nested type names
-      bool writingAssemblyName = false;
-      bool skippingAssemblyDetails = false;
-      for (int i = 0; i < fullyQualifiedTypeName.Length; i++)
-      {
-        char current = fullyQualifiedTypeName[i];
-        switch (current)
-        {
-          case '[':
-            writingAssemblyName = false;
-            skippingAssemblyDetails = false;
-            builder.Append(current);
-            break;
-          case ']':
-            writingAssemblyName = false;
-            skippingAssemblyDetails = false;
-            builder.Append(current);
-            break;
-          case ',':
-            if (!writingAssemblyName)
-            {
-              writingAssemblyName = true;
-              builder.Append(current);
-            }
-            else
-            {
-              skippingAssemblyDetails = true;
-            }
-            break;
-          default:
-            if (!skippingAssemblyDetails)
-              builder.Append(current);
-            break;
-        }
-      }
-
-      return builder.ToString();
-    }
-
-    public static bool IsInstantiatableType(Type t)
-    {
-      ValidationUtils.ArgumentNotNull(t, "t");
-
-      if (t.IsAbstract || t.IsInterface || t.IsArray || t.IsGenericTypeDefinition || t == typeof(void))
-        return false;
-
-      if (!HasDefaultConstructor(t))
-        return false;
-
-      return true;
-    }
-
-    public static bool HasDefaultConstructor(Type t)
-    {
-      return HasDefaultConstructor(t, false);
-    }
-
-    public static bool HasDefaultConstructor(Type t, bool nonPublic)
-    {
-      ValidationUtils.ArgumentNotNull(t, "t");
-
-      if (t.IsValueType)
-        return true;
-
-      return (GetDefaultConstructor(t, nonPublic) != null);
-    }
-
-    public static ConstructorInfo GetDefaultConstructor(Type t)
-    {
-      return GetDefaultConstructor(t, false);
-    }
-
-    public static ConstructorInfo GetDefaultConstructor(Type t, bool nonPublic)
-    {
-      BindingFlags accessModifier = BindingFlags.Public;
-      
-      if (nonPublic)
-        accessModifier = accessModifier | BindingFlags.NonPublic;
-
-      return t.GetConstructor(accessModifier | BindingFlags.Instance, null, new Type[0], null);
-    }
-
-    public static bool IsNullable(Type t)
-    {
-      ValidationUtils.ArgumentNotNull(t, "t");
-
-      if (t.IsValueType)
-        return IsNullableType(t);
-
-      return true;
-    }
-
-    public static bool IsNullableType(Type t)
-    {
-      ValidationUtils.ArgumentNotNull(t, "t");
-
-      return (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>));
-    }
-
-    //public static bool IsValueTypeUnitializedValue(ValueType value)
-    //{
-    //  if (value == null)
-    //    return true;
-
-    //  return value.Equals(CreateUnitializedValue(value.GetType()));
-    //}
-
-    public static bool IsUnitializedValue(object value)
-    {
-      if (value == null)
-      {
-        return true;
-      }
-      else
-      {
-        object unitializedValue = CreateUnitializedValue(value.GetType());
-        return value.Equals(unitializedValue);
-      }
-    }
-
-    public static object CreateUnitializedValue(Type type)
-    {
-      ValidationUtils.ArgumentNotNull(type, "type");
-
-      if (type.IsGenericTypeDefinition)
-        throw new ArgumentException("Type {0} is a generic type definition and cannot be instantiated.".FormatWith(CultureInfo.InvariantCulture, type), "type");
-
-      if (type.IsClass || type.IsInterface || type == typeof(void))
-        return null;
-      else if (type.IsValueType)
-        return Activator.CreateInstance(type);
-      else
-        throw new ArgumentException("Type {0} cannot be instantiated.".FormatWith(CultureInfo.InvariantCulture, type), "type");
-    }
-
-    public static bool IsPropertyIndexed(PropertyInfo property)
-    {
-      ValidationUtils.ArgumentNotNull(property, "property");
-
-      return !CollectionUtils.IsNullOrEmpty<ParameterInfo>(property.GetIndexParameters());
-    }
-
-    public static bool ImplementsGenericDefinition(Type type, Type genericInterfaceDefinition)
-    {
-      Type implementingType;
-      return ImplementsGenericDefinition(type, genericInterfaceDefinition, out implementingType);
-    }
-
-    public static bool ImplementsGenericDefinition(Type type, Type genericInterfaceDefinition, out Type implementingType)
-    {
-      ValidationUtils.ArgumentNotNull(type, "type");
-      ValidationUtils.ArgumentNotNull(genericInterfaceDefinition, "genericInterfaceDefinition");
-
-      if (!genericInterfaceDefinition.IsInterface || !genericInterfaceDefinition.IsGenericTypeDefinition)
-        throw new ArgumentNullException("'{0}' is not a generic interface definition.".FormatWith(CultureInfo.InvariantCulture, genericInterfaceDefinition));
-
-      if (type.IsInterface)
-      {
-        if (type.IsGenericType)
-        {
-          Type interfaceDefinition = type.GetGenericTypeDefinition();
-
-          if (genericInterfaceDefinition == interfaceDefinition)
-          {
-            implementingType = type;
-            return true;
-          }
-        }
-      }
-
-      foreach (Type i in type.GetInterfaces())
-      {
-        if (i.IsGenericType)
-        {
-          Type interfaceDefinition = i.GetGenericTypeDefinition();
-
-          if (genericInterfaceDefinition == interfaceDefinition)
-          {
-            implementingType = i;
-            return true;
-          }
-        }
-      }
-
-      implementingType = null;
-      return false;
-    }
-
-    public static bool AssignableToTypeName(this Type type, string fullTypeName, out Type match)
-    {
-      Type current = type;
-
-      while (current != null)
-      {
-        if (string.Equals(current.FullName, fullTypeName, StringComparison.Ordinal))
-        {
-          match = current;
-          return true;
-        }
-
-        current = current.BaseType;
-      }
-
-      foreach (Type i in type.GetInterfaces())
-      {
-        if (string.Equals(i.Name, fullTypeName, StringComparison.Ordinal))
-        {
-          match = type;
-          return true;
-        }
-      }
-
-      match = null;
-      return false;
-    }
-
-    public static bool AssignableToTypeName(this Type type, string fullTypeName)
-    {
-      Type match;
-      return type.AssignableToTypeName(fullTypeName, out match);
-    }
-
-    public static bool InheritsGenericDefinition(Type type, Type genericClassDefinition)
-    {
-      Type implementingType;
-      return InheritsGenericDefinition(type, genericClassDefinition, out implementingType);
-    }
-
-    public static bool InheritsGenericDefinition(Type type, Type genericClassDefinition, out Type implementingType)
-    {
-      ValidationUtils.ArgumentNotNull(type, "type");
-      ValidationUtils.ArgumentNotNull(genericClassDefinition, "genericClassDefinition");
-
-      if (!genericClassDefinition.IsClass || !genericClassDefinition.IsGenericTypeDefinition)
-        throw new ArgumentNullException("'{0}' is not a generic class definition.".FormatWith(CultureInfo.InvariantCulture, genericClassDefinition));
-
-      return InheritsGenericDefinitionInternal(type, genericClassDefinition, out implementingType);
-    }
-
-    private static bool InheritsGenericDefinitionInternal(Type currentType, Type genericClassDefinition, out Type implementingType)
-    {
-      if (currentType.IsGenericType)
-      {
-        Type currentGenericClassDefinition = currentType.GetGenericTypeDefinition();
-
-        if (genericClassDefinition == currentGenericClassDefinition)
-        {
-          implementingType = currentType;
-          return true;
-        }
-      }
-
-      if (currentType.BaseType == null)
-      {
-        implementingType = null;
-        return false;
-      }
-
-      return InheritsGenericDefinitionInternal(currentType.BaseType, genericClassDefinition, out implementingType);
-    }
-
-    /// <summary>
-    /// Gets the type of the typed collection's items.
-    /// </summary>
-    /// <param name="type">The type.</param>
-    /// <returns>The type of the typed collection's items.</returns>
-    public static Type GetCollectionItemType(Type type)
-    {
-      ValidationUtils.ArgumentNotNull(type, "type");
-      Type genericListType;
-
-      if (type.IsArray)
-      {
-        return type.GetElementType();
-      }
-      else if (ImplementsGenericDefinition(type, typeof(IEnumerable<>), out genericListType))
-      {
-        if (genericListType.IsGenericTypeDefinition)
-          throw new Exception("Type {0} is not a collection.".FormatWith(CultureInfo.InvariantCulture, type));
-
-        return genericListType.GetGenericArguments()[0];
-      }
-      else if (typeof(IEnumerable).IsAssignableFrom(type))
-      {
-        return null;
-      }
-      else
-      {
-        throw new Exception("Type {0} is not a collection.".FormatWith(CultureInfo.InvariantCulture, type));
-      }
-    }
-
-    public static void GetDictionaryKeyValueTypes(Type dictionaryType, out Type keyType, out Type valueType)
-    {
-      ValidationUtils.ArgumentNotNull(dictionaryType, "type");
-
-      Type genericDictionaryType;
-      if (ImplementsGenericDefinition(dictionaryType, typeof(IDictionary<,>), out genericDictionaryType))
-      {
-        if (genericDictionaryType.IsGenericTypeDefinition)
-          throw new Exception("Type {0} is not a dictionary.".FormatWith(CultureInfo.InvariantCulture, dictionaryType));
-
-        Type[] dictionaryGenericArguments = genericDictionaryType.GetGenericArguments();
-
-        keyType = dictionaryGenericArguments[0];
-        valueType = dictionaryGenericArguments[1];
-        return;
-      }
-      else if (typeof(IDictionary).IsAssignableFrom(dictionaryType))
-      {
-        keyType = null;
-        valueType = null;
-        return;
-      }
-      else
-      {
-        throw new Exception("Type {0} is not a dictionary.".FormatWith(CultureInfo.InvariantCulture, dictionaryType));
-      }
-    }
-
-    public static Type GetDictionaryValueType(Type dictionaryType)
-    {
-      Type keyType;
-      Type valueType;
-      GetDictionaryKeyValueTypes(dictionaryType, out keyType, out valueType);
-
-      return valueType;
-    }
-
-    public static Type GetDictionaryKeyType(Type dictionaryType)
-    {
-      Type keyType;
-      Type valueType;
-      GetDictionaryKeyValueTypes(dictionaryType, out keyType, out valueType);
-
-      return keyType;
-    }
-
-    /// <summary>
-    /// Tests whether the list's items are their unitialized value.
-    /// </summary>
-    /// <param name="list">The list.</param>
-    /// <returns>Whether the list's items are their unitialized value</returns>
-    public static bool ItemsUnitializedValue<T>(IList<T> list)
-    {
-      ValidationUtils.ArgumentNotNull(list, "list");
-
-      Type elementType = GetCollectionItemType(list.GetType());
-
-      if (elementType.IsValueType)
-      {
-        object unitializedValue = CreateUnitializedValue(elementType);
-
-        for (int i = 0; i < list.Count; i++)
-        {
-          if (!list[i].Equals(unitializedValue))
-            return false;
-        }
-      }
-      else if (elementType.IsClass)
-      {
-        for (int i = 0; i < list.Count; i++)
-        {
-          object value = list[i];
-
-          if (value != null)
-            return false;
-        }
-      }
-      else
-      {
-        throw new Exception("Type {0} is neither a ValueType or a Class.".FormatWith(CultureInfo.InvariantCulture, elementType));
-      }
-
-      return true;
-    }
-
-    /// <summary>
-    /// Gets the member's underlying type.
-    /// </summary>
-    /// <param name="member">The member.</param>
-    /// <returns>The underlying type of the member.</returns>
-    public static Type GetMemberUnderlyingType(MemberInfo member)
-    {
-      ValidationUtils.ArgumentNotNull(member, "member");
-
-      switch (member.MemberType)
-      {
-        case MemberTypes.Field:
-          return ((FieldInfo)member).FieldType;
-        case MemberTypes.Property:
-          return ((PropertyInfo)member).PropertyType;
-        case MemberTypes.Event:
-          return ((EventInfo)member).EventHandlerType;
-        default:
-          throw new ArgumentException("MemberInfo must be of type FieldInfo, PropertyInfo or EventInfo", "member");
-      }
-    }
-
-    /// <summary>
-    /// Determines whether the member is an indexed property.
-    /// </summary>
-    /// <param name="member">The member.</param>
-    /// <returns>
-    /// 	<c>true</c> if the member is an indexed property; otherwise, <c>false</c>.
-    /// </returns>
-    public static bool IsIndexedProperty(MemberInfo member)
-    {
-      ValidationUtils.ArgumentNotNull(member, "member");
-
-      PropertyInfo propertyInfo = member as PropertyInfo;
-
-      if (propertyInfo != null)
-        return IsIndexedProperty(propertyInfo);
-      else
-        return false;
-    }
-
-    /// <summary>
-    /// Determines whether the property is an indexed property.
-    /// </summary>
-    /// <param name="property">The property.</param>
-    /// <returns>
-    /// 	<c>true</c> if the property is an indexed property; otherwise, <c>false</c>.
-    /// </returns>
-    public static bool IsIndexedProperty(PropertyInfo property)
-    {
-      ValidationUtils.ArgumentNotNull(property, "property");
-
-      return (property.GetIndexParameters().Length > 0);
-    }
-
-    /// <summary>
-    /// Gets the member's value on the object.
-    /// </summary>
-    /// <param name="member">The member.</param>
-    /// <param name="target">The target object.</param>
-    /// <returns>The member's value on the object.</returns>
-    public static object GetMemberValue(MemberInfo member, object target)
-    {
-      ValidationUtils.ArgumentNotNull(member, "member");
-      ValidationUtils.ArgumentNotNull(target, "target");
-
-      switch (member.MemberType)
-      {
-        case MemberTypes.Field:
-          return ((FieldInfo)member).GetValue(target);
-        case MemberTypes.Property:
-          try
-          {
-            return ((PropertyInfo)member).GetValue(target, null);
-          }
-          catch (TargetParameterCountException e)
-          {
-            throw new ArgumentException("MemberInfo '{0}' has index parameters".FormatWith(CultureInfo.InvariantCulture, member.Name), e);
-          }
-        default:
-          throw new ArgumentException("MemberInfo '{0}' is not of type FieldInfo or PropertyInfo".FormatWith(CultureInfo.InvariantCulture, CultureInfo.InvariantCulture, member.Name), "member");
-      }
-    }
-
-    /// <summary>
-    /// Sets the member's value on the target object.
-    /// </summary>
-    /// <param name="member">The member.</param>
-    /// <param name="target">The target.</param>
-    /// <param name="value">The value.</param>
-    public static void SetMemberValue(MemberInfo member, object target, object value)
-    {
-      ValidationUtils.ArgumentNotNull(member, "member");
-      ValidationUtils.ArgumentNotNull(target, "target");
-
-      switch (member.MemberType)
-      {
-        case MemberTypes.Field:
-          ((FieldInfo)member).SetValue(target, value);
-          break;
-        case MemberTypes.Property:
-          ((PropertyInfo)member).SetValue(target, value, null);
-          break;
-        default:
-          throw new ArgumentException("MemberInfo '{0}' must be of type FieldInfo or PropertyInfo".FormatWith(CultureInfo.InvariantCulture, member.Name), "member");
-      }
-    }
-
-    /// <summary>
-    /// Determines whether the specified MemberInfo can be read.
-    /// </summary>
-    /// <param name="member">The MemberInfo to determine whether can be read.</param>
-    /// /// <param name="nonPublic">if set to <c>true</c> then allow the member to be gotten non-publicly.</param>
-    /// <returns>
-    /// 	<c>true</c> if the specified MemberInfo can be read; otherwise, <c>false</c>.
-    /// </returns>
-    public static bool CanReadMemberValue(MemberInfo member, bool nonPublic)
-    {
-      switch (member.MemberType)
-      {
-        case MemberTypes.Field:
-          FieldInfo fieldInfo = (FieldInfo)member;
-
-          if (nonPublic)
-            return true;
-          else if (fieldInfo.IsPublic)
-            return true;
-          return false;
-        case MemberTypes.Property:
-          PropertyInfo propertyInfo = (PropertyInfo) member;
-
-          if (!propertyInfo.CanRead)
-            return false;
-          if (nonPublic)
-            return true;
-          return (propertyInfo.GetGetMethod(nonPublic) != null);
-        default:
-          return false;
-      }
-    }
-
-    /// <summary>
-    /// Determines whether the specified MemberInfo can be set.
-    /// </summary>
-    /// <param name="member">The MemberInfo to determine whether can be set.</param>
-    /// <param name="nonPublic">if set to <c>true</c> then allow the member to be set non-publicly.</param>
-    /// <returns>
-    /// 	<c>true</c> if the specified MemberInfo can be set; otherwise, <c>false</c>.
-    /// </returns>
-    public static bool CanSetMemberValue(MemberInfo member, bool nonPublic)
-    {
-      switch (member.MemberType)
-      {
-        case MemberTypes.Field:
-          FieldInfo fieldInfo = (FieldInfo)member;
-
-          if (fieldInfo.IsInitOnly)
-            return false;
-          if (nonPublic)
-            return true;
-          else if (fieldInfo.IsPublic)
-            return true;
-          return false;
-        case MemberTypes.Property:
-          PropertyInfo propertyInfo = (PropertyInfo)member;
-
-          if (!propertyInfo.CanWrite)
-            return false;
-          if (nonPublic)
-            return true;
-          return (propertyInfo.GetSetMethod(nonPublic) != null);
-        default:
-          return false;
-      }
-    }
-
-    public static List<MemberInfo> GetFieldsAndProperties<T>(BindingFlags bindingAttr)
-    {
-      return GetFieldsAndProperties(typeof(T), bindingAttr);
-    }
-
-    public static List<MemberInfo> GetFieldsAndProperties(Type type, BindingFlags bindingAttr)
-    {
-      List<MemberInfo> targetMembers = new List<MemberInfo>();
-
-      targetMembers.AddRange(GetFields(type, bindingAttr));
-      targetMembers.AddRange(GetProperties(type, bindingAttr));
-
-      // for some reason .NET returns multiple members when overriding a generic member on a base class
-      // http://forums.msdn.microsoft.com/en-US/netfxbcl/thread/b5abbfee-e292-4a64-8907-4e3f0fb90cd9/
-      // filter members to only return the override on the topmost class
-      // update: I think this is fixed in .NET 3.5 SP1 - leave this in for now...
-      List<MemberInfo> distinctMembers = new List<MemberInfo>(targetMembers.Count);
-
-      var groupedMembers = targetMembers.GroupBy(m => m.Name).Select(g => new { Count = g.Count(), Members = g.Cast<MemberInfo>() });
-      foreach (var groupedMember in groupedMembers)
-      {
-        if (groupedMember.Count == 1)
-        {
-          distinctMembers.Add(groupedMember.Members.First());
-        }
-        else
-        {
-          var members = groupedMember.Members.Where(m => !IsOverridenGenericMember(m, bindingAttr) || m.Name == "Item");
-
-          distinctMembers.AddRange(members);
-        }
-      }
-
-      return distinctMembers;
-    }
-
-    private static bool IsOverridenGenericMember(MemberInfo memberInfo, BindingFlags bindingAttr)
-    {
-      if (memberInfo.MemberType != MemberTypes.Field && memberInfo.MemberType != MemberTypes.Property)
-        throw new ArgumentException("Member must be a field or property.");
-
-      Type declaringType = memberInfo.DeclaringType;
-      if (!declaringType.IsGenericType)
-        return false;
-      Type genericTypeDefinition = declaringType.GetGenericTypeDefinition();
-      if (genericTypeDefinition == null)
-        return false;
-      MemberInfo[] members = genericTypeDefinition.GetMember(memberInfo.Name, bindingAttr);
-      if (members.Length == 0)
-        return false;
-      Type memberUnderlyingType = GetMemberUnderlyingType(members[0]);
-      if (!memberUnderlyingType.IsGenericParameter)
-        return false;
-
-      return true;
-    }
-
-    public static T GetAttribute<T>(ICustomAttributeProvider attributeProvider) where T : Attribute
-    {
-      return GetAttribute<T>(attributeProvider, true);
-    }
-
-    public static T GetAttribute<T>(ICustomAttributeProvider attributeProvider, bool inherit) where T : Attribute
-    {
-      T[] attributes = GetAttributes<T>(attributeProvider, inherit);
-
-      return CollectionUtils.GetSingleItem(attributes, true);
-    }
-
-    public static T[] GetAttributes<T>(ICustomAttributeProvider attributeProvider, bool inherit) where T : Attribute
-    {
-      ValidationUtils.ArgumentNotNull(attributeProvider, "attributeProvider");
-
-      // http://hyperthink.net/blog/getcustomattributes-gotcha/
-      // ICustomAttributeProvider doesn't do inheritance
-
-      if (attributeProvider is Assembly)
-        return (T[])Attribute.GetCustomAttributes((Assembly)attributeProvider, typeof(T), inherit);
-
-      if (attributeProvider is MemberInfo)
-        return (T[])Attribute.GetCustomAttributes((MemberInfo)attributeProvider, typeof(T), inherit);
-
-      if (attributeProvider is Module)
-        return (T[])Attribute.GetCustomAttributes((Module)attributeProvider, typeof(T), inherit);
-
-      if (attributeProvider is ParameterInfo)
-        return (T[])Attribute.GetCustomAttributes((ParameterInfo)attributeProvider, typeof(T), inherit);
-
-      return (T[])attributeProvider.GetCustomAttributes(typeof(T), inherit);
-    }
-
-    public static string GetNameAndAssessmblyName(Type t)
-    {
-      ValidationUtils.ArgumentNotNull(t, "t");
-
-      return t.FullName + ", " + t.Assembly.GetName().Name;
-    }
-
-    public static Type MakeGenericType(Type genericTypeDefinition, params Type[] innerTypes)
-    {
-      ValidationUtils.ArgumentNotNull(genericTypeDefinition, "genericTypeDefinition");
-      ValidationUtils.ArgumentNotNullOrEmpty<Type>(innerTypes, "innerTypes");
-      ValidationUtils.ArgumentConditionTrue(genericTypeDefinition.IsGenericTypeDefinition, "genericTypeDefinition", "Type {0} is not a generic type definition.".FormatWith(CultureInfo.InvariantCulture, genericTypeDefinition));
-
-      return genericTypeDefinition.MakeGenericType(innerTypes);
-    }
-
-    public static object CreateGeneric(Type genericTypeDefinition, Type innerType, params object[] args)
-    {
-      return CreateGeneric(genericTypeDefinition, new [] { innerType }, args);
-    }
-
-    public static object CreateGeneric(Type genericTypeDefinition, IList<Type> innerTypes, params object[] args)
-    {
-      return CreateGeneric(genericTypeDefinition, innerTypes, (t, a) => CreateInstance(t, a.ToArray()), args);
-    }
-
-    public static object CreateGeneric(Type genericTypeDefinition, IList<Type> innerTypes, Func<Type, IList<object>, object> instanceCreator, params object[] args)
-    {
-      ValidationUtils.ArgumentNotNull(genericTypeDefinition, "genericTypeDefinition");
-      ValidationUtils.ArgumentNotNullOrEmpty(innerTypes, "innerTypes");
-      ValidationUtils.ArgumentNotNull(instanceCreator, "createInstance");
-
-      Type specificType = MakeGenericType(genericTypeDefinition, innerTypes.ToArray());
-
-      return instanceCreator(specificType, args);
-    }
-
-    public static bool IsCompatibleValue(object value, Type type)
-    {
-      if (value == null)
-        return IsNullable(type);
-
-      if (type.IsAssignableFrom(value.GetType()))
-        return true;
-
-      return false;
-    }
-
-     public static object CreateInstance(Type type, params object[] args)
-     {
-       ValidationUtils.ArgumentNotNull(type, "type");
-
-#if !PocketPC
-       return Activator.CreateInstance(type, args);
-#else
-       // CF doesn't have a Activator.CreateInstance overload that takes args
-       // lame
-
-       if (type.IsValueType && CollectionUtils.IsNullOrEmpty<object>(args))
-         return Activator.CreateInstance(type);
-
-       ConstructorInfo[] constructors = type.GetConstructors();
-       ConstructorInfo match = constructors.Where(c =>
-         {
-           ParameterInfo[] parameters = c.GetParameters();
-           if (parameters.Length != args.Length)
-             return false;
-
-           for (int i = 0; i < parameters.Length; i++)
-           {
-             ParameterInfo parameter = parameters[i];
-             object value = args[i];
-
-             if (!IsCompatibleValue(value, parameter.ParameterType))
-               return false;
-           }
-
-           return true;
-         }).FirstOrDefault();
-
-       if (match == null)
-         throw new Exception("Could not create '{0}' with given parameters.".FormatWith(CultureInfo.InvariantCulture, type));
-
-       return match.Invoke(args);
-#endif
-     }
-
-    public static void SplitFullyQualifiedTypeName(string fullyQualifiedTypeName, out string typeName, out string assemblyName)
-    {
-      int? assemblyDelimiterIndex = GetAssemblyDelimiterIndex(fullyQualifiedTypeName);
-
-      if (assemblyDelimiterIndex != null)
-      {
-        typeName = fullyQualifiedTypeName.Substring(0, assemblyDelimiterIndex.Value).Trim();
-        assemblyName = fullyQualifiedTypeName.Substring(assemblyDelimiterIndex.Value + 1, fullyQualifiedTypeName.Length - assemblyDelimiterIndex.Value - 1).Trim();
-      }
-      else
-      {
-        typeName = fullyQualifiedTypeName;
-        assemblyName = null;
-      }
-
-    }
-
-    private static int? GetAssemblyDelimiterIndex(string fullyQualifiedTypeName)
-    {
-      // we need to get the first comma following all surrounded in brackets because of generic types
-      // e.g. System.Collections.Generic.Dictionary`2[[System.String, mscorlib,Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-      int scope = 0;
-      for (int i = 0; i < fullyQualifiedTypeName.Length; i++)
-      {
-        char current = fullyQualifiedTypeName[i];
-        switch (current)
-        {
-          case '[':
-            scope++;
-            break;
-          case ']':
-            scope--;
-            break;
-          case ',':
-            if (scope == 0)
-              return i;
-            break;
-        }
-      }
-
-      return null;
-    }
-
-    public static IEnumerable<FieldInfo> GetFields(Type targetType, BindingFlags bindingAttr)
-    {
-      ValidationUtils.ArgumentNotNull(targetType, "targetType");
-
-      List<MemberInfo> fieldInfos = new List<MemberInfo>(targetType.GetFields(bindingAttr));
-      // Type.GetFields doesn't return inherited private fields
-      // manually find private fields from base class
-      GetChildPrivateFields(fieldInfos, targetType, bindingAttr);
-
-      return fieldInfos.Cast<FieldInfo>();
-    }
-
-    private static void GetChildPrivateFields(IList<MemberInfo> initialFields, Type targetType, BindingFlags bindingAttr)
-    {
-      // fix weirdness with private FieldInfos only being returned for the current Type
-      // find base type fields and add them to result
-      if ((bindingAttr & BindingFlags.NonPublic) != 0)
-      {
-        // modify flags to not search for public fields
-        BindingFlags nonPublicBindingAttr = bindingAttr.RemoveFlag(BindingFlags.Public);
-
-        while ((targetType = targetType.BaseType) != null)
-        {
-          // filter out protected fields
-          IEnumerable<MemberInfo> childPrivateFields =
-            targetType.GetFields(nonPublicBindingAttr).Where(f => f.IsPrivate).Cast<MemberInfo>();
-
-          initialFields.AddRange(childPrivateFields);
-        }
-      }
-    }
-
-    public static IEnumerable<PropertyInfo> GetProperties(Type targetType, BindingFlags bindingAttr)
-    {
-      ValidationUtils.ArgumentNotNull(targetType, "targetType");
-
-      List<MemberInfo> propertyInfos = new List<MemberInfo>(targetType.GetProperties(bindingAttr));
-      GetChildPrivateProperties(propertyInfos, targetType, bindingAttr);
-
-      return propertyInfos.Cast<PropertyInfo>();
-    }
-
-    public static BindingFlags RemoveFlag(this BindingFlags bindingAttr, BindingFlags flag)
-    {
-      return ((bindingAttr & flag) == flag)
-        ? bindingAttr ^ flag
-        : bindingAttr;
-    }
-
-    private static void GetChildPrivateProperties(IList<MemberInfo> initialProperties, Type targetType, BindingFlags bindingAttr)
-    {
-      // fix weirdness with private PropertyInfos only being returned for the current Type
-      // find base type properties and add them to result
-      if ((bindingAttr & BindingFlags.NonPublic) != 0)
-      {
-        // modify flags to not search for public fields
-        BindingFlags nonPublicBindingAttr = bindingAttr.RemoveFlag(BindingFlags.Public);
-
-        while ((targetType = targetType.BaseType) != null)
-        {
-          foreach (PropertyInfo propertyInfo in targetType.GetProperties(nonPublicBindingAttr))
-          {
-            PropertyInfo nonPublicProperty = propertyInfo;
-
-            // have to test on name rather than reference because instances are different
-            // depending on the type that GetProperties was called on
-            int index = initialProperties.IndexOf(p => p.Name == nonPublicProperty.Name);
-            if (index == -1)
-            {
-              initialProperties.Add(nonPublicProperty);
-            }
-            else
-            {
-              // replace nonpublic properties for a child, but gotten from
-              // the parent with the one from the child
-              // the property gotten from the child will have access to private getter/setter
-              initialProperties[index] = nonPublicProperty;
-            }
-          }
-        }
-      }
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Collections;
+using System.Globalization;
+using System.Runtime.Serialization;
+using System.Runtime.Serialization.Formatters;
+using System.Text;
+#if NETFX_CORE
+using IConvertible = Newtonsoft.Json.Utilities.Convertible;
+#endif
+#if NETFX_CORE || PORTABLE
+using ICustomAttributeProvider = Newtonsoft.Json.Utilities.CustomAttributeProvider;
+#endif
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#else
+using System.Linq;
+#endif
+using Newtonsoft.Json.Serialization;
+
+namespace Newtonsoft.Json.Utilities
+{
+#if NETFX_CORE || PORTABLE
+  internal enum MemberTypes
+  {
+    Property,
+    Field,
+    Event,
+    Method,
+    Other
+  }
+
+  internal class CustomAttributeProvider
+  {
+    private readonly object _underlyingObject;
+
+    public CustomAttributeProvider(object o)
+    {
+      _underlyingObject = o;
+    }
+
+    public object UnderlyingObject
+    {
+      get { return _underlyingObject; }
+    }
+  }
+#endif
+
+#if NETFX_CORE
+  internal enum TypeCode
+  {
+    Empty,
+    Object,
+    String,
+    Char,
+    Boolean,
+    SByte,
+    Int16,
+    UInt16,
+    Int32,
+    Byte,
+    UInt32,
+    Int64,
+    UInt64,
+    Single,
+    Double,
+    DateTime,
+    Decimal
+  }
+
+  [Flags]
+  internal enum BindingFlags
+  {
+    Default = 0,
+    IgnoreCase = 1,
+    DeclaredOnly = 2,
+    Instance = 4,
+    Static = 8,
+    Public = 16,
+    NonPublic = 32,
+    FlattenHierarchy = 64,
+    InvokeMethod = 256,
+    CreateInstance = 512,
+    GetField = 1024,
+    SetField = 2048,
+    GetProperty = 4096,
+    SetProperty = 8192,
+    PutDispProperty = 16384,
+    ExactBinding = 65536,
+    PutRefDispProperty = 32768,
+    SuppressChangeType = 131072,
+    OptionalParamBinding = 262144,
+    IgnoreReturn = 16777216
+  }
+#endif
+
+  internal static class ReflectionUtils
+  {
+    public static readonly Type[] EmptyTypes;
+
+    static ReflectionUtils()
+    {
+#if !(NETFX_CORE || PORTABLE)
+      EmptyTypes = Type.EmptyTypes;
+#else
+      EmptyTypes = new Type[0];
+#endif
+    }
+
+    public static ICustomAttributeProvider GetCustomAttributeProvider(this object o)
+    {
+#if !(NETFX_CORE || PORTABLE)
+      return (ICustomAttributeProvider)o;
+#else
+      return new ICustomAttributeProvider(o);
+#endif
+    }
+
+    public static bool IsVirtual(this PropertyInfo propertyInfo)
+    {
+      ValidationUtils.ArgumentNotNull(propertyInfo, "propertyInfo");
+
+      MethodInfo m = propertyInfo.GetGetMethod();
+      if (m != null && m.IsVirtual)
+        return true;
+
+      m = propertyInfo.GetSetMethod();
+      if (m != null && m.IsVirtual)
+        return true;
+
+      return false;
+    }
+
+    public static Type GetObjectType(object v)
+    {
+      return (v != null) ? v.GetType() : null;
+    }
+
+    public static string GetTypeName(Type t, FormatterAssemblyStyle assemblyFormat)
+    {
+      return GetTypeName(t, assemblyFormat, null);
+    }
+
+    public static string GetTypeName(Type t, FormatterAssemblyStyle assemblyFormat, SerializationBinder binder)
+    {
+      string fullyQualifiedTypeName;
+#if !(NET20 || NET35)
+      if (binder != null)
+      {
+        string assemblyName, typeName;
+        binder.BindToName(t, out assemblyName, out typeName);
+        fullyQualifiedTypeName = typeName + (assemblyName == null ? "" : ", " + assemblyName);
+      }
+      else
+      {
+        fullyQualifiedTypeName = t.AssemblyQualifiedName;
+      }
+#else
+      fullyQualifiedTypeName = t.AssemblyQualifiedName;
+#endif
+
+      switch (assemblyFormat)
+      {
+        case FormatterAssemblyStyle.Simple:
+          return RemoveAssemblyDetails(fullyQualifiedTypeName);
+        case FormatterAssemblyStyle.Full:
+          return fullyQualifiedTypeName;
+        default:
+          throw new ArgumentOutOfRangeException();
+      }
+    }
+
+    private static string RemoveAssemblyDetails(string fullyQualifiedTypeName)
+    {
+      StringBuilder builder = new StringBuilder();
+
+      // loop through the type name and filter out qualified assembly details from nested type names
+      bool writingAssemblyName = false;
+      bool skippingAssemblyDetails = false;
+      for (int i = 0; i < fullyQualifiedTypeName.Length; i++)
+      {
+        char current = fullyQualifiedTypeName[i];
+        switch (current)
+        {
+          case '[':
+            writingAssemblyName = false;
+            skippingAssemblyDetails = false;
+            builder.Append(current);
+            break;
+          case ']':
+            writingAssemblyName = false;
+            skippingAssemblyDetails = false;
+            builder.Append(current);
+            break;
+          case ',':
+            if (!writingAssemblyName)
+            {
+              writingAssemblyName = true;
+              builder.Append(current);
+            }
+            else
+            {
+              skippingAssemblyDetails = true;
+            }
+            break;
+          default:
+            if (!skippingAssemblyDetails)
+              builder.Append(current);
+            break;
+        }
+      }
+
+      return builder.ToString();
+    }
+
+    public static bool IsInstantiatableType(Type t)
+    {
+      ValidationUtils.ArgumentNotNull(t, "t");
+
+      if (t.IsAbstract() || t.IsInterface() || t.IsArray || t.IsGenericTypeDefinition() || t == typeof(void))
+        return false;
+
+      if (!HasDefaultConstructor(t))
+        return false;
+
+      return true;
+    }
+
+    public static bool HasDefaultConstructor(Type t)
+    {
+      return HasDefaultConstructor(t, false);
+    }
+
+    public static bool HasDefaultConstructor(Type t, bool nonPublic)
+    {
+      ValidationUtils.ArgumentNotNull(t, "t");
+
+      if (t.IsValueType())
+        return true;
+
+      return (GetDefaultConstructor(t, nonPublic) != null);
+    }
+
+    public static ConstructorInfo GetDefaultConstructor(Type t)
+    {
+      return GetDefaultConstructor(t, false);
+    }
+
+    public static ConstructorInfo GetDefaultConstructor(Type t, bool nonPublic)
+    {
+      BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public;
+      if (nonPublic)
+        bindingFlags = bindingFlags | BindingFlags.NonPublic;
+
+      return t.GetConstructors(bindingFlags).SingleOrDefault(c => !c.GetParameters().Any());
+    }
+
+    public static bool IsNullable(Type t)
+    {
+      ValidationUtils.ArgumentNotNull(t, "t");
+
+      if (t.IsValueType())
+        return IsNullableType(t);
+
+      return true;
+    }
+
+    public static bool IsNullableType(Type t)
+    {
+      ValidationUtils.ArgumentNotNull(t, "t");
+
+      return (t.IsGenericType() && t.GetGenericTypeDefinition() == typeof(Nullable<>));
+    }
+
+    public static Type EnsureNotNullableType(Type t)
+    {
+      return (IsNullableType(t))
+        ? Nullable.GetUnderlyingType(t)
+        : t;
+    }
+
+    public static bool ImplementsGenericDefinition(Type type, Type genericInterfaceDefinition)
+    {
+      Type implementingType;
+      return ImplementsGenericDefinition(type, genericInterfaceDefinition, out implementingType);
+    }
+
+    public static bool ImplementsGenericDefinition(Type type, Type genericInterfaceDefinition, out Type implementingType)
+    {
+      ValidationUtils.ArgumentNotNull(type, "type");
+      ValidationUtils.ArgumentNotNull(genericInterfaceDefinition, "genericInterfaceDefinition");
+
+      if (!genericInterfaceDefinition.IsInterface() || !genericInterfaceDefinition.IsGenericTypeDefinition())
+        throw new ArgumentNullException("'{0}' is not a generic interface definition.".FormatWith(CultureInfo.InvariantCulture, genericInterfaceDefinition));
+
+      if (type.IsInterface())
+      {
+        if (type.IsGenericType())
+        {
+          Type interfaceDefinition = type.GetGenericTypeDefinition();
+
+          if (genericInterfaceDefinition == interfaceDefinition)
+          {
+            implementingType = type;
+            return true;
+          }
+        }
+      }
+
+      foreach (Type i in type.GetInterfaces())
+      {
+        if (i.IsGenericType())
+        {
+          Type interfaceDefinition = i.GetGenericTypeDefinition();
+
+          if (genericInterfaceDefinition == interfaceDefinition)
+          {
+            implementingType = i;
+            return true;
+          }
+        }
+      }
+
+      implementingType = null;
+      return false;
+    }
+
+    public static bool InheritsGenericDefinition(Type type, Type genericClassDefinition)
+    {
+      Type implementingType;
+      return InheritsGenericDefinition(type, genericClassDefinition, out implementingType);
+    }
+
+    public static bool InheritsGenericDefinition(Type type, Type genericClassDefinition, out Type implementingType)
+    {
+      ValidationUtils.ArgumentNotNull(type, "type");
+      ValidationUtils.ArgumentNotNull(genericClassDefinition, "genericClassDefinition");
+
+      if (!genericClassDefinition.IsClass() || !genericClassDefinition.IsGenericTypeDefinition())
+        throw new ArgumentNullException("'{0}' is not a generic class definition.".FormatWith(CultureInfo.InvariantCulture, genericClassDefinition));
+
+      return InheritsGenericDefinitionInternal(type, genericClassDefinition, out implementingType);
+    }
+
+    private static bool InheritsGenericDefinitionInternal(Type currentType, Type genericClassDefinition, out Type implementingType)
+    {
+      if (currentType.IsGenericType())
+      {
+        Type currentGenericClassDefinition = currentType.GetGenericTypeDefinition();
+
+        if (genericClassDefinition == currentGenericClassDefinition)
+        {
+          implementingType = currentType;
+          return true;
+        }
+      }
+
+      if (currentType.BaseType() == null)
+      {
+        implementingType = null;
+        return false;
+      }
+
+      return InheritsGenericDefinitionInternal(currentType.BaseType(), genericClassDefinition, out implementingType);
+    }
+
+    /// <summary>
+    /// Gets the type of the typed collection's items.
+    /// </summary>
+    /// <param name="type">The type.</param>
+    /// <returns>The type of the typed collection's items.</returns>
+    public static Type GetCollectionItemType(Type type)
+    {
+      ValidationUtils.ArgumentNotNull(type, "type");
+      Type genericListType;
+
+      if (type.IsArray)
+      {
+        return type.GetElementType();
+      }
+      else if (ImplementsGenericDefinition(type, typeof(IEnumerable<>), out genericListType))
+      {
+        if (genericListType.IsGenericTypeDefinition())
+          throw new Exception("Type {0} is not a collection.".FormatWith(CultureInfo.InvariantCulture, type));
+
+        return genericListType.GetGenericArguments()[0];
+      }
+      else if (typeof(IEnumerable).IsAssignableFrom(type))
+      {
+        return null;
+      }
+      else
+      {
+        throw new Exception("Type {0} is not a collection.".FormatWith(CultureInfo.InvariantCulture, type));
+      }
+    }
+
+    public static void GetDictionaryKeyValueTypes(Type dictionaryType, out Type keyType, out Type valueType)
+    {
+      ValidationUtils.ArgumentNotNull(dictionaryType, "type");
+
+      Type genericDictionaryType;
+      if (ImplementsGenericDefinition(dictionaryType, typeof(IDictionary<,>), out genericDictionaryType))
+      {
+        if (genericDictionaryType.IsGenericTypeDefinition())
+          throw new Exception("Type {0} is not a dictionary.".FormatWith(CultureInfo.InvariantCulture, dictionaryType));
+
+        Type[] dictionaryGenericArguments = genericDictionaryType.GetGenericArguments();
+
+        keyType = dictionaryGenericArguments[0];
+        valueType = dictionaryGenericArguments[1];
+        return;
+      }
+      else if (typeof(IDictionary).IsAssignableFrom(dictionaryType))
+      {
+        keyType = null;
+        valueType = null;
+        return;
+      }
+      else
+      {
+        throw new Exception("Type {0} is not a dictionary.".FormatWith(CultureInfo.InvariantCulture, dictionaryType));
+      }
+    }
+
+    public static Type GetDictionaryValueType(Type dictionaryType)
+    {
+      Type keyType;
+      Type valueType;
+      GetDictionaryKeyValueTypes(dictionaryType, out keyType, out valueType);
+
+      return valueType;
+    }
+
+    public static Type GetDictionaryKeyType(Type dictionaryType)
+    {
+      Type keyType;
+      Type valueType;
+      GetDictionaryKeyValueTypes(dictionaryType, out keyType, out valueType);
+
+      return keyType;
+    }
+
+    /// <summary>
+    /// Gets the member's underlying type.
+    /// </summary>
+    /// <param name="member">The member.</param>
+    /// <returns>The underlying type of the member.</returns>
+    public static Type GetMemberUnderlyingType(MemberInfo member)
+    {
+      ValidationUtils.ArgumentNotNull(member, "member");
+
+      switch (member.MemberType())
+      {
+        case MemberTypes.Field:
+          return ((FieldInfo)member).FieldType;
+        case MemberTypes.Property:
+          return ((PropertyInfo)member).PropertyType;
+        case MemberTypes.Event:
+          return ((EventInfo)member).EventHandlerType;
+        default:
+          throw new ArgumentException("MemberInfo must be of type FieldInfo, PropertyInfo or EventInfo", "member");
+      }
+    }
+
+    /// <summary>
+    /// Determines whether the member is an indexed property.
+    /// </summary>
+    /// <param name="member">The member.</param>
+    /// <returns>
+    /// 	<c>true</c> if the member is an indexed property; otherwise, <c>false</c>.
+    /// </returns>
+    public static bool IsIndexedProperty(MemberInfo member)
+    {
+      ValidationUtils.ArgumentNotNull(member, "member");
+
+      PropertyInfo propertyInfo = member as PropertyInfo;
+
+      if (propertyInfo != null)
+        return IsIndexedProperty(propertyInfo);
+      else
+        return false;
+    }
+
+    /// <summary>
+    /// Determines whether the property is an indexed property.
+    /// </summary>
+    /// <param name="property">The property.</param>
+    /// <returns>
+    /// 	<c>true</c> if the property is an indexed property; otherwise, <c>false</c>.
+    /// </returns>
+    public static bool IsIndexedProperty(PropertyInfo property)
+    {
+      ValidationUtils.ArgumentNotNull(property, "property");
+
+      return (property.GetIndexParameters().Length > 0);
+    }
+
+    /// <summary>
+    /// Gets the member's value on the object.
+    /// </summary>
+    /// <param name="member">The member.</param>
+    /// <param name="target">The target object.</param>
+    /// <returns>The member's value on the object.</returns>
+    public static object GetMemberValue(MemberInfo member, object target)
+    {
+      ValidationUtils.ArgumentNotNull(member, "member");
+      ValidationUtils.ArgumentNotNull(target, "target");
+
+      switch (member.MemberType())
+      {
+        case MemberTypes.Field:
+          return ((FieldInfo)member).GetValue(target);
+        case MemberTypes.Property:
+          try
+          {
+            return ((PropertyInfo)member).GetValue(target, null);
+          }
+          catch (TargetParameterCountException e)
+          {
+            throw new ArgumentException("MemberInfo '{0}' has index parameters".FormatWith(CultureInfo.InvariantCulture, member.Name), e);
+          }
+        default:
+          throw new ArgumentException("MemberInfo '{0}' is not of type FieldInfo or PropertyInfo".FormatWith(CultureInfo.InvariantCulture, CultureInfo.InvariantCulture, member.Name), "member");
+      }
+    }
+
+    /// <summary>
+    /// Sets the member's value on the target object.
+    /// </summary>
+    /// <param name="member">The member.</param>
+    /// <param name="target">The target.</param>
+    /// <param name="value">The value.</param>
+    public static void SetMemberValue(MemberInfo member, object target, object value)
+    {
+      ValidationUtils.ArgumentNotNull(member, "member");
+      ValidationUtils.ArgumentNotNull(target, "target");
+
+      switch (member.MemberType())
+      {
+        case MemberTypes.Field:
+          ((FieldInfo)member).SetValue(target, value);
+          break;
+        case MemberTypes.Property:
+          ((PropertyInfo)member).SetValue(target, value, null);
+          break;
+        default:
+          throw new ArgumentException("MemberInfo '{0}' must be of type FieldInfo or PropertyInfo".FormatWith(CultureInfo.InvariantCulture, member.Name), "member");
+      }
+    }
+
+    /// <summary>
+    /// Determines whether the specified MemberInfo can be read.
+    /// </summary>
+    /// <param name="member">The MemberInfo to determine whether can be read.</param>
+    /// /// <param name="nonPublic">if set to <c>true</c> then allow the member to be gotten non-publicly.</param>
+    /// <returns>
+    /// 	<c>true</c> if the specified MemberInfo can be read; otherwise, <c>false</c>.
+    /// </returns>
+    public static bool CanReadMemberValue(MemberInfo member, bool nonPublic)
+    {
+      switch (member.MemberType())
+      {
+        case MemberTypes.Field:
+          FieldInfo fieldInfo = (FieldInfo)member;
+
+          if (nonPublic)
+            return true;
+          else if (fieldInfo.IsPublic)
+            return true;
+          return false;
+        case MemberTypes.Property:
+          PropertyInfo propertyInfo = (PropertyInfo) member;
+
+          if (!propertyInfo.CanRead)
+            return false;
+          if (nonPublic)
+            return true;
+          return (propertyInfo.GetGetMethod(nonPublic) != null);
+        default:
+          return false;
+      }
+    }
+
+    /// <summary>
+    /// Determines whether the specified MemberInfo can be set.
+    /// </summary>
+    /// <param name="member">The MemberInfo to determine whether can be set.</param>
+    /// <param name="nonPublic">if set to <c>true</c> then allow the member to be set non-publicly.</param>
+    /// <param name="canSetReadOnly">if set to <c>true</c> then allow the member to be set if read-only.</param>
+    /// <returns>
+    /// 	<c>true</c> if the specified MemberInfo can be set; otherwise, <c>false</c>.
+    /// </returns>
+    public static bool CanSetMemberValue(MemberInfo member, bool nonPublic, bool canSetReadOnly)
+    {
+      switch (member.MemberType())
+      {
+        case MemberTypes.Field:
+          FieldInfo fieldInfo = (FieldInfo)member;
+
+          if (fieldInfo.IsInitOnly && !canSetReadOnly)
+            return false;
+          if (nonPublic)
+            return true;
+          else if (fieldInfo.IsPublic)
+            return true;
+          return false;
+        case MemberTypes.Property:
+          PropertyInfo propertyInfo = (PropertyInfo)member;
+
+          if (!propertyInfo.CanWrite)
+            return false;
+          if (nonPublic)
+            return true;
+          return (propertyInfo.GetSetMethod(nonPublic) != null);
+        default:
+          return false;
+      }
+    }
+
+    public static List<MemberInfo> GetFieldsAndProperties(Type type, BindingFlags bindingAttr)
+    {
+      List<MemberInfo> targetMembers = new List<MemberInfo>();
+
+      targetMembers.AddRange(GetFields(type, bindingAttr));
+      targetMembers.AddRange(GetProperties(type, bindingAttr));
+
+      // for some reason .NET returns multiple members when overriding a generic member on a base class
+      // http://forums.msdn.microsoft.com/en-US/netfxbcl/thread/b5abbfee-e292-4a64-8907-4e3f0fb90cd9/
+      // filter members to only return the override on the topmost class
+      // update: I think this is fixed in .NET 3.5 SP1 - leave this in for now...
+      List<MemberInfo> distinctMembers = new List<MemberInfo>(targetMembers.Count);
+
+      foreach (var groupedMember in targetMembers.GroupBy(m => m.Name))
+      {
+        int count = groupedMember.Count();
+        IList<MemberInfo> members = groupedMember.ToList();
+
+        if (count == 1)
+        {
+          distinctMembers.Add(members.First());
+        }
+        else
+        {
+          var resolvedMembers = members.Where(m => !IsOverridenGenericMember(m, bindingAttr) || m.Name == "Item");
+
+          distinctMembers.AddRange(resolvedMembers);
+        }
+      }
+
+      return distinctMembers;
+    }
+
+
+    private static bool IsOverridenGenericMember(MemberInfo memberInfo, BindingFlags bindingAttr)
+    {
+      MemberTypes memberType = memberInfo.MemberType();
+      if (memberType != MemberTypes.Field && memberType != MemberTypes.Property)
+        throw new ArgumentException("Member must be a field or property.");
+
+      Type declaringType = memberInfo.DeclaringType;
+      if (!declaringType.IsGenericType())
+        return false;
+      Type genericTypeDefinition = declaringType.GetGenericTypeDefinition();
+      if (genericTypeDefinition == null)
+        return false;
+      MemberInfo[] members = genericTypeDefinition.GetMember(memberInfo.Name, bindingAttr);
+      if (members.Length == 0)
+        return false;
+      Type memberUnderlyingType = GetMemberUnderlyingType(members[0]);
+      if (!memberUnderlyingType.IsGenericParameter)
+        return false;
+
+      return true;
+    }
+
+    public static T GetAttribute<T>(ICustomAttributeProvider attributeProvider) where T : Attribute
+    {
+      return GetAttribute<T>(attributeProvider, true);
+    }
+
+    public static T GetAttribute<T>(ICustomAttributeProvider attributeProvider, bool inherit) where T : Attribute
+    {
+      T[] attributes = GetAttributes<T>(attributeProvider, inherit);
+
+      return attributes.SingleOrDefault();
+    }
+
+#if !(NETFX_CORE)
+    public static T[] GetAttributes<T>(ICustomAttributeProvider attributeProvider, bool inherit) where T : Attribute
+    {
+      ValidationUtils.ArgumentNotNull(attributeProvider, "attributeProvider");
+
+      object provider;
+
+#if !PORTABLE
+      provider = attributeProvider;
+#else
+      provider = attributeProvider.UnderlyingObject;
+#endif
+
+      // http://hyperthink.net/blog/getcustomattributes-gotcha/
+      // ICustomAttributeProvider doesn't do inheritance
+
+      if (provider is Type)
+        return (T[])((Type)provider).GetCustomAttributes(typeof(T), inherit);
+
+      if (provider is Assembly)
+        return (T[])Attribute.GetCustomAttributes((Assembly)provider, typeof(T));
+
+      if (provider is MemberInfo)
+        return (T[])Attribute.GetCustomAttributes((MemberInfo)provider, typeof(T), inherit);
+
+#if !PORTABLE
+      if (provider is Module)
+        return (T[])Attribute.GetCustomAttributes((Module)provider, typeof(T), inherit);
+#endif
+
+      if (provider is ParameterInfo)
+        return (T[])Attribute.GetCustomAttributes((ParameterInfo)provider, typeof(T), inherit);
+
+#if !PORTABLE
+      return (T[])attributeProvider.GetCustomAttributes(typeof(T), inherit);
+#else
+      throw new Exception("Cannot get attributes from '{0}'.".FormatWith(CultureInfo.InvariantCulture, provider));
+#endif
+    }
+#else
+    public static T[] GetAttributes<T>(ICustomAttributeProvider attributeProvider, bool inherit) where T : Attribute
+    {
+      object provider = attributeProvider.UnderlyingObject;
+
+      if (provider is Type)
+        return ((Type)provider).GetTypeInfo().GetCustomAttributes<T>(inherit).ToArray();
+
+      if (provider is Assembly)
+        return ((Assembly)provider).GetCustomAttributes<T>().ToArray();
+
+      if (provider is MemberInfo)
+        return ((MemberInfo)provider).GetCustomAttributes<T>(inherit).ToArray();
+
+      if (provider is Module)
+        return ((Module)provider).GetCustomAttributes<T>().ToArray();
+
+      if (provider is ParameterInfo)
+        return ((ParameterInfo)provider).GetCustomAttributes<T>(inherit).ToArray();
+
+      throw new Exception("Cannot get attributes from '{0}'.".FormatWith(CultureInfo.InvariantCulture, provider));
+    }
+#endif
+
+    public static Type MakeGenericType(Type genericTypeDefinition, params Type[] innerTypes)
+    {
+      ValidationUtils.ArgumentNotNull(genericTypeDefinition, "genericTypeDefinition");
+      ValidationUtils.ArgumentNotNullOrEmpty<Type>(innerTypes, "innerTypes");
+      ValidationUtils.ArgumentConditionTrue(genericTypeDefinition.IsGenericTypeDefinition(), "genericTypeDefinition", "Type {0} is not a generic type definition.".FormatWith(CultureInfo.InvariantCulture, genericTypeDefinition));
+
+      return genericTypeDefinition.MakeGenericType(innerTypes);
+    }
+
+    public static object CreateGeneric(Type genericTypeDefinition, Type innerType, params object[] args)
+    {
+      return CreateGeneric(genericTypeDefinition, new [] { innerType }, args);
+    }
+
+    public static object CreateGeneric(Type genericTypeDefinition, IList<Type> innerTypes, params object[] args)
+    {
+      return CreateGeneric(genericTypeDefinition, innerTypes, (t, a) => CreateInstance(t, a.ToArray()), args);
+    }
+
+    public static object CreateGeneric(Type genericTypeDefinition, IList<Type> innerTypes, Func<Type, IList<object>, object> instanceCreator, params object[] args)
+    {
+      ValidationUtils.ArgumentNotNull(genericTypeDefinition, "genericTypeDefinition");
+      ValidationUtils.ArgumentNotNullOrEmpty(innerTypes, "innerTypes");
+      ValidationUtils.ArgumentNotNull(instanceCreator, "createInstance");
+
+      Type specificType = MakeGenericType(genericTypeDefinition, innerTypes.ToArray());
+
+      return instanceCreator(specificType, args);
+    }
+
+     public static object CreateInstance(Type type, params object[] args)
+     {
+       ValidationUtils.ArgumentNotNull(type, "type");
+
+#if !PocketPC
+       return Activator.CreateInstance(type, args);
+#else
+       // CF doesn't have a Activator.CreateInstance overload that takes args
+       // lame
+
+       if (type.IsValueType && CollectionUtils.IsNullOrEmpty<object>(args))
+         return Activator.CreateInstance(type);
+
+       ConstructorInfo[] constructors = type.GetConstructors();
+       ConstructorInfo match = constructors.Where(c =>
+         {
+           ParameterInfo[] parameters = c.GetParameters();
+           if (parameters.Length != args.Length)
+             return false;
+
+           for (int i = 0; i < parameters.Length; i++)
+           {
+             ParameterInfo parameter = parameters[i];
+             object value = args[i];
+
+             if (!IsCompatibleValue(value, parameter.ParameterType))
+               return false;
+           }
+
+           return true;
+         }).FirstOrDefault();
+
+       if (match == null)
+         throw new Exception("Could not create '{0}' with given parameters.".FormatWith(CultureInfo.InvariantCulture, type));
+
+       return match.Invoke(args);
+#endif
+     }
+
+    public static void SplitFullyQualifiedTypeName(string fullyQualifiedTypeName, out string typeName, out string assemblyName)
+    {
+      int? assemblyDelimiterIndex = GetAssemblyDelimiterIndex(fullyQualifiedTypeName);
+
+      if (assemblyDelimiterIndex != null)
+      {
+        typeName = fullyQualifiedTypeName.Substring(0, assemblyDelimiterIndex.Value).Trim();
+        assemblyName = fullyQualifiedTypeName.Substring(assemblyDelimiterIndex.Value + 1, fullyQualifiedTypeName.Length - assemblyDelimiterIndex.Value - 1).Trim();
+      }
+      else
+      {
+        typeName = fullyQualifiedTypeName;
+        assemblyName = null;
+      }
+
+    }
+
+    private static int? GetAssemblyDelimiterIndex(string fullyQualifiedTypeName)
+    {
+      // we need to get the first comma following all surrounded in brackets because of generic types
+      // e.g. System.Collections.Generic.Dictionary`2[[System.String, mscorlib,Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+      int scope = 0;
+      for (int i = 0; i < fullyQualifiedTypeName.Length; i++)
+      {
+        char current = fullyQualifiedTypeName[i];
+        switch (current)
+        {
+          case '[':
+            scope++;
+            break;
+          case ']':
+            scope--;
+            break;
+          case ',':
+            if (scope == 0)
+              return i;
+            break;
+        }
+      }
+
+      return null;
+    }
+
+    public static MemberInfo GetMemberInfoFromType(Type targetType, MemberInfo memberInfo)
+    {
+      const BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
+
+      switch (memberInfo.MemberType())
+      {
+        case MemberTypes.Property:
+          PropertyInfo propertyInfo = (PropertyInfo) memberInfo;
+
+          Type[] types = propertyInfo.GetIndexParameters().Select(p => p.ParameterType).ToArray();
+
+          return targetType.GetProperty(propertyInfo.Name, bindingAttr, null, propertyInfo.PropertyType, types, null);
+        default:
+          return targetType.GetMember(memberInfo.Name, memberInfo.MemberType(), bindingAttr).SingleOrDefault();
+      }
+    }
+
+    public static IEnumerable<FieldInfo> GetFields(Type targetType, BindingFlags bindingAttr)
+    {
+      ValidationUtils.ArgumentNotNull(targetType, "targetType");
+
+      List<MemberInfo> fieldInfos = new List<MemberInfo>(targetType.GetFields(bindingAttr));
+#if !NETFX_CORE
+      // Type.GetFields doesn't return inherited private fields
+      // manually find private fields from base class
+      GetChildPrivateFields(fieldInfos, targetType, bindingAttr);
+#endif
+
+      return fieldInfos.Cast<FieldInfo>();
+    }
+
+    private static void GetChildPrivateFields(IList<MemberInfo> initialFields, Type targetType, BindingFlags bindingAttr)
+    {
+      // fix weirdness with private FieldInfos only being returned for the current Type
+      // find base type fields and add them to result
+      if ((bindingAttr & BindingFlags.NonPublic) != 0)
+      {
+        // modify flags to not search for public fields
+        BindingFlags nonPublicBindingAttr = bindingAttr.RemoveFlag(BindingFlags.Public);
+
+        while ((targetType = targetType.BaseType()) != null)
+        {
+          // filter out protected fields
+          IEnumerable<MemberInfo> childPrivateFields =
+            targetType.GetFields(nonPublicBindingAttr).Where(f => f.IsPrivate).Cast<MemberInfo>();
+
+          initialFields.AddRange(childPrivateFields);
+        }
+      }
+    }
+
+    public static IEnumerable<PropertyInfo> GetProperties(Type targetType, BindingFlags bindingAttr)
+    {
+      ValidationUtils.ArgumentNotNull(targetType, "targetType");
+
+      List<PropertyInfo> propertyInfos = new List<PropertyInfo>(targetType.GetProperties(bindingAttr));
+      GetChildPrivateProperties(propertyInfos, targetType, bindingAttr);
+
+      // a base class private getter/setter will be inaccessable unless the property was gotten from the base class
+      for (int i = 0; i < propertyInfos.Count; i++)
+      {
+        PropertyInfo member = propertyInfos[i];
+        if (member.DeclaringType != targetType)
+        {
+          PropertyInfo declaredMember = (PropertyInfo)GetMemberInfoFromType(member.DeclaringType, member);
+          propertyInfos[i] = declaredMember;
+        }
+      }
+
+      return propertyInfos;
+    }
+
+    public static BindingFlags RemoveFlag(this BindingFlags bindingAttr, BindingFlags flag)
+    {
+      return ((bindingAttr & flag) == flag)
+        ? bindingAttr ^ flag
+        : bindingAttr;
+    }
+
+    private static void GetChildPrivateProperties(IList<PropertyInfo> initialProperties, Type targetType, BindingFlags bindingAttr)
+    {
+      // fix weirdness with private PropertyInfos only being returned for the current Type
+      // find base type properties and add them to result
+      if ((bindingAttr & BindingFlags.NonPublic) != 0)
+      {
+        // modify flags to not search for public fields
+        BindingFlags nonPublicBindingAttr = bindingAttr.RemoveFlag(BindingFlags.Public);
+
+        while ((targetType = targetType.BaseType()) != null)
+        {
+          foreach (PropertyInfo propertyInfo in targetType.GetProperties(nonPublicBindingAttr))
+          {
+            PropertyInfo nonPublicProperty = propertyInfo;
+
+            // have to test on name rather than reference because instances are different
+            // depending on the type that GetProperties was called on
+            int index = initialProperties.IndexOf(p => p.Name == nonPublicProperty.Name);
+            if (index == -1)
+            {
+              initialProperties.Add(nonPublicProperty);
+            }
+            else
+            {
+              // replace nonpublic properties for a child, but gotten from
+              // the parent with the one from the child
+              // the property gotten from the child will have access to private getter/setter
+              initialProperties[index] = nonPublicProperty;
+            }
+          }
+        }
+      }
+    }
+
+    public static bool IsMethodOverridden(Type currentType, Type methodDeclaringType, string method)
+    {
+      bool isMethodOverriden = currentType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
+        .Any(info =>
+             info.Name == method &&
+             // check that the method overrides the original on DynamicObjectProxy
+             info.DeclaringType != methodDeclaringType
+             // todo - find out whether there is a way to do this in winrt
+#if !NETFX_CORE
+             && info.GetBaseDefinition().DeclaringType == methodDeclaringType
+#endif
+        );
+
+      return isMethodOverriden;
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/StringBuffer.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/StringBuffer.cs
index 747e6d0..0b28fc3 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/StringBuffer.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/StringBuffer.cs
@@ -1,99 +1,107 @@
-#region License
-// 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.
-#endregion
-
-using System;
-
-namespace Newtonsoft.Json.Utilities
-{
-  /// <summary>
-  /// Builds a string. Unlike StringBuilder this class lets you reuse it's internal buffer.
-  /// </summary>
-  internal class StringBuffer
-  {
-    private char[] _buffer;
-    private int _position;
-
-    private static readonly char[] _emptyBuffer = new char[0];
-
-    public int Position
-    {
-      get { return _position; }
-      set { _position = value; }
-    }
-
-    public StringBuffer()
-    {
-      _buffer = _emptyBuffer;
-    }
-
-    public StringBuffer(int initalSize)
-    {
-      _buffer = new char[initalSize];
-    }
-
-    public void Append(char value)
-    {
-      // test if the buffer array is large enough to take the value
-      if (_position == _buffer.Length)
-      {
-        EnsureSize(1);
-      }
-
-      // set value and increment poisition
-      _buffer[_position++] = value;
-    }
-
-    public void Clear()
-    {
-      _buffer = _emptyBuffer;
-      _position = 0;
-    }
-
-    private void EnsureSize(int appendLength)
-    {
-      char[] newBuffer = new char[(_position + appendLength) * 2];
-
-      Array.Copy(_buffer, newBuffer, _position);
-
-      _buffer = newBuffer;
-    }
-
-    public override string ToString()
-    {
-      return ToString(0, _position);
-    }
-
-    public string ToString(int start, int length)
-    {
-      // TODO: validation
-      return new string(_buffer, start, length);
-    }
-
-    public char[] GetInternalBuffer()
-    {
-      return _buffer;
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json.Utilities
+{
+  /// <summary>
+  /// Builds a string. Unlike StringBuilder this class lets you reuse it's internal buffer.
+  /// </summary>
+  internal class StringBuffer
+  {
+    private char[] _buffer;
+    private int _position;
+
+    private static readonly char[] EmptyBuffer = new char[0];
+
+    public int Position
+    {
+      get { return _position; }
+      set { _position = value; }
+    }
+
+    public StringBuffer()
+    {
+      _buffer = EmptyBuffer;
+    }
+
+    public StringBuffer(int initalSize)
+    {
+      _buffer = new char[initalSize];
+    }
+
+    public void Append(char value)
+    {
+      // test if the buffer array is large enough to take the value
+      if (_position == _buffer.Length)
+        EnsureSize(1);
+
+      // set value and increment poisition
+      _buffer[_position++] = value;
+    }
+
+    public void Append(char[] buffer, int startIndex, int count)
+    {
+      if (_position + count >= _buffer.Length)
+        EnsureSize(count);
+
+      Array.Copy(buffer, startIndex, _buffer, _position, count);
+
+      _position += count;
+    }
+
+    public void Clear()
+    {
+      _buffer = EmptyBuffer;
+      _position = 0;
+    }
+
+    private void EnsureSize(int appendLength)
+    {
+      char[] newBuffer = new char[(_position + appendLength) * 2];
+
+      Array.Copy(_buffer, newBuffer, _position);
+
+      _buffer = newBuffer;
+    }
+
+    public override string ToString()
+    {
+      return ToString(0, _position);
+    }
+
+    public string ToString(int start, int length)
+    {
+      // TODO: validation
+      return new string(_buffer, start, length);
+    }
+
+    public char[] GetInternalBuffer()
+    {
+      return _buffer;
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/StringReference.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/StringReference.cs
new file mode 100644
index 0000000..a4a9f2e
--- /dev/null
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/StringReference.cs
@@ -0,0 +1,61 @@
+#region License
+// 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.
+#endregion
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal struct StringReference
+  {
+    private readonly char[] _chars;
+    private readonly int _startIndex;
+    private readonly int _length;
+
+    public char[] Chars
+    {
+      get { return _chars; }
+    }
+
+    public int StartIndex
+    {
+      get { return _startIndex; }
+    }
+
+    public int Length
+    {
+      get { return _length; }
+    }
+
+    public StringReference(char[] chars, int startIndex, int length)
+    {
+      _chars = chars;
+      _startIndex = startIndex;
+      _length = length;
+    }
+
+    public override string ToString()
+    {
+      return new string(_chars, _startIndex, _length);
+    }
+  }
+}
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/StringUtils.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/StringUtils.cs
index df5b7ee..9e82479 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/StringUtils.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/StringUtils.cs
@@ -1,373 +1,189 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Linq;
-using System.Globalization;
-
-namespace Newtonsoft.Json.Utilities
-{
-  internal static class StringUtils
-  {
-    public const string CarriageReturnLineFeed = "\r\n";
-    public const string Empty = "";
-    public const char CarriageReturn = '\r';
-    public const char LineFeed = '\n';
-    public const char Tab = '\t';
-
-    //public static string FormatWith(this string format, params object[] args)
-    //{
-    //  return FormatWith(format, null, args);
-    //}
-
-    public static string FormatWith(this string format, IFormatProvider provider, params object[] args)
-    {
-      ValidationUtils.ArgumentNotNull(format, "format");
-
-      return string.Format(provider, format, args);
-    }
-
-    /// <summary>
-    /// Determines whether the string contains white space.
-    /// </summary>
-    /// <param name="s">The string to test for white space.</param>
-    /// <returns>
-    /// 	<c>true</c> if the string contains white space; otherwise, <c>false</c>.
-    /// </returns>
-    public static bool ContainsWhiteSpace(string s)
-    {
-      if (s == null)
-        throw new ArgumentNullException("s");
-
-      for (int i = 0; i < s.Length; i++)
-      {
-        if (char.IsWhiteSpace(s[i]))
-          return true;
-      }
-      return false;
-    }
-
-    /// <summary>
-    /// Determines whether the string is all white space. Empty string will return false.
-    /// </summary>
-    /// <param name="s">The string to test whether it is all white space.</param>
-    /// <returns>
-    /// 	<c>true</c> if the string is all white space; otherwise, <c>false</c>.
-    /// </returns>
-    public static bool IsWhiteSpace(string s)
-    {
-      if (s == null)
-        throw new ArgumentNullException("s");
-
-      if (s.Length == 0)
-        return false;
-
-      for (int i = 0; i < s.Length; i++)
-      {
-        if (!char.IsWhiteSpace(s[i]))
-          return false;
-      }
-
-      return true;
-    }
-
-    /// <summary>
-    /// Ensures the target string ends with the specified string.
-    /// </summary>
-    /// <param name="target">The target.</param>
-    /// <param name="value">The value.</param>
-    /// <returns>The target string with the value string at the end.</returns>
-    public static string EnsureEndsWith(string target, string value)
-    {
-      if (target == null)
-        throw new ArgumentNullException("target");
-
-      if (value == null)
-        throw new ArgumentNullException("value");
-
-      if (target.Length >= value.Length)
-      {
-        if (string.Compare(target, target.Length - value.Length, value, 0, value.Length, StringComparison.OrdinalIgnoreCase) ==
-                        0)
-          return target;
-
-        string trimmedString = target.TrimEnd(null);
-
-        if (string.Compare(trimmedString, trimmedString.Length - value.Length, value, 0, value.Length,
-                        StringComparison.OrdinalIgnoreCase) == 0)
-          return target;
-      }
-
-      return target + value;
-    }
-
-    public static bool IsNullOrEmptyOrWhiteSpace(string s)
-    {
-      if (string.IsNullOrEmpty(s))
-        return true;
-      else if (IsWhiteSpace(s))
-        return true;
-      else
-        return false;
-    }
-
-    /// <summary>
-    /// Perform an action if the string is not null or empty.
-    /// </summary>
-    /// <param name="value">The value.</param>
-    /// <param name="action">The action to perform.</param>
-    public static void IfNotNullOrEmpty(string value, Action<string> action)
-    {
-      IfNotNullOrEmpty(value, action, null);
-    }
-
-    private static void IfNotNullOrEmpty(string value, Action<string> trueAction, Action<string> falseAction)
-    {
-      if (!string.IsNullOrEmpty(value))
-      {
-        if (trueAction != null)
-          trueAction(value);
-      }
-      else
-      {
-        if (falseAction != null)
-          falseAction(value);
-      }
-    }
-
-    /// <summary>
-    /// Indents the specified string.
-    /// </summary>
-    /// <param name="s">The string to indent.</param>
-    /// <param name="indentation">The number of characters to indent by.</param>
-    /// <returns></returns>
-    public static string Indent(string s, int indentation)
-    {
-      return Indent(s, indentation, ' ');
-    }
-
-    /// <summary>
-    /// Indents the specified string.
-    /// </summary>
-    /// <param name="s">The string to indent.</param>
-    /// <param name="indentation">The number of characters to indent by.</param>
-    /// <param name="indentChar">The indent character.</param>
-    /// <returns></returns>
-    public static string Indent(string s, int indentation, char indentChar)
-    {
-      if (s == null)
-        throw new ArgumentNullException("s");
-
-      if (indentation <= 0)
-        throw new ArgumentException("Must be greater than zero.", "indentation");
-
-      StringReader sr = new StringReader(s);
-      StringWriter sw = new StringWriter(CultureInfo.InvariantCulture);
-
-      ActionTextReaderLine(sr, sw, delegate(TextWriter tw, string line)
-      {
-        tw.Write(new string(indentChar, indentation));
-        tw.Write(line);
-      });
-
-      return sw.ToString();
-    }
-
-    private delegate void ActionLine(TextWriter textWriter, string line);
-
-    private static void ActionTextReaderLine(TextReader textReader, TextWriter textWriter, ActionLine lineAction)
-    {
-      string line;
-      bool firstLine = true;
-      while ((line = textReader.ReadLine()) != null)
-      {
-        if (!firstLine)
-          textWriter.WriteLine();
-        else
-          firstLine = false;
-
-        lineAction(textWriter, line);
-      }
-    }
-
-    /// <summary>
-    /// Numbers the lines.
-    /// </summary>
-    /// <param name="s">The string to number.</param>
-    /// <returns></returns>
-    public static string NumberLines(string s)
-    {
-      if (s == null)
-        throw new ArgumentNullException("s");
-
-      StringReader sr = new StringReader(s);
-      StringWriter sw = new StringWriter(CultureInfo.InvariantCulture);
-
-      int lineNumber = 1;
-
-      ActionTextReaderLine(sr, sw, delegate(TextWriter tw, string line)
-      {
-        tw.Write(lineNumber.ToString(CultureInfo.InvariantCulture).PadLeft(4));
-        tw.Write(". ");
-        tw.Write(line);
-
-        lineNumber++;
-      });
-
-      return sw.ToString();
-    }
-
-    /// <summary>
-    /// Nulls an empty string.
-    /// </summary>
-    /// <param name="s">The string.</param>
-    /// <returns>Null if the string was null, otherwise the string unchanged.</returns>
-    public static string NullEmptyString(string s)
-    {
-      return (string.IsNullOrEmpty(s)) ? null : s;
-    }
-
-    public static string ReplaceNewLines(string s, string replacement)
-    {
-      StringReader sr = new StringReader(s);
-      StringBuilder sb = new StringBuilder();
-
-      bool first = true;
-
-      string line;
-      while ((line = sr.ReadLine()) != null)
-      {
-        if (first)
-          first = false;
-        else
-          sb.Append(replacement);
-
-        sb.Append(line);
-      }
-
-      return sb.ToString();
-    }
-
-    public static string Truncate(string s, int maximumLength)
-    {
-      return Truncate(s, maximumLength, "...");
-    }
-
-    public static string Truncate(string s, int maximumLength, string suffix)
-    {
-      if (suffix == null)
-        throw new ArgumentNullException("suffix");
-
-      if (maximumLength <= 0)
-        throw new ArgumentException("Maximum length must be greater than zero.", "maximumLength");
-
-      int subStringLength = maximumLength - suffix.Length;
-
-      if (subStringLength <= 0)
-        throw new ArgumentException("Length of suffix string is greater or equal to maximumLength");
-
-      if (s != null && s.Length > maximumLength)
-      {
-        string truncatedString = s.Substring(0, subStringLength);
-        // incase the last character is a space
-        truncatedString = truncatedString.Trim();
-        truncatedString += suffix;
-
-        return truncatedString;
-      }
-      else
-      {
-        return s;
-      }
-    }
-
-    public static StringWriter CreateStringWriter(int capacity)
-    {
-      StringBuilder sb = new StringBuilder(capacity);
-      StringWriter sw = new StringWriter(sb, CultureInfo.InvariantCulture);
-
-      return sw;
-    }
-
-    public static int? GetLength(string value)
-    {
-      if (value == null)
-        return null;
-      else
-        return value.Length;
-    }
-
-    public static string ToCharAsUnicode(char c)
-    {
-      char h1 = MathUtils.IntToHex((c >> 12) & '\x000f');
-      char h2 = MathUtils.IntToHex((c >> 8) & '\x000f');
-      char h3 = MathUtils.IntToHex((c >> 4) & '\x000f');
-      char h4 = MathUtils.IntToHex(c & '\x000f');
-
-      return new string(new[] { '\\', 'u', h1, h2, h3, h4 });
-    }
-
-    public static void WriteCharAsUnicode(TextWriter writer, char c)
-    {
-      ValidationUtils.ArgumentNotNull(writer, "writer");
-
-      char h1 = MathUtils.IntToHex((c >> 12) & '\x000f');
-      char h2 = MathUtils.IntToHex((c >> 8) & '\x000f');
-      char h3 = MathUtils.IntToHex((c >> 4) & '\x000f');
-      char h4 = MathUtils.IntToHex(c & '\x000f');
-
-      writer.Write('\\');
-      writer.Write('u');
-      writer.Write(h1);
-      writer.Write(h2);
-      writer.Write(h3);
-      writer.Write(h4);
-    }
-
-    public static TSource ForgivingCaseSensitiveFind<TSource>(this IEnumerable<TSource> source, Func<TSource, string> valueSelector, string testValue)
-    {
-      if (source == null)
-        throw new ArgumentNullException("source");
-      if (valueSelector == null)
-        throw new ArgumentNullException("valueSelector");
-
-      var caseInsensitiveResults = source.Where(s => string.Compare(valueSelector(s), testValue, StringComparison.OrdinalIgnoreCase) == 0);
-      if (caseInsensitiveResults.Count() <= 1)
-      {
-        return caseInsensitiveResults.SingleOrDefault();
-      }
-      else
-      {
-        // multiple results returned. now filter using case sensitivity
-        var caseSensitiveResults = source.Where(s => string.Compare(valueSelector(s), testValue, StringComparison.Ordinal) == 0);
-        return caseSensitiveResults.SingleOrDefault();
-      }
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Globalization;
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#else
+using System.Linq;
+#endif
+using Newtonsoft.Json.Serialization;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal static class StringUtils
+  {
+    public const string CarriageReturnLineFeed = "\r\n";
+    public const string Empty = "";
+    public const char CarriageReturn = '\r';
+    public const char LineFeed = '\n';
+    public const char Tab = '\t';
+
+    public static string FormatWith(this string format, IFormatProvider provider, object arg0)
+    {
+      return format.FormatWith(provider, new[] { arg0 });
+    }
+
+    public static string FormatWith(this string format, IFormatProvider provider, object arg0, object arg1)
+    {
+      return format.FormatWith(provider, new[] { arg0, arg1 });
+    }
+
+    public static string FormatWith(this string format, IFormatProvider provider, object arg0, object arg1, object arg2)
+    {
+      return format.FormatWith(provider, new[] { arg0, arg1, arg2 });
+    }
+
+    public static string FormatWith(this string format, IFormatProvider provider, params object[] args)
+    {
+      ValidationUtils.ArgumentNotNull(format, "format");
+
+      return string.Format(provider, format, args);
+    }
+
+    /// <summary>
+    /// Determines whether the string is all white space. Empty string will return false.
+    /// </summary>
+    /// <param name="s">The string to test whether it is all white space.</param>
+    /// <returns>
+    /// 	<c>true</c> if the string is all white space; otherwise, <c>false</c>.
+    /// </returns>
+    public static bool IsWhiteSpace(string s)
+    {
+      if (s == null)
+        throw new ArgumentNullException("s");
+
+      if (s.Length == 0)
+        return false;
+
+      for (int i = 0; i < s.Length; i++)
+      {
+        if (!char.IsWhiteSpace(s[i]))
+          return false;
+      }
+
+      return true;
+    }
+
+    /// <summary>
+    /// Nulls an empty string.
+    /// </summary>
+    /// <param name="s">The string.</param>
+    /// <returns>Null if the string was null, otherwise the string unchanged.</returns>
+    public static string NullEmptyString(string s)
+    {
+      return (string.IsNullOrEmpty(s)) ? null : s;
+    }
+
+    public static StringWriter CreateStringWriter(int capacity)
+    {
+      StringBuilder sb = new StringBuilder(capacity);
+      StringWriter sw = new StringWriter(sb, CultureInfo.InvariantCulture);
+
+      return sw;
+    }
+
+    public static int? GetLength(string value)
+    {
+      if (value == null)
+        return null;
+      else
+        return value.Length;
+    }
+
+    public static void ToCharAsUnicode(char c, char[] buffer)
+    {
+      buffer[0] = '\\';
+      buffer[1] = 'u';
+      buffer[2] = MathUtils.IntToHex((c >> 12) & '\x000f');
+      buffer[3] = MathUtils.IntToHex((c >> 8) & '\x000f');
+      buffer[4] = MathUtils.IntToHex((c >> 4) & '\x000f');
+      buffer[5] = MathUtils.IntToHex(c & '\x000f');
+    }
+
+    public static TSource ForgivingCaseSensitiveFind<TSource>(this IEnumerable<TSource> source, Func<TSource, string> valueSelector, string testValue)
+    {
+      if (source == null)
+        throw new ArgumentNullException("source");
+      if (valueSelector == null)
+        throw new ArgumentNullException("valueSelector");
+
+      var caseInsensitiveResults = source.Where(s => string.Equals(valueSelector(s), testValue, StringComparison.OrdinalIgnoreCase));
+      if (caseInsensitiveResults.Count() <= 1)
+      {
+        return caseInsensitiveResults.SingleOrDefault();
+      }
+      else
+      {
+        // multiple results returned. now filter using case sensitivity
+        var caseSensitiveResults = source.Where(s => string.Equals(valueSelector(s), testValue, StringComparison.Ordinal));
+        return caseSensitiveResults.SingleOrDefault();
+      }
+    }
+
+    public static string ToCamelCase(string s)
+    {
+      if (string.IsNullOrEmpty(s))
+        return s;
+
+      if (!char.IsUpper(s[0]))
+        return s;
+
+      string camelCase = null;
+#if !(NETFX_CORE || PORTABLE)
+      camelCase = char.ToLower(s[0], CultureInfo.InvariantCulture).ToString(CultureInfo.InvariantCulture);
+#else
+      camelCase = char.ToLower(s[0]).ToString();
+#endif
+
+      if (s.Length > 1)
+        camelCase += s.Substring(1);
+
+      return camelCase;
+    }
+
+    public static bool IsHighSurrogate(char c)
+    {
+#if !(SILVERLIGHT || PORTABLE)
+      return char.IsHighSurrogate(c);
+#else
+      return (c >= 55296 && c <= 56319);
+#endif
+    }
+
+    public static bool IsLowSurrogate(char c)
+    {
+#if !(SILVERLIGHT || PORTABLE)
+      return char.IsLowSurrogate(c);
+#else
+      return (c >= 56320 && c <= 57343);
+#endif
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ThreadSafeStore.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ThreadSafeStore.cs
index 8d4921a..b4903e9 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ThreadSafeStore.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ThreadSafeStore.cs
@@ -1,60 +1,89 @@
-using System;
-using System.Collections.Generic;
-
-namespace Newtonsoft.Json.Utilities
-{
-  internal class ThreadSafeStore<TKey, TValue>
-  {
-    private readonly object _lock = new object();
-    private Dictionary<TKey, TValue> _store;
-    private readonly Func<TKey, TValue> _creator;
-
-    public ThreadSafeStore(Func<TKey, TValue> creator)
-    {
-      if (creator == null)
-        throw new ArgumentNullException("creator");
-
-      _creator = creator;
-    }
-
-    public TValue Get(TKey key)
-    {
-      if (_store == null)
-        return AddValue(key);
-
-      TValue value;
-      if (!_store.TryGetValue(key, out value))
-        return AddValue(key);
-
-      return value;
-    }
-
-    private TValue AddValue(TKey key)
-    {
-      TValue value = _creator(key);
-
-      lock (_lock)
-      {
-        if (_store == null)
-        {
-          _store = new Dictionary<TKey, TValue>();
-          _store[key] = value;
-        }
-        else
-        {
-          // double check locking
-          TValue checkValue;
-          if (_store.TryGetValue(key, out checkValue))
-            return checkValue;
-
-          Dictionary<TKey, TValue> newStore = new Dictionary<TKey, TValue>(_store);
-          newStore[key] = value;
-
-          _store = newStore;
-        }
-
-        return value;
-      }
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#endif
+using Newtonsoft.Json.Serialization;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal class ThreadSafeStore<TKey, TValue>
+  {
+    private readonly object _lock = new object();
+    private Dictionary<TKey, TValue> _store;
+    private readonly Func<TKey, TValue> _creator;
+
+    public ThreadSafeStore(Func<TKey, TValue> creator)
+    {
+      if (creator == null)
+        throw new ArgumentNullException("creator");
+
+      _creator = creator;
+    }
+
+    public TValue Get(TKey key)
+    {
+      if (_store == null)
+        return AddValue(key);
+
+      TValue value;
+      if (!_store.TryGetValue(key, out value))
+        return AddValue(key);
+
+      return value;
+    }
+
+    private TValue AddValue(TKey key)
+    {
+      TValue value = _creator(key);
+
+      lock (_lock)
+      {
+        if (_store == null)
+        {
+          _store = new Dictionary<TKey, TValue>();
+          _store[key] = value;
+        }
+        else
+        {
+          // double check locking
+          TValue checkValue;
+          if (_store.TryGetValue(key, out checkValue))
+            return checkValue;
+
+          Dictionary<TKey, TValue> newStore = new Dictionary<TKey, TValue>(_store);
+          newStore[key] = value;
+
+          _store = newStore;
+        }
+
+        return value;
+      }
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/TypeExtensions.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/TypeExtensions.cs
new file mode 100644
index 0000000..e2a3ab8
--- /dev/null
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/TypeExtensions.cs
@@ -0,0 +1,591 @@
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+#if NET20
+using Newtonsoft.Json.Utilities.LinqBridge;
+#else
+using System.Linq;
+#endif
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal static class TypeExtensions
+  {
+#if NETFX_CORE
+    private static BindingFlags DefaultFlags = BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance;
+
+    public static MethodInfo GetGetMethod(this PropertyInfo propertyInfo)
+    {
+      return propertyInfo.GetGetMethod(false);
+    }
+
+    public static MethodInfo GetGetMethod(this PropertyInfo propertyInfo, bool nonPublic)
+    {
+      MethodInfo getMethod = propertyInfo.GetMethod;
+      if (getMethod != null && (getMethod.IsPublic || nonPublic))
+        return getMethod;
+
+      return null;
+    }
+
+    public static MethodInfo GetSetMethod(this PropertyInfo propertyInfo)
+    {
+      return propertyInfo.GetSetMethod(false);
+    }
+
+    public static MethodInfo GetSetMethod(this PropertyInfo propertyInfo, bool nonPublic)
+    {
+      MethodInfo setMethod = propertyInfo.SetMethod;
+      if (setMethod != null && (setMethod.IsPublic || nonPublic))
+        return setMethod;
+
+      return null;
+    }
+
+    public static bool IsSubclassOf(this Type type, Type c)
+    {
+      return type.GetTypeInfo().IsSubclassOf(c);
+    }
+
+    public static bool IsAssignableFrom(this Type type, Type c)
+    {
+      return type.GetTypeInfo().IsAssignableFrom(c.GetTypeInfo());
+    }
+#endif
+
+    public static MemberTypes MemberType(this MemberInfo memberInfo)
+    {
+#if !(NETFX_CORE || PORTABLE)
+      return memberInfo.MemberType;
+#else
+      if (memberInfo is PropertyInfo)
+        return MemberTypes.Property;
+      else if (memberInfo is FieldInfo)
+        return MemberTypes.Field;
+      else if (memberInfo is EventInfo)
+        return MemberTypes.Event;
+      else if (memberInfo is MethodInfo)
+        return MemberTypes.Method;
+      else
+        return MemberTypes.Other;
+#endif
+    }
+
+    public static bool ContainsGenericParameters(this Type type)
+    {
+#if !NETFX_CORE
+      return type.ContainsGenericParameters;
+#else
+      return type.GetTypeInfo().ContainsGenericParameters;
+#endif
+    }
+
+    public static bool IsInterface(this Type type)
+    {
+#if !NETFX_CORE
+      return type.IsInterface;
+#else
+      return type.GetTypeInfo().IsInterface;
+#endif
+    }
+
+    public static bool IsGenericType(this Type type)
+    {
+#if !NETFX_CORE
+      return type.IsGenericType;
+#else
+      return type.GetTypeInfo().IsGenericType;
+#endif
+    }
+
+    public static bool IsGenericTypeDefinition(this Type type)
+    {
+#if !NETFX_CORE
+      return type.IsGenericTypeDefinition;
+#else
+      return type.GetTypeInfo().IsGenericTypeDefinition;
+#endif
+    }
+
+    public static Type BaseType(this Type type)
+    {
+#if !NETFX_CORE
+      return type.BaseType;
+#else
+      return type.GetTypeInfo().BaseType;
+#endif
+    }
+
+    public static bool IsEnum(this Type type)
+    {
+#if !NETFX_CORE
+      return type.IsEnum;
+#else
+      return type.GetTypeInfo().IsEnum;
+#endif
+    }
+
+    public static bool IsClass(this Type type)
+    {
+#if !NETFX_CORE
+      return type.IsClass;
+#else
+      return type.GetTypeInfo().IsClass;
+#endif
+    }
+
+    public static bool IsSealed(this Type type)
+    {
+#if !NETFX_CORE
+      return type.IsSealed;
+#else
+      return type.GetTypeInfo().IsSealed;
+#endif
+    }
+
+#if PORTABLE
+    public static PropertyInfo GetProperty(this Type type, string name, BindingFlags bindingFlags, object placeholder1, Type propertyType, IList<Type> indexParameters, object placeholder2)
+    {
+      IList<PropertyInfo> propertyInfos = type.GetProperties(bindingFlags);
+
+      return propertyInfos.Where(p =>
+      {
+        if (name != null && name != p.Name)
+          return false;
+        if (propertyType != null && propertyType != p.PropertyType)
+          return false;
+        if (indexParameters != null)
+        {
+          if (!p.GetIndexParameters().Select(ip => ip.ParameterType).SequenceEqual(indexParameters))
+            return false;
+        }
+
+        return true;
+      }).SingleOrDefault();
+    }
+
+    public static IEnumerable<MemberInfo> GetMember(this Type type, string name, MemberTypes memberType, BindingFlags bindingFlags)
+    {
+      return type.GetMembers(bindingFlags).Where(m =>
+        {
+          if (name != null && name != m.Name)
+            return false;
+          if (m.MemberType() != memberType)
+            return false;
+
+          return true;
+        });
+    }
+#endif
+
+#if NETFX_CORE
+    public static bool IsDefined(this Type type, Type attributeType, bool inherit)
+    {
+      return type.GetTypeInfo().CustomAttributes.Any(a => a.AttributeType == attributeType);
+    }
+
+    public static MethodInfo GetMethod(this Type type, string name)
+    {
+      return type.GetMethod(name, DefaultFlags);
+    }
+
+    public static MethodInfo GetMethod(this Type type, string name, BindingFlags bindingFlags)
+    {
+      return type.GetTypeInfo().GetDeclaredMethod(name);
+    }
+
+    public static MethodInfo GetMethod(this Type type, IList<Type> parameterTypes)
+    {
+      return type.GetMethod(null, parameterTypes);
+    }
+
+    public static MethodInfo GetMethod(this Type type, string name, IList<Type> parameterTypes)
+    {
+      return type.GetMethod(name, DefaultFlags, null, parameterTypes, null);
+    }
+
+    public static MethodInfo GetMethod(this Type type, string name, BindingFlags bindingFlags, object placeHolder1, IList<Type> parameterTypes, object placeHolder2)
+    {
+      return type.GetTypeInfo().DeclaredMethods.Where(m =>
+      {
+        if (name != null && m.Name != name)
+          return false;
+
+        if (!TestAccessibility(m, bindingFlags))
+          return false;
+
+        return m.GetParameters().Select(p => p.ParameterType).SequenceEqual(parameterTypes);
+      }).SingleOrDefault();
+    }
+
+    public static PropertyInfo GetProperty(this Type type, string name, BindingFlags bindingFlags, object placeholder1, Type propertyType, IList<Type> indexParameters, object placeholder2)
+    {
+      return type.GetTypeInfo().DeclaredProperties.Where(p =>
+      {
+        if (name != null && name != p.Name)
+          return false;
+        if (propertyType != null && propertyType != p.PropertyType)
+          return false;
+        if (indexParameters != null)
+        {
+          if (!p.GetIndexParameters().Select(ip => ip.ParameterType).SequenceEqual(indexParameters))
+            return false;
+        }
+
+        return true;
+      }).SingleOrDefault();
+    }
+
+    public static IEnumerable<MemberInfo> GetMember(this Type type, string name, MemberTypes memberType, BindingFlags bindingFlags)
+    {
+      return type.GetTypeInfo().GetMembersRecursive().Where(m =>
+      {
+        if (name != null && name != m.Name)
+          return false;
+        if (m.MemberType() != memberType)
+          return false;
+        if (!TestAccessibility(m, bindingFlags))
+          return false;
+
+        return true;
+      });
+    }
+
+    public static IEnumerable<ConstructorInfo> GetConstructors(this Type type)
+    {
+      return type.GetConstructors(DefaultFlags);
+    }
+
+    public static IEnumerable<ConstructorInfo> GetConstructors(this Type type, BindingFlags bindingFlags)
+    {
+      return type.GetConstructors(bindingFlags, null);
+    }
+
+    private static IEnumerable<ConstructorInfo> GetConstructors(this Type type, BindingFlags bindingFlags, IList<Type> parameterTypes)
+    {
+      return type.GetTypeInfo().DeclaredConstructors.Where(c =>
+      {
+        if (!TestAccessibility(c, bindingFlags))
+          return false;
+
+        if (parameterTypes != null && !c.GetParameters().Select(p => p.ParameterType).SequenceEqual(parameterTypes))
+          return false;
+
+        return true;
+      });
+    }
+
+    public static ConstructorInfo GetConstructor(this Type type, IList<Type> parameterTypes)
+    {
+      return type.GetConstructor(DefaultFlags, null, parameterTypes, null);
+    }
+
+    public static ConstructorInfo GetConstructor(this Type type, BindingFlags bindingFlags, object placeholder1, IList<Type> parameterTypes, object placeholder2)
+    {
+      return type.GetConstructors(bindingFlags, parameterTypes).SingleOrDefault();
+    }
+
+    public static MemberInfo[] GetMember(this Type type, string member)
+    {
+      return type.GetMember(member, DefaultFlags);
+    }
+
+    public static MemberInfo[] GetMember(this Type type, string member, BindingFlags bindingFlags)
+    {
+      return type.GetTypeInfo().GetMembersRecursive().Where(m => m.Name == member && TestAccessibility(m, bindingFlags)).ToArray();
+    }
+
+    public static MemberInfo GetField(this Type type, string member)
+    {
+      return type.GetField(member, DefaultFlags);
+    }
+
+    public static MemberInfo GetField(this Type type, string member, BindingFlags bindingFlags)
+    {
+      return type.GetTypeInfo().GetDeclaredField(member);
+    }
+
+    public static IEnumerable<PropertyInfo> GetProperties(this Type type, BindingFlags bindingFlags)
+    {
+      return type.GetTypeInfo().GetPropertiesRecursive().Where(p => TestAccessibility(p, bindingFlags));
+    }
+
+    private static IList<MemberInfo> GetMembersRecursive(this TypeInfo type)
+    {
+      TypeInfo t = type;
+      IList<MemberInfo> members = new List<MemberInfo>();
+      while (t != null)
+      {
+        foreach (var member in t.DeclaredMembers)
+        {
+          if (!members.Any(p => p.Name == member.Name))
+            members.Add(member);
+        }
+        t = (t.BaseType != null) ? t.BaseType.GetTypeInfo() : null;
+      }
+
+      return members;
+    }
+
+    private static IList<PropertyInfo> GetPropertiesRecursive(this TypeInfo type)
+    {
+      TypeInfo t = type;
+      IList<PropertyInfo> properties = new List<PropertyInfo>();
+      while (t != null)
+      {
+        foreach (var member in t.DeclaredProperties)
+        {
+          if (!properties.Any(p => p.Name == member.Name))
+            properties.Add(member);
+        }
+        t = (t.BaseType != null) ? t.BaseType.GetTypeInfo() : null;
+      }
+
+      return properties;
+    }
+
+    private static IList<FieldInfo> GetFieldsRecursive(this TypeInfo type)
+    {
+      TypeInfo t = type;
+      IList<FieldInfo> fields = new List<FieldInfo>();
+      while (t != null)
+      {
+        foreach (var member in t.DeclaredFields)
+        {
+          if (!fields.Any(p => p.Name == member.Name))
+            fields.Add(member);
+        }
+        t = (t.BaseType != null) ? t.BaseType.GetTypeInfo() : null;
+      }
+
+      return fields;
+    }
+
+    public static IEnumerable<MethodInfo> GetMethods(this Type type, BindingFlags bindingFlags)
+    {
+      return type.GetTypeInfo().DeclaredMethods;
+    }
+
+    public static PropertyInfo GetProperty(this Type type, string name)
+    {
+      return type.GetProperty(name, DefaultFlags);
+    }
+
+    public static PropertyInfo GetProperty(this Type type, string name, BindingFlags bindingFlags)
+    {
+      return type.GetTypeInfo().GetDeclaredProperty(name);
+    }
+
+    public static IEnumerable<FieldInfo> GetFields(this Type type)
+    {
+      return type.GetFields(DefaultFlags);
+    }
+
+    public static IEnumerable<FieldInfo> GetFields(this Type type, BindingFlags bindingFlags)
+    {
+      return type.GetTypeInfo().GetFieldsRecursive().Where(f => TestAccessibility(f, bindingFlags)).ToList();
+    }
+
+    private static bool TestAccessibility(PropertyInfo member, BindingFlags bindingFlags)
+    {
+      if (member.GetMethod != null && TestAccessibility(member.GetMethod, bindingFlags))
+        return true;
+
+      if (member.SetMethod != null && TestAccessibility(member.SetMethod, bindingFlags))
+        return true;
+
+      return false;
+    }
+
+    private static bool TestAccessibility(MemberInfo member, BindingFlags bindingFlags)
+    {
+      if (member is FieldInfo)
+      {
+        return TestAccessibility((FieldInfo)member, bindingFlags);
+      }
+      else if (member is MethodBase)
+      {
+        return TestAccessibility((MethodBase)member, bindingFlags);
+      }
+      else if (member is PropertyInfo)
+      {
+        return TestAccessibility((PropertyInfo)member, bindingFlags);
+      }
+
+      throw new Exception("Unexpected member type.");
+    }
+
+    private static bool TestAccessibility(FieldInfo member, BindingFlags bindingFlags)
+    {
+      bool visibility = (member.IsPublic && bindingFlags.HasFlag(BindingFlags.Public)) ||
+        (!member.IsPublic && bindingFlags.HasFlag(BindingFlags.NonPublic));
+
+      bool instance = (member.IsStatic && bindingFlags.HasFlag(BindingFlags.Static)) ||
+        (!member.IsStatic && bindingFlags.HasFlag(BindingFlags.Instance));
+
+      return visibility && instance;
+    }
+
+    private static bool TestAccessibility(MethodBase member, BindingFlags bindingFlags)
+    {
+      bool visibility = (member.IsPublic && bindingFlags.HasFlag(BindingFlags.Public)) ||
+        (!member.IsPublic && bindingFlags.HasFlag(BindingFlags.NonPublic));
+
+      bool instance = (member.IsStatic && bindingFlags.HasFlag(BindingFlags.Static)) ||
+        (!member.IsStatic && bindingFlags.HasFlag(BindingFlags.Instance));
+
+      return visibility && instance;
+    }
+
+    public static Type[] GetGenericArguments(this Type type)
+    {
+      return type.GetTypeInfo().GenericTypeArguments;
+    }
+
+    public static IEnumerable<Type> GetInterfaces(this Type type)
+    {
+      return type.GetTypeInfo().ImplementedInterfaces;
+    }
+
+    public static IEnumerable<MethodInfo> GetMethods(this Type type)
+    {
+      return type.GetTypeInfo().DeclaredMethods;
+    }
+#endif
+
+    public static bool IsAbstract(this Type type)
+    {
+#if !NETFX_CORE
+      return type.IsAbstract;
+#else
+      return type.GetTypeInfo().IsAbstract;
+#endif
+    }
+
+    public static bool IsVisible(this Type type)
+    {
+#if !NETFX_CORE
+      return type.IsVisible;
+#else
+      return type.GetTypeInfo().IsVisible;
+#endif
+    }
+
+    public static bool IsValueType(this Type type)
+    {
+#if !NETFX_CORE
+      return type.IsValueType;
+#else
+      return type.GetTypeInfo().IsValueType;
+#endif
+    }
+
+    public static bool AssignableToTypeName(this Type type, string fullTypeName, out Type match)
+    {
+      Type current = type;
+
+      while (current != null)
+      {
+        if (string.Equals(current.FullName, fullTypeName, StringComparison.Ordinal))
+        {
+          match = current;
+          return true;
+        }
+
+        current = current.BaseType();
+      }
+
+      foreach (Type i in type.GetInterfaces())
+      {
+        if (string.Equals(i.Name, fullTypeName, StringComparison.Ordinal))
+        {
+          match = type;
+          return true;
+        }
+      }
+
+      match = null;
+      return false;
+    }
+
+    public static bool AssignableToTypeName(this Type type, string fullTypeName)
+    {
+      Type match;
+      return type.AssignableToTypeName(fullTypeName, out match);
+    }
+
+    public static MethodInfo GetGenericMethod(this Type type, string name, params Type[] parameterTypes)
+    {
+      var methods = type.GetMethods().Where(method => method.Name == name);
+
+      foreach (var method in methods)
+      {
+        if (method.HasParameters(parameterTypes))
+          return method;
+      }
+
+      return null;
+    }
+
+    public static bool HasParameters(this MethodInfo method, params Type[] parameterTypes)
+    {
+      var methodParameters = method.GetParameters().Select(parameter => parameter.ParameterType).ToArray();
+
+      if (methodParameters.Length != parameterTypes.Length)
+        return false;
+
+      for (int i = 0; i < methodParameters.Length; i++)
+        if (methodParameters[i].ToString() != parameterTypes[i].ToString())
+          return false;
+
+      return true;
+    }
+
+    public static IEnumerable<Type> GetAllInterfaces(this Type target)
+    {
+      foreach (var i in target.GetInterfaces())
+      {
+        yield return i;
+        foreach (var ci in i.GetInterfaces())
+        {
+          yield return ci;
+        }
+      }
+    }
+
+    public static IEnumerable<MethodInfo> GetAllMethods(this Type target)
+    {
+      var allTypes = target.GetAllInterfaces().ToList();
+      allTypes.Add(target);
+
+      return from type in allTypes
+             from method in type.GetMethods()
+             select method;
+    }
+  }
+}
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ValidationUtils.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ValidationUtils.cs
index 5065448..3f01824 100644
--- a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ValidationUtils.cs
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ValidationUtils.cs
@@ -1,149 +1,79 @@
-#region License
-// 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.
-#endregion
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Text;
-using System.Globalization;
-
-namespace Newtonsoft.Json.Utilities
-{
-  internal static class ValidationUtils
-  {
-    public const string EmailAddressRegex = @"^([a-zA-Z0-9_'+*$%\^&!\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9:]{2,4})+$";
-    public const string CurrencyRegex = @"(^\$?(?!0,?\d)\d{1,3}(,?\d{3})*(\.\d\d)?)$";
-    public const string DateRegex =
-        @"^(((0?[1-9]|[12]\d|3[01])[\.\-\/](0?[13578]|1[02])[\.\-\/]((1[6-9]|[2-9]\d)?\d{2}|\d))|((0?[1-9]|[12]\d|30)[\.\-\/](0?[13456789]|1[012])[\.\-\/]((1[6-9]|[2-9]\d)?\d{2}|\d))|((0?[1-9]|1\d|2[0-8])[\.\-\/]0?2[\.\-\/]((1[6-9]|[2-9]\d)?\d{2}|\d))|(29[\.\-\/]0?2[\.\-\/]((1[6-9]|[2-9]\d)?(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)|00|[048])))$";
-    public const string NumericRegex = @"\d*";
-
-    public static void ArgumentNotNullOrEmpty(string value, string parameterName)
-    {
-      if (value == null)
-        throw new ArgumentNullException(parameterName);
-
-      if (value.Length == 0)
-        throw new ArgumentException("'{0}' cannot be empty.".FormatWith(CultureInfo.InvariantCulture, parameterName), parameterName);
-    }
-
-    public static void ArgumentNotNullOrEmptyOrWhitespace(string value, string parameterName)
-    {
-      ArgumentNotNullOrEmpty(value, parameterName);
-
-      if (StringUtils.IsWhiteSpace(value))
-        throw new ArgumentException("'{0}' cannot only be whitespace.".FormatWith(CultureInfo.InvariantCulture, parameterName), parameterName);
-    }
-
-    public static void ArgumentTypeIsEnum(Type enumType, string parameterName)
-    {
-      ArgumentNotNull(enumType, "enumType");
-
-      if (!enumType.IsEnum)
-        throw new ArgumentException("Type {0} is not an Enum.".FormatWith(CultureInfo.InvariantCulture, enumType), parameterName);
-    }
-
-    public static void ArgumentNotNullOrEmpty<T>(ICollection<T> collection, string parameterName)
-    {
-      ArgumentNotNullOrEmpty<T>(collection, parameterName, "Collection '{0}' cannot be empty.".FormatWith(CultureInfo.InvariantCulture, parameterName));
-    }
-
-    public static void ArgumentNotNullOrEmpty<T>(ICollection<T> collection, string parameterName, string message)
-    {
-      if (collection == null)
-        throw new ArgumentNullException(parameterName);
-
-      if (collection.Count == 0)
-        throw new ArgumentException(message, parameterName);
-    }
-
-    public static void ArgumentNotNullOrEmpty(ICollection collection, string parameterName)
-    {
-      ArgumentNotNullOrEmpty(collection, parameterName, "Collection '{0}' cannot be empty.".FormatWith(CultureInfo.InvariantCulture, parameterName));
-    }
-
-    public static void ArgumentNotNullOrEmpty(ICollection collection, string parameterName, string message)
-    {
-      if (collection == null)
-        throw new ArgumentNullException(parameterName);
-
-      if (collection.Count == 0)
-        throw new ArgumentException(message, parameterName);
-    }
-
-    public static void ArgumentNotNull(object value, string parameterName)
-    {
-      if (value == null)
-        throw new ArgumentNullException(parameterName);
-    }
-
-    public static void ArgumentNotNegative(int value, string parameterName)
-    {
-      if (value <= 0)
-        throw MiscellaneousUtils.CreateArgumentOutOfRangeException(parameterName, value, "Argument cannot be negative.");
-    }
-
-    public static void ArgumentNotNegative(int value, string parameterName, string message)
-    {
-      if (value <= 0)
-        throw MiscellaneousUtils.CreateArgumentOutOfRangeException(parameterName, value, message);
-    }
-
-    public static void ArgumentNotZero(int value, string parameterName)
-    {
-      if (value == 0)
-        throw MiscellaneousUtils.CreateArgumentOutOfRangeException(parameterName, value, "Argument cannot be zero.");
-    }
-
-    public static void ArgumentNotZero(int value, string parameterName, string message)
-    {
-      if (value == 0)
-        throw MiscellaneousUtils.CreateArgumentOutOfRangeException(parameterName, value, message);
-    }
-
-    public static void ArgumentIsPositive<T>(T value, string parameterName) where T : struct, IComparable<T>
-    {
-      if (value.CompareTo(default(T)) != 1)
-        throw MiscellaneousUtils.CreateArgumentOutOfRangeException(parameterName, value, "Positive number required.");
-    }
-
-    public static void ArgumentIsPositive(int value, string parameterName, string message)
-    {
-      if (value > 0)
-        throw MiscellaneousUtils.CreateArgumentOutOfRangeException(parameterName, value, message);
-    }
-
-    public static void ObjectNotDisposed(bool disposed, Type objectType)
-    {
-      if (disposed)
-        throw new ObjectDisposedException(objectType.Name);
-    }
-
-    public static void ArgumentConditionTrue(bool condition, string parameterName, string message)
-    {
-      if (!condition)
-        throw new ArgumentException(message, parameterName);
-    }
-  }
+#region License
+// 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.
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal static class ValidationUtils
+  {
+    public static void ArgumentNotNullOrEmpty(string value, string parameterName)
+    {
+      if (value == null)
+        throw new ArgumentNullException(parameterName);
+
+      if (value.Length == 0)
+        throw new ArgumentException("'{0}' cannot be empty.".FormatWith(CultureInfo.InvariantCulture, parameterName), parameterName);
+    }
+
+    public static void ArgumentTypeIsEnum(Type enumType, string parameterName)
+    {
+      ArgumentNotNull(enumType, "enumType");
+
+      if (!enumType.IsEnum())
+        throw new ArgumentException("Type {0} is not an Enum.".FormatWith(CultureInfo.InvariantCulture, enumType), parameterName);
+    }
+
+    public static void ArgumentNotNullOrEmpty<T>(ICollection<T> collection, string parameterName)
+    {
+      ArgumentNotNullOrEmpty<T>(collection, parameterName, "Collection '{0}' cannot be empty.".FormatWith(CultureInfo.InvariantCulture, parameterName));
+    }
+
+    public static void ArgumentNotNullOrEmpty<T>(ICollection<T> collection, string parameterName, string message)
+    {
+      if (collection == null)
+        throw new ArgumentNullException(parameterName);
+
+      if (collection.Count == 0)
+        throw new ArgumentException(message, parameterName);
+    }
+
+    public static void ArgumentNotNull(object value, string parameterName)
+    {
+      if (value == null)
+        throw new ArgumentNullException(parameterName);
+    }
+
+    public static void ArgumentConditionTrue(bool condition, string parameterName, string message)
+    {
+      if (!condition)
+        throw new ArgumentException(message, parameterName);
+    }
+  }
 }
\ No newline at end of file
diff --git a/lib/Newtonsoft.Json/Src/Newtonsoft.Json/WriteState.cs b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/WriteState.cs
new file mode 100644
index 0000000..609a394
--- /dev/null
+++ b/lib/Newtonsoft.Json/Src/Newtonsoft.Json/WriteState.cs
@@ -0,0 +1,66 @@
+#region License
+// 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.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Specifies the state of the <see cref="JsonWriter"/>.
+  /// </summary>
+  public enum WriteState
+  {
+    /// <summary>
+    /// An exception has been thrown, which has left the <see cref="JsonWriter"/> in an invalid state.
+    /// You may call the <see cref="JsonWriter.Close"/> method to put the <see cref="JsonWriter"/> in the <c>Closed</c> state.
+    /// Any other <see cref="JsonWriter"/> method calls results in an <see cref="InvalidOperationException"/> being thrown. 
+    /// </summary>
+    Error,
+    /// <summary>
+    /// The <see cref="JsonWriter.Close"/> method has been called. 
+    /// </summary>
+    Closed,
+    /// <summary>
+    /// An object is being written. 
+    /// </summary>
+    Object,
+    /// <summary>
+    /// A array is being written.
+    /// </summary>
+    Array,
+    /// <summary>
+    /// A constructor is being written.
+    /// </summary>
+    Constructor,
+    /// <summary>
+    /// A property is being written.
+    /// </summary>
+    Property,
+    /// <summary>
+    /// A write method has not been called.
+    /// </summary>
+    Start
+  }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/AssemblyUtils.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/AssemblyUtils.cs
new file mode 100644
index 0000000..d8d4ee6
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/AssemblyUtils.cs
@@ -0,0 +1,135 @@
+using System;
+using System.IO;
+using System.Reflection;
+using System.Text;
+using System.Text.RegularExpressions;
+#if SILVERLIGHT
+using System.Windows;
+#endif
+using ServiceStack.Common.Support;
+
+namespace ServiceStack.Text
+{
+    /// <summary>
+    /// Utils to load types
+    /// </summary>
+    public static class AssemblyUtils
+    {
+        private const string FileUri = "file:///";
+        private const string DllExt = "dll";
+        private const string ExeExt = "dll";
+        private const char UriSeperator = '/';
+
+#if !XBOX
+        /// <summary>
+        /// Find the type from the name supplied
+        /// </summary>
+        /// <param name="typeName">[typeName] or [typeName, assemblyName]</param>
+        /// <returns></returns>
+        public static Type FindType(string typeName)
+        {
+#if !SILVERLIGHT
+            var type = Type.GetType(typeName);
+            if (type != null) return type;
+#endif
+            var typeDef = new AssemblyTypeDefinition(typeName);
+            if (!String.IsNullOrEmpty(typeDef.AssemblyName))
+            {
+                return FindType(typeDef.TypeName, typeDef.AssemblyName);
+            }
+            else
+            {
+                return FindTypeFromLoadedAssemblies(typeDef.TypeName);
+            }
+        }
+#endif
+
+#if !XBOX
+        /// <summary>
+        /// Find type if it exists
+        /// </summary>
+        /// <param name="typeName"></param>
+        /// <param name="assemblyName"></param>
+        /// <returns>The type if it exists</returns>
+        public static Type FindType(string typeName, string assemblyName)
+        {
+            var type = FindTypeFromLoadedAssemblies(typeName);
+            if (type != null)
+            {
+                return type;
+            }
+            var binPath = GetAssemblyBinPath(Assembly.GetExecutingAssembly());
+            Assembly assembly = null;
+            var assemblyDllPath = binPath + String.Format("{0}.{1}", assemblyName, DllExt);
+            if (File.Exists(assemblyDllPath))
+            {
+                assembly = LoadAssembly(assemblyDllPath);
+            }
+            var assemblyExePath = binPath + String.Format("{0}.{1}", assemblyName, ExeExt);
+            if (File.Exists(assemblyExePath))
+            {
+                assembly = LoadAssembly(assemblyExePath);
+            }
+            return assembly != null ? assembly.GetType(typeName) : null;
+        }
+#endif
+
+#if !XBOX
+        public static Type FindTypeFromLoadedAssemblies(string typeName)
+        {
+#if SILVERLIGHT4
+        	var assemblies = ((dynamic) AppDomain.CurrentDomain).GetAssemblies() as Assembly[];
+#else
+			var assemblies = AppDomain.CurrentDomain.GetAssemblies();
+#endif
+        	foreach (var assembly in assemblies)
+            {
+                var type = assembly.GetType(typeName);
+                if (type != null)
+                {
+                    return type;
+                }
+            }
+            return null;
+        }
+#endif
+
+#if !SILVERLIGHT
+private static Assembly LoadAssembly(string assemblyPath)
+		{
+			return Assembly.LoadFrom(assemblyPath);
+		}
+#else
+        private static Assembly LoadAssembly(string assemblyPath)
+        {            
+            var sri = Application.GetResourceStream(new Uri(assemblyPath, UriKind.Relative));
+            var myPart = new AssemblyPart();
+            var assembly = myPart.Load(sri.Stream);
+            return assembly;
+        }
+#endif
+
+#if !XBOX
+        public static string GetAssemblyBinPath(Assembly assembly)
+        {
+            var binPathPos = assembly.CodeBase.LastIndexOf(UriSeperator);
+            var assemblyPath = assembly.CodeBase.Substring(0, binPathPos + 1);
+            if (assemblyPath.StartsWith(FileUri))
+            {
+                assemblyPath = assemblyPath.Remove(0, FileUri.Length);
+            }
+            return assemblyPath;
+        }
+#endif
+
+#if !SILVERLIGHT
+		static readonly Regex versionRegEx = new Regex(", Version=[^\\]]+", RegexOptions.Compiled);
+#else
+        static readonly Regex versionRegEx = new Regex(", Version=[^\\]]+");
+#endif
+        public static string ToTypeString(this Type type)
+        {
+            return versionRegEx.Replace(type.AssemblyQualifiedName, "");
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DateTimeSerializer.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DateTimeSerializer.cs
new file mode 100644
index 0000000..6e2083e
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DateTimeSerializer.cs
@@ -0,0 +1,151 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.Globalization;
+using System.Xml;
+using ServiceStack.Text.Json;
+
+namespace ServiceStack.Text.Common
+{
+	public static class DateTimeSerializer
+	{
+		public const string ShortDateTimeFormat = "yyyy-MM-dd";					//11
+		public const string DefaultDateTimeFormat = "dd/MM/yyyy HH:mm:ss";		//20
+		public const string DefaultDateTimeFormatWithFraction = "dd/MM/yyyy HH:mm:ss.fff";	//24
+		public const string XsdDateTimeFormat = "yyyy-MM-ddTHH:mm:ss.fffffffZ";	//29
+		public const string XsdDateTimeFormat3F = "yyyy-MM-ddTHH:mm:ss.fffZ";	//25
+		public const string XsdDateTimeFormatSeconds = "yyyy-MM-ddTHH:mm:ssZ";	//21
+
+		public const string EscapedWcfJsonPrefix = "\\/Date(";
+		public const string EscapedWcfJsonSuffix = ")\\/";
+		public const string WcfJsonPrefix = "/Date(";
+		public const char WcfJsonSuffix = ')';
+
+		public static DateTime ParseShortestXsdDateTime(string dateTimeStr)
+		{
+			if (string.IsNullOrEmpty(dateTimeStr))
+				return DateTime.MinValue;
+
+			if (dateTimeStr.StartsWith(EscapedWcfJsonPrefix) || dateTimeStr.StartsWith(WcfJsonPrefix))
+				return ParseWcfJsonDate(dateTimeStr);
+
+			if (dateTimeStr.Length == DefaultDateTimeFormat.Length
+				|| dateTimeStr.Length == DefaultDateTimeFormatWithFraction.Length)
+				return DateTime.Parse(dateTimeStr, CultureInfo.InvariantCulture);
+
+			if (dateTimeStr.Length == XsdDateTimeFormatSeconds.Length)
+				return DateTime.ParseExact(dateTimeStr, XsdDateTimeFormatSeconds, null,
+										   DateTimeStyles.AdjustToUniversal);
+
+			if (dateTimeStr.Length >= XsdDateTimeFormat3F.Length
+				&& dateTimeStr.Length <= XsdDateTimeFormat.Length)
+				return XmlConvert.ToDateTime(dateTimeStr, XmlDateTimeSerializationMode.Local);
+
+			return DateTime.Parse(dateTimeStr, null, DateTimeStyles.AssumeLocal);
+		}
+
+		public static string ToDateTimeString(DateTime dateTime)
+		{
+			return dateTime.ToStableUniversalTime().ToString(XsdDateTimeFormat);
+		}
+
+		public static DateTime ParseDateTime(string dateTimeStr)
+		{
+			return DateTime.ParseExact(dateTimeStr, XsdDateTimeFormat, null);
+		}
+
+		public static string ToXsdDateTimeString(DateTime dateTime)
+		{
+			return XmlConvert.ToString(dateTime.ToStableUniversalTime(), XmlDateTimeSerializationMode.Utc);
+		}
+
+		public static DateTime ParseXsdDateTime(string dateTimeStr)
+		{
+			return XmlConvert.ToDateTime(dateTimeStr, XmlDateTimeSerializationMode.Utc);
+		}
+
+		public static string ToShortestXsdDateTimeString(DateTime dateTime)
+		{
+			var timeOfDay = dateTime.TimeOfDay;
+
+			if (timeOfDay.Ticks == 0)
+				return dateTime.ToString(ShortDateTimeFormat);
+
+			if (timeOfDay.Milliseconds == 0)
+				return dateTime.ToStableUniversalTime().ToString(XsdDateTimeFormatSeconds);
+
+			return ToXsdDateTimeString(dateTime);
+		}
+
+
+		static readonly char[] TimeZoneChars = new[] { '+', '-' };
+
+		/// <summary>
+		/// WCF Json format: /Date(unixts+0000)/
+		/// </summary>
+		/// <param name="wcfJsonDate"></param>
+		/// <returns></returns>
+		public static DateTime ParseWcfJsonDate(string wcfJsonDate)
+		{
+
+			if (wcfJsonDate[0] == JsonUtils.EscapeChar)
+			{
+				wcfJsonDate = wcfJsonDate.Substring(1);
+			}
+
+			var suffixPos = wcfJsonDate.IndexOf(WcfJsonSuffix);
+			var timeString = wcfJsonDate.Substring(WcfJsonPrefix.Length, suffixPos - WcfJsonPrefix.Length);
+
+			if (JsConfig.DateHandler == JsonDateHandler.ISO8601)
+			{
+				return DateTime.Parse(timeString, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind);
+			}
+
+			var timeZonePos = timeString.LastIndexOfAny(TimeZoneChars);
+			var timeZone = timeZonePos <= 0 ? string.Empty : timeString.Substring(timeZonePos);
+			var unixTimeString = timeString.Substring(0, timeString.Length - timeZone.Length);
+
+			var unixTime = long.Parse(unixTimeString);
+
+			if (timeZone == string.Empty)
+			{
+				// when no timezone offset is supplied, then treat the time as UTC
+				return unixTime.FromUnixTimeMs();
+			}
+
+			if (JsConfig.DateHandler == JsonDateHandler.DCJSCompatible)
+			{
+				// DCJS ignores the offset and considers it local time if any offset exists
+				return unixTime.FromUnixTimeMs().ToLocalTime();
+			}
+
+			var offset = timeZone.FromTimeOffsetString();
+			var date = unixTime.FromUnixTimeMs(offset);
+			return date;
+		}
+
+		public static string ToWcfJsonDate(DateTime dateTime)
+		{
+			if (JsConfig.DateHandler == JsonDateHandler.ISO8601)
+			{
+				return EscapedWcfJsonPrefix + dateTime.ToString("o", CultureInfo.InvariantCulture) + EscapedWcfJsonSuffix;
+			}
+
+			var timestamp = dateTime.ToUnixTimeMs();
+			var offset = dateTime.Kind == DateTimeKind.Utc || dateTime.Kind == DateTimeKind.Unspecified
+							? string.Empty
+							: TimeZoneInfo.Local.GetUtcOffset(dateTime).ToTimeOffsetString();
+			return EscapedWcfJsonPrefix + timestamp + offset + EscapedWcfJsonSuffix;
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeArray.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeArray.cs
new file mode 100644
index 0000000..ebe087b
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeArray.cs
@@ -0,0 +1,182 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Reflection;
+using System.Threading;
+
+namespace ServiceStack.Text.Common
+{
+	internal static class DeserializeArrayWithElements<TSerializer>
+		where TSerializer : ITypeSerializer
+	{
+		private static Dictionary<Type, ParseArrayOfElementsDelegate> ParseDelegateCache 
+			= new Dictionary<Type, ParseArrayOfElementsDelegate>();
+
+		private delegate object ParseArrayOfElementsDelegate(string value, ParseStringDelegate parseFn);
+
+		public static Func<string, ParseStringDelegate, object> GetParseFn(Type type)
+		{
+			ParseArrayOfElementsDelegate parseFn;
+			if (ParseDelegateCache.TryGetValue(type, out parseFn)) return parseFn.Invoke;
+
+            var genericType = typeof(DeserializeArrayWithElements<,>).MakeGenericType(type, typeof(TSerializer));
+            var mi = genericType.GetMethod("ParseGenericArray", BindingFlags.Public | BindingFlags.Static);
+            parseFn = (ParseArrayOfElementsDelegate)Delegate.CreateDelegate(typeof(ParseArrayOfElementsDelegate), mi);
+
+            Dictionary<Type, ParseArrayOfElementsDelegate> snapshot, newCache;
+            do
+            {
+                snapshot = ParseDelegateCache;
+                newCache = new Dictionary<Type, ParseArrayOfElementsDelegate>(ParseDelegateCache);
+                newCache[type] = parseFn;
+
+            } while (!ReferenceEquals(
+                Interlocked.CompareExchange(ref ParseDelegateCache, newCache, snapshot), snapshot));
+
+			return parseFn.Invoke;
+		}
+	}
+
+	internal static class DeserializeArrayWithElements<T, TSerializer>
+		where TSerializer : ITypeSerializer
+	{
+		private static readonly ITypeSerializer Serializer = JsWriter.GetTypeSerializer<TSerializer>();
+
+		public static T[] ParseGenericArray(string value, ParseStringDelegate elementParseFn)
+		{
+			if ((value = DeserializeListWithElements<TSerializer>.StripList(value)) == null) return null;
+			if (value == string.Empty) return new T[0];
+
+			if (value[0] == JsWriter.MapStartChar)
+			{
+				var itemValues = new List<string>();
+				var i = 0;
+				do
+				{
+					itemValues.Add(Serializer.EatTypeValue(value, ref i));
+				} while (++i < value.Length);
+
+				var results = new T[itemValues.Count];
+				for (var j=0; j < itemValues.Count; j++)
+				{
+					results[j] = (T)elementParseFn(itemValues[j]);
+				}
+				return results;
+			}
+			else
+			{
+				var to = new List<T>();
+				var valueLength = value.Length;
+
+				var i = 0;
+				while (i < valueLength)
+				{
+					var elementValue = Serializer.EatValue(value, ref i);
+					var listValue = elementValue;
+					to.Add((T)elementParseFn(listValue));
+					Serializer.EatItemSeperatorOrMapEndChar(value, ref i);
+				}
+
+				return to.ToArray();
+			}
+		}
+	}
+
+	internal static class DeserializeArray<TSerializer>
+		where TSerializer : ITypeSerializer
+	{
+		private static Dictionary<Type, ParseStringDelegate> ParseDelegateCache = new Dictionary<Type, ParseStringDelegate>();
+
+		public static ParseStringDelegate GetParseFn(Type type)
+		{
+			ParseStringDelegate parseFn;
+            if (ParseDelegateCache.TryGetValue(type, out parseFn)) return parseFn;
+
+            var genericType = typeof(DeserializeArray<,>).MakeGenericType(type, typeof(TSerializer));
+            var mi = genericType.GetMethod("GetParseFn", BindingFlags.Public | BindingFlags.Static);
+            var parseFactoryFn = (Func<ParseStringDelegate>)Delegate.CreateDelegate(
+                typeof(Func<ParseStringDelegate>), mi);
+            parseFn = parseFactoryFn();
+            
+            Dictionary<Type, ParseStringDelegate> snapshot, newCache;
+            do
+            {
+                snapshot = ParseDelegateCache;
+                newCache = new Dictionary<Type, ParseStringDelegate>(ParseDelegateCache);
+                newCache[type] = parseFn;
+
+            } while (!ReferenceEquals(
+                Interlocked.CompareExchange(ref ParseDelegateCache, newCache, snapshot), snapshot));
+
+			return parseFn;
+		}
+	}
+
+	internal static class DeserializeArray<T, TSerializer>
+		where TSerializer : ITypeSerializer
+	{
+		private static readonly ITypeSerializer Serializer = JsWriter.GetTypeSerializer<TSerializer>();
+
+		private static readonly ParseStringDelegate CacheFn;
+
+		static DeserializeArray()
+		{
+			CacheFn = GetParseFn();
+		}
+
+		public static ParseStringDelegate Parse
+		{
+			get { return CacheFn; }
+		}
+
+		public static ParseStringDelegate GetParseFn()
+		{
+			var type = typeof (T);
+			if (!type.IsArray)
+				throw new ArgumentException(string.Format("Type {0} is not an Array type", type.FullName));
+
+			if (type == typeof(string[]))
+				return ParseStringArray;
+			if (type == typeof(byte[]))
+				return ParseByteArray;
+
+			var elementType = type.GetElementType();
+			var elementParseFn = Serializer.GetParseFn(elementType);
+			if (elementParseFn != null)
+			{
+				var parseFn = DeserializeArrayWithElements<TSerializer>.GetParseFn(elementType);
+				return value => parseFn(value, elementParseFn);
+			}
+			return null;
+		}
+
+		public static string[] ParseStringArray(string value)
+		{
+			if ((value = DeserializeListWithElements<TSerializer>.StripList(value)) == null) return null;
+			return value == string.Empty
+					? new string[0]
+					: DeserializeListWithElements<TSerializer>.ParseStringList(value).ToArray();
+		}
+		
+		public static byte[] ParseByteArray(string value)
+		{
+			if ((value = DeserializeListWithElements<TSerializer>.StripList(value)) == null) return null;
+			if ((value = Serializer.ParseRawString(value)) == null) return null;
+			return value == string.Empty
+			       	? new byte[0]
+			       	: Convert.FromBase64String(value);
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeBuiltin.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeBuiltin.cs
new file mode 100644
index 0000000..66cda71
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeBuiltin.cs
@@ -0,0 +1,114 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.Globalization;
+
+namespace ServiceStack.Text.Common
+{
+	public static class DeserializeBuiltin<T>
+	{
+		private static readonly ParseStringDelegate CachedParseFn;
+		static DeserializeBuiltin()
+		{
+			CachedParseFn = GetParseFn();
+		}
+
+		public static ParseStringDelegate Parse
+		{
+			get { return CachedParseFn; }
+		}
+
+		private static ParseStringDelegate GetParseFn()
+		{
+			//Note the generic typeof(T) is faster than using var type = typeof(T)
+			if (typeof(T) == typeof(bool))
+				return value => bool.Parse(value);
+			if (typeof(T) == typeof(byte))
+				return value => byte.Parse(value);
+			if (typeof(T) == typeof(sbyte))
+				return value => sbyte.Parse(value);
+			if (typeof(T) == typeof(short))
+				return value => short.Parse(value);
+			if (typeof(T) == typeof(int))
+				return value => int.Parse(value);
+			if (typeof(T) == typeof(long))
+				return value => long.Parse(value);
+			if (typeof(T) == typeof(float))
+				return value => float.Parse(value, CultureInfo.InvariantCulture);
+			if (typeof(T) == typeof(double))
+				return value => double.Parse(value, CultureInfo.InvariantCulture);
+			if (typeof(T) == typeof(decimal))
+				return value => decimal.Parse(value, CultureInfo.InvariantCulture);
+
+			if (typeof(T) == typeof(Guid))
+				return value => new Guid(value);
+			if (typeof(T) == typeof(DateTime) || typeof(T) == typeof(DateTime?))
+				return value => DateTimeSerializer.ParseShortestXsdDateTime(value);
+			if (typeof(T) == typeof(TimeSpan))
+				return value => TimeSpan.Parse(value);
+#if !MONOTOUCH && !SILVERLIGHT && !XBOX
+			if (typeof(T) == typeof(System.Data.Linq.Binary))
+				return value => new System.Data.Linq.Binary(Convert.FromBase64String(value));
+#endif				
+			if (typeof(T) == typeof(char))
+			{
+				char cValue;
+				return value => char.TryParse(value, out cValue) ? cValue : '\0';
+			}
+			if (typeof(T) == typeof(ushort))
+				return value => ushort.Parse(value);
+			if (typeof(T) == typeof(uint))
+				return value => uint.Parse(value);
+			if (typeof(T) == typeof(ulong))
+				return value => ulong.Parse(value);
+
+			if (typeof(T) == typeof(bool?))
+				return value => value == null ? (bool?)null : bool.Parse(value);
+			if (typeof(T) == typeof(byte?))
+				return value => value == null ? (byte?)null : byte.Parse(value);
+			if (typeof(T) == typeof(sbyte?))
+				return value => value == null ? (sbyte?)null : sbyte.Parse(value);
+			if (typeof(T) == typeof(short?))
+				return value => value == null ? (short?)null : short.Parse(value);
+			if (typeof(T) == typeof(int?))
+				return value => value == null ? (int?)null : int.Parse(value);
+			if (typeof(T) == typeof(long?))
+				return value => value == null ? (long?)null : long.Parse(value);
+			if (typeof(T) == typeof(float?))
+				return value => value == null ? (float?)null : float.Parse(value, CultureInfo.InvariantCulture);
+			if (typeof(T) == typeof(double?))
+				return value => value == null ? (double?)null : double.Parse(value, CultureInfo.InvariantCulture);
+			if (typeof(T) == typeof(decimal?))
+				return value => value == null ? (decimal?)null : decimal.Parse(value, CultureInfo.InvariantCulture);
+			
+			if (typeof(T) == typeof(TimeSpan?))
+				return value => value == null ? (TimeSpan?)null : TimeSpan.Parse(value);
+			if (typeof(T) == typeof(Guid?))
+				return value => value == null ? (Guid?)null : new Guid(value);				
+			if (typeof(T) == typeof(ushort?))
+				return value => value == null ? (ushort?)null : ushort.Parse(value);
+			if (typeof(T) == typeof(uint?))
+				return value => value == null ? (uint?)null : uint.Parse(value);
+			if (typeof(T) == typeof(ulong?))
+				return value => value == null ? (ulong?)null : ulong.Parse(value);
+			
+			if (typeof(T) == typeof(char?))
+			{
+				char cValue;
+				return value => value == null ? (char?)null : char.TryParse(value, out cValue) ? cValue : '\0';
+			}
+			
+			return null;
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeCollection.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeCollection.cs
new file mode 100644
index 0000000..0c87e26
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeCollection.cs
@@ -0,0 +1,122 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Threading;
+
+namespace ServiceStack.Text.Common
+{
+	internal static class DeserializeCollection<TSerializer>
+		where TSerializer : ITypeSerializer
+	{
+		private static readonly ITypeSerializer Serializer = JsWriter.GetTypeSerializer<TSerializer>();
+
+		public static ParseStringDelegate GetParseMethod(Type type)
+		{
+			var collectionInterface = type.GetTypeWithGenericInterfaceOf(typeof(ICollection<>));
+			if (collectionInterface == null)
+				throw new ArgumentException(string.Format("Type {0} is not of type ICollection<>", type.FullName));
+
+			//optimized access for regularly used types
+			if (type.HasInterface(typeof(ICollection<string>)))
+				return value => ParseStringCollection(value, type);
+
+			if (type.HasInterface(typeof(ICollection<int>)))
+				return value => ParseIntCollection(value, type);
+
+			var elementType =  collectionInterface.GetGenericArguments()[0];
+
+			var supportedTypeParseMethod = Serializer.GetParseFn(elementType);
+			if (supportedTypeParseMethod != null)
+			{
+				var createCollectionType = type.HasAnyTypeDefinitionsOf(typeof(ICollection<>))
+					? null : type;
+
+				return value => ParseCollectionType(value, createCollectionType, elementType, supportedTypeParseMethod);
+			}
+
+			return null;
+		}
+
+		public static ICollection<string> ParseStringCollection(string value, Type createType)
+		{
+			var items = DeserializeArrayWithElements<string, TSerializer>.ParseGenericArray(value, Serializer.ParseString);
+			return CreateAndPopulate(createType, items);
+		}
+
+		public static ICollection<int> ParseIntCollection(string value, Type createType)
+		{
+			var items = DeserializeArrayWithElements<int, TSerializer>.ParseGenericArray(value, x => int.Parse(x));
+			return CreateAndPopulate(createType, items);
+		}
+
+		public static ICollection<T> ParseCollection<T>(string value, Type createType, ParseStringDelegate parseFn)
+		{
+			if (value == null) return null;
+
+			var items = DeserializeArrayWithElements<T, TSerializer>.ParseGenericArray(value, parseFn);
+			return CreateAndPopulate(createType, items);
+		}
+
+		private static ICollection<T> CreateAndPopulate<T>(Type ofCollectionType, T[] withItems)
+		{
+			if (ofCollectionType == null) return new List<T>(withItems);
+
+			var genericTypeDefinition = ofCollectionType.IsGenericType()
+				? ofCollectionType.GetGenericTypeDefinition()
+				: null;
+#if !XBOX
+			if (genericTypeDefinition == typeof(HashSet<T>))
+				return new HashSet<T>(withItems);
+#endif
+			if (genericTypeDefinition == typeof(LinkedList<T>))
+				return new LinkedList<T>(withItems);
+
+			var collection = (ICollection<T>)ofCollectionType.CreateInstance();
+			foreach (var item in withItems)
+			{
+				collection.Add(item);
+			}
+			return collection;
+		}
+
+		private static Dictionary<Type, ParseCollectionDelegate> ParseDelegateCache 
+			= new Dictionary<Type, ParseCollectionDelegate>();
+
+		private delegate object ParseCollectionDelegate(string value, Type createType, ParseStringDelegate parseFn);
+
+		public static object ParseCollectionType(string value, Type createType, Type elementType, ParseStringDelegate parseFn)
+		{
+			ParseCollectionDelegate parseDelegate;
+			if (ParseDelegateCache.TryGetValue(elementType, out parseDelegate))
+                return parseDelegate(value, createType, parseFn);
+
+            var mi = typeof(DeserializeCollection<TSerializer>).GetMethod("ParseCollection", BindingFlags.Static | BindingFlags.Public);
+            var genericMi = mi.MakeGenericMethod(new[] { elementType });
+            parseDelegate = (ParseCollectionDelegate)Delegate.CreateDelegate(typeof(ParseCollectionDelegate), genericMi);
+
+            Dictionary<Type, ParseCollectionDelegate> snapshot, newCache;
+            do
+            {
+                snapshot = ParseDelegateCache;
+                newCache = new Dictionary<Type, ParseCollectionDelegate>(ParseDelegateCache);
+                newCache[elementType] = parseDelegate;
+
+            } while (!ReferenceEquals(
+                Interlocked.CompareExchange(ref ParseDelegateCache, newCache, snapshot), snapshot));
+            
+            return parseDelegate(value, createType, parseFn);
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeDictionary.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeDictionary.cs
new file mode 100644
index 0000000..8cf78c3
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeDictionary.cs
@@ -0,0 +1,194 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Runtime.Serialization;
+using System.Text;
+using System.Threading;
+using ServiceStack.Text.Json;
+
+namespace ServiceStack.Text.Common
+{
+	internal static class DeserializeDictionary<TSerializer>
+		where TSerializer : ITypeSerializer
+	{
+		private static readonly ITypeSerializer Serializer = JsWriter.GetTypeSerializer<TSerializer>();
+
+		const int KeyIndex = 0;
+		const int ValueIndex = 1;
+
+		public static ParseStringDelegate GetParseMethod(Type type)
+		{
+			var mapInterface = type.GetTypeWithGenericInterfaceOf(typeof(IDictionary<,>));
+			if (mapInterface == null)
+				throw new ArgumentException(string.Format("Type {0} is not of type IDictionary<,>", type.FullName));
+
+			//optimized access for regularly used types
+			if (type == typeof(Dictionary<string, string>))
+			{
+				return ParseStringDictionary;
+			}
+
+			var dictionaryArgs = mapInterface.GetGenericArguments();
+
+			var keyTypeParseMethod = Serializer.GetParseFn(dictionaryArgs[KeyIndex]);
+			if (keyTypeParseMethod == null) return null;
+
+			var valueTypeParseMethod = Serializer.GetParseFn(dictionaryArgs[ValueIndex]);
+			if (valueTypeParseMethod == null) return null;
+
+			var createMapType = type.HasAnyTypeDefinitionsOf(typeof(Dictionary<,>), typeof(IDictionary<,>))
+				? null : type;
+
+			return value => ParseDictionaryType(value, createMapType, dictionaryArgs, keyTypeParseMethod, valueTypeParseMethod);
+		}
+
+		public static Dictionary<string, string> ParseStringDictionary(string value)
+		{
+			var index = VerifyAndGetStartIndex(value, typeof(Dictionary<string, string>));
+
+			var result = new Dictionary<string, string>();
+
+			if (value == JsWriter.EmptyMap) return result;
+
+			var valueLength = value.Length;
+			while (index < valueLength)
+			{
+				var keyValue = Serializer.EatMapKey(value, ref index);
+				Serializer.EatMapKeySeperator(value, ref index);
+				var elementValue = Serializer.EatValue(value, ref index);
+
+				var mapKey = keyValue;
+				var mapValue = elementValue;
+
+				result[mapKey] = mapValue;
+
+				Serializer.EatItemSeperatorOrMapEndChar(value, ref index);
+			}
+
+			return result;
+		}
+
+		public static IDictionary<TKey, TValue> ParseDictionary<TKey, TValue>(
+			string value, Type createMapType,
+			ParseStringDelegate parseKeyFn, ParseStringDelegate parseValueFn)
+		{
+			if (value == null) return null;
+
+			var tryToParseItemsAsDictionaries =
+				JsConfig.ConvertObjectTypesIntoStringDictionary && typeof(TValue) == typeof(object);
+
+			var index = VerifyAndGetStartIndex(value, createMapType);
+
+			var to = (createMapType == null)
+				? new Dictionary<TKey, TValue>()
+				: (IDictionary<TKey, TValue>)ReflectionExtensions.CreateInstance(createMapType);
+
+			if (value == JsWriter.EmptyMap) return to;
+
+			var valueLength = value.Length;
+			while (index < valueLength)
+			{
+				var keyValue = Serializer.EatMapKey(value, ref index);
+				Serializer.EatMapKeySeperator(value, ref index);
+				var elementValue = Serializer.EatValue(value, ref index);
+
+				var mapKey = (TKey)parseKeyFn(keyValue);
+				var mapValue = (TValue)parseValueFn(elementValue);
+
+				if (tryToParseItemsAsDictionaries)
+				{
+					var mapValueString = mapValue as string;
+					var tryParseValueAsDictionary = JsonUtils.IsJsObject(mapValueString);
+					if (tryParseValueAsDictionary)
+					{
+						var tmpMap = ParseDictionary<TKey, TValue>(mapValueString, createMapType, parseKeyFn, parseValueFn);
+						to[mapKey] = (tmpMap != null && tmpMap.Count > 0)
+							? (TValue)tmpMap
+							: to[mapKey] = mapValue;
+					}
+					else
+					{
+						to[mapKey] = mapValue;
+					}
+				}
+				else
+				{
+					to[mapKey] = mapValue;
+				}
+
+				Serializer.EatItemSeperatorOrMapEndChar(value, ref index);
+			}
+
+			return to;
+		}
+
+		private static int VerifyAndGetStartIndex(string value, Type createMapType)
+		{
+			var index = 0;
+			if (!Serializer.EatMapStartChar(value, ref index))
+			{
+				//Don't throw ex because some KeyValueDataContractDeserializer don't have '{}'
+				Tracer.Instance.WriteDebug("WARN: Map definitions should start with a '{0}', expecting serialized type '{1}', got string starting with: {2}",
+					JsWriter.MapStartChar, createMapType != null ? createMapType.Name : "Dictionary<,>", value.Substring(0, value.Length < 50 ? value.Length : 50));
+			}
+			return index;
+		}
+
+		private static Dictionary<string, ParseDictionaryDelegate> ParseDelegateCache
+			= new Dictionary<string, ParseDictionaryDelegate>();
+
+		private delegate object ParseDictionaryDelegate(string value, Type createMapType,
+			ParseStringDelegate keyParseFn, ParseStringDelegate valueParseFn);
+
+		public static object ParseDictionaryType(string value, Type createMapType, Type[] argTypes,
+			ParseStringDelegate keyParseFn, ParseStringDelegate valueParseFn)
+		{
+
+			ParseDictionaryDelegate parseDelegate;
+			var key = GetTypesKey(argTypes);
+			if (ParseDelegateCache.TryGetValue(key, out parseDelegate))
+                return parseDelegate(value, createMapType, keyParseFn, valueParseFn);
+
+            var mi = typeof(DeserializeDictionary<TSerializer>).GetMethod("ParseDictionary", BindingFlags.Static | BindingFlags.Public);
+            var genericMi = mi.MakeGenericMethod(argTypes);
+            parseDelegate = (ParseDictionaryDelegate)Delegate.CreateDelegate(typeof(ParseDictionaryDelegate), genericMi);
+
+            Dictionary<string, ParseDictionaryDelegate> snapshot, newCache;
+            do
+            {
+                snapshot = ParseDelegateCache;
+                newCache = new Dictionary<string, ParseDictionaryDelegate>(ParseDelegateCache);
+                newCache[key] = parseDelegate;
+
+            } while (!ReferenceEquals(
+                Interlocked.CompareExchange(ref ParseDelegateCache, newCache, snapshot), snapshot));
+
+			return parseDelegate(value, createMapType, keyParseFn, valueParseFn);
+		}
+
+		private static string GetTypesKey(params Type[] types)
+		{
+			var sb = new StringBuilder(256);
+			foreach (var type in types)
+			{
+				if (sb.Length > 0)
+					sb.Append(">");
+
+				sb.Append(type.FullName);
+			}
+			return sb.ToString();
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeListWithElements.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeListWithElements.cs
new file mode 100644
index 0000000..48658ed
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeListWithElements.cs
@@ -0,0 +1,243 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Reflection;
+using System.Threading;
+
+namespace ServiceStack.Text.Common
+{
+	internal static class DeserializeListWithElements<TSerializer>
+		where TSerializer : ITypeSerializer
+	{
+		internal static readonly ITypeSerializer Serializer = JsWriter.GetTypeSerializer<TSerializer>();
+
+		private static Dictionary<Type, ParseListDelegate> ParseDelegateCache 
+			= new Dictionary<Type, ParseListDelegate>();
+
+		private delegate object ParseListDelegate(string value, Type createListType, ParseStringDelegate parseFn);
+
+		public static Func<string, Type, ParseStringDelegate, object> GetListTypeParseFn(
+			Type createListType, Type elementType, ParseStringDelegate parseFn)
+		{
+			ParseListDelegate parseDelegate;
+			if (ParseDelegateCache.TryGetValue(elementType, out parseDelegate))
+                return parseDelegate.Invoke;
+
+            var genericType = typeof(DeserializeListWithElements<,>).MakeGenericType(elementType, typeof(TSerializer));
+            var mi = genericType.GetMethod("ParseGenericList", BindingFlags.Static | BindingFlags.Public);
+            parseDelegate = (ParseListDelegate)Delegate.CreateDelegate(typeof(ParseListDelegate), mi);
+
+            Dictionary<Type, ParseListDelegate> snapshot, newCache;
+            do
+            {
+                snapshot = ParseDelegateCache;
+                newCache = new Dictionary<Type, ParseListDelegate>(ParseDelegateCache);
+                newCache[elementType] = parseDelegate;
+
+            } while (!ReferenceEquals(
+                Interlocked.CompareExchange(ref ParseDelegateCache, newCache, snapshot), snapshot));
+
+			return parseDelegate.Invoke;
+		}
+
+		internal static string StripList(string value)
+		{
+			if (string.IsNullOrEmpty(value))
+				return null;
+
+			const int startQuotePos = 1;
+			const int endQuotePos = 2;
+			return value[0] == JsWriter.ListStartChar
+			       	? value.Substring(startQuotePos, value.Length - endQuotePos)
+			       	: value;
+		}
+
+		public static List<string> ParseStringList(string value)
+		{
+			if ((value = StripList(value)) == null) return null;
+			if (value == string.Empty) return new List<string>();
+
+			var to = new List<string>();
+			var valueLength = value.Length;
+
+			var i = 0;
+			while (i < valueLength)
+			{
+				var elementValue = Serializer.EatValue(value, ref i);
+				var listValue = elementValue;
+				to.Add(listValue);
+				Serializer.EatItemSeperatorOrMapEndChar(value, ref i);
+			}
+
+			return to;
+		}
+
+		public static List<int> ParseIntList(string value)
+		{
+			if ((value = StripList(value)) == null) return null;
+			if (value == string.Empty) return new List<int>();
+
+			var intParts = value.Split(JsWriter.ItemSeperator);
+			var intValues = new List<int>(intParts.Length);
+			foreach (var intPart in intParts)
+			{
+				intValues.Add(int.Parse(intPart));
+			}
+			return intValues;
+		}
+	}
+
+	internal static class DeserializeListWithElements<T, TSerializer>
+		where TSerializer : ITypeSerializer
+	{
+		private static readonly ITypeSerializer Serializer = JsWriter.GetTypeSerializer<TSerializer>();
+
+		public static ICollection<T> ParseGenericList(string value, Type createListType, ParseStringDelegate parseFn)
+		{
+			if ((value = DeserializeListWithElements<TSerializer>.StripList(value)) == null) return null;
+
+            var isReadOnly = createListType != null 
+                && (createListType.IsGenericType && createListType.GetGenericTypeDefinition() == typeof(ReadOnlyCollection<>));
+
+			var to = (createListType == null || isReadOnly)
+			    ? new List<T>()
+			    : (ICollection<T>)createListType.CreateInstance();
+
+			if (value == string.Empty) return to;
+
+			if (!string.IsNullOrEmpty(value))
+			{
+				if (value[0] == JsWriter.MapStartChar)
+				{
+					var i = 0;
+					do
+					{
+						var itemValue = Serializer.EatTypeValue(value, ref i);
+						to.Add((T)parseFn(itemValue));
+					} while (++i < value.Length);
+				}
+				else
+				{
+					var valueLength = value.Length;
+
+					var i = 0;
+					while (i < valueLength)
+					{
+						var elementValue = Serializer.EatValue(value, ref i);
+						var listValue = elementValue;
+						to.Add((T)parseFn(listValue));
+						Serializer.EatItemSeperatorOrMapEndChar(value, ref i);
+					}
+
+				}
+			}
+			
+			//TODO: 8-10-2011 -- this CreateInstance call should probably be moved over to ReflectionExtensions, 
+			//but not sure how you'd like to go about caching constructors with parameters -- I would probably build a NewExpression, .Compile to a LambdaExpression and cache
+			return isReadOnly ? (ICollection<T>)Activator.CreateInstance(createListType, to) : to;
+		}
+	}
+
+	internal static class DeserializeList<T, TSerializer>
+		where TSerializer : ITypeSerializer
+	{
+		private readonly static ParseStringDelegate CacheFn;
+
+		static DeserializeList()
+		{
+			CacheFn = GetParseFn();
+		}
+
+		public static ParseStringDelegate Parse
+		{
+			get { return CacheFn; }
+		}
+
+		public static ParseStringDelegate GetParseFn()
+		{
+			var listInterface = typeof(T).GetTypeWithGenericInterfaceOf(typeof(IList<>));
+			if (listInterface == null)
+				throw new ArgumentException(string.Format("Type {0} is not of type IList<>", typeof(T).FullName));
+
+			//optimized access for regularly used types
+			if (typeof(T) == typeof(List<string>))
+				return DeserializeListWithElements<TSerializer>.ParseStringList;
+
+			if (typeof(T) == typeof(List<int>))
+				return DeserializeListWithElements<TSerializer>.ParseIntList;
+
+			var elementType = listInterface.GetGenericArguments()[0];
+
+			var supportedTypeParseMethod = DeserializeListWithElements<TSerializer>.Serializer.GetParseFn(elementType);
+			if (supportedTypeParseMethod != null)
+			{
+				var createListType = typeof(T).HasAnyTypeDefinitionsOf(typeof(List<>), typeof(IList<>))
+					? null : typeof(T);
+
+				var parseFn = DeserializeListWithElements<TSerializer>.GetListTypeParseFn(createListType, elementType, supportedTypeParseMethod);
+				return value => parseFn(value, createListType, supportedTypeParseMethod);
+			}
+
+			return null;
+		}
+
+	}
+
+	internal static class DeserializeEnumerable<T, TSerializer>
+		where TSerializer : ITypeSerializer
+	{
+		private readonly static ParseStringDelegate CacheFn;
+
+		static DeserializeEnumerable()
+		{
+			CacheFn = GetParseFn();
+		}
+
+		public static ParseStringDelegate Parse
+		{
+			get { return CacheFn; }
+		}
+
+		public static ParseStringDelegate GetParseFn()
+		{
+			var enumerableInterface = typeof(T).GetTypeWithGenericInterfaceOf(typeof(IEnumerable<>));
+			if (enumerableInterface == null)
+				throw new ArgumentException(string.Format("Type {0} is not of type IEnumerable<>", typeof(T).FullName));
+
+			//optimized access for regularly used types
+			if (typeof(T) == typeof(IEnumerable<string>))
+				return DeserializeListWithElements<TSerializer>.ParseStringList;
+
+			if (typeof(T) == typeof(IEnumerable<int>))
+				return DeserializeListWithElements<TSerializer>.ParseIntList;
+
+			var elementType = enumerableInterface.GetGenericArguments()[0];
+
+			var supportedTypeParseMethod = DeserializeListWithElements<TSerializer>.Serializer.GetParseFn(elementType);
+			if (supportedTypeParseMethod != null)
+			{
+				const Type createListTypeWithNull = null; //Use conversions outside this class. see: Queue
+
+				var parseFn = DeserializeListWithElements<TSerializer>.GetListTypeParseFn(
+					createListTypeWithNull, elementType, supportedTypeParseMethod);
+
+				return value => parseFn(value, createListTypeWithNull, supportedTypeParseMethod);
+			}
+
+			return null;
+		}
+
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeSpecializedCollections.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeSpecializedCollections.cs
new file mode 100644
index 0000000..43da398
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeSpecializedCollections.cs
@@ -0,0 +1,212 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Linq;
+using System.Reflection;
+
+namespace ServiceStack.Text.Common
+{
+	internal static class DeserializeSpecializedCollections<T, TSerializer>
+		where TSerializer : ITypeSerializer
+	{
+		private readonly static ParseStringDelegate CacheFn;
+
+		static DeserializeSpecializedCollections()
+		{
+			CacheFn = GetParseFn();
+		}
+
+		public static ParseStringDelegate Parse
+		{
+			get { return CacheFn; }
+		}
+
+		public static ParseStringDelegate GetParseFn()
+		{
+			if (typeof(T).HasAnyTypeDefinitionsOf(typeof(Queue<>)))
+			{
+				if (typeof(T) == typeof(Queue<string>))
+					return ParseStringQueue;
+
+				if (typeof(T) == typeof(Queue<int>))
+					return ParseIntQueue;
+
+				return GetGenericQueueParseFn();
+			}
+
+			if (typeof(T).HasAnyTypeDefinitionsOf(typeof(Stack<>)))
+			{
+				if (typeof(T) == typeof(Stack<string>))
+					return ParseStringStack;
+
+				if (typeof(T) == typeof(Stack<int>))
+					return ParseIntStack;
+
+				return GetGenericStackParseFn();
+			}
+
+#if !SILVERLIGHT
+			if (typeof(T) == typeof(StringCollection))
+			{
+				return ParseStringCollection<TSerializer>;
+			}
+#endif
+
+			return GetGenericEnumerableParseFn();
+		}
+
+		public static Queue<string> ParseStringQueue(string value)
+		{
+			var parse = (IEnumerable<string>)DeserializeList<List<string>, TSerializer>.Parse(value);
+			return new Queue<string>(parse);
+		}
+
+		public static Queue<int> ParseIntQueue(string value)
+		{
+			var parse = (IEnumerable<int>)DeserializeList<List<int>, TSerializer>.Parse(value);
+			return new Queue<int>(parse);
+		}
+
+#if !SILVERLIGHT
+		public static StringCollection ParseStringCollection<TSerializer>(string value) where TSerializer : ITypeSerializer
+		{
+			if ((value = DeserializeListWithElements<TSerializer>.StripList(value)) == null) return null;
+			return value == String.Empty
+			       ? new StringCollection()
+			       : ToStringCollection(DeserializeListWithElements<TSerializer>.ParseStringList(value));
+		}
+
+		public static StringCollection ToStringCollection(List<string> items)
+		{
+			var to = new StringCollection();
+			foreach (var item in items)
+			{
+				to.Add(item);
+			}
+			return to;
+		}
+#endif
+
+		internal static ParseStringDelegate GetGenericQueueParseFn()
+		{
+			var enumerableInterface = typeof(T).GetTypeWithGenericInterfaceOf(typeof(IEnumerable<>));
+			var elementType = enumerableInterface.GetGenericArguments()[0];
+
+			var genericType = typeof(SpecializedQueueElements<>).MakeGenericType(elementType);
+
+			var mi = genericType.GetMethod("ConvertToQueue", BindingFlags.Static | BindingFlags.Public);
+
+			var convertToQueue = (ConvertObjectDelegate)Delegate.CreateDelegate(typeof(ConvertObjectDelegate), mi);
+
+			var parseFn = DeserializeEnumerable<T, TSerializer>.GetParseFn();
+
+			return x => convertToQueue(parseFn(x));
+		}
+
+		public static Stack<string> ParseStringStack(string value)
+		{
+			var parse = (IEnumerable<string>)DeserializeList<List<string>, TSerializer>.Parse(value);
+			return new Stack<string>(parse);
+		}
+
+		public static Stack<int> ParseIntStack(string value)
+		{
+			var parse = (IEnumerable<int>)DeserializeList<List<int>, TSerializer>.Parse(value);
+			return new Stack<int>(parse);
+		}
+
+		internal static ParseStringDelegate GetGenericStackParseFn()
+		{
+			var enumerableInterface = typeof(T).GetTypeWithGenericInterfaceOf(typeof(IEnumerable<>));
+			var elementType = enumerableInterface.GetGenericArguments()[0];
+
+			var genericType = typeof(SpecializedQueueElements<>).MakeGenericType(elementType);
+
+			var mi = genericType.GetMethod("ConvertToStack", BindingFlags.Static | BindingFlags.Public);
+
+			var convertToQueue = (ConvertObjectDelegate)Delegate.CreateDelegate(typeof(ConvertObjectDelegate), mi);
+
+			var parseFn = DeserializeEnumerable<T, TSerializer>.GetParseFn();
+
+			return x => convertToQueue(parseFn(x));
+		}
+
+		public static ParseStringDelegate GetGenericEnumerableParseFn()
+		{
+			var enumerableInterface = typeof(T).GetTypeWithGenericInterfaceOf(typeof(IEnumerable<>));
+			var elementType = enumerableInterface.GetGenericArguments()[0];
+
+			var genericType = typeof(SpecializedEnumerableElements<,>).MakeGenericType(typeof(T), elementType);
+
+			var fi = genericType.GetField("ConvertFn", BindingFlags.Static | BindingFlags.Public);
+
+			var convertFn = fi.GetValue(null) as ConvertObjectDelegate;
+			if (convertFn == null) return null;
+
+			var parseFn = DeserializeEnumerable<T, TSerializer>.GetParseFn();
+
+			return x => convertFn(parseFn(x));
+		}
+	}
+
+	internal class SpecializedQueueElements<T>
+	{
+		public static Queue<T> ConvertToQueue(object enumerable)
+		{
+			if (enumerable == null) return null;
+			return new Queue<T>((IEnumerable<T>)enumerable);
+		}
+
+		public static Stack<T> ConvertToStack(object enumerable)
+		{
+			if (enumerable == null) return null;
+			return new Stack<T>((IEnumerable<T>)enumerable);
+		}
+	}
+
+	internal class SpecializedEnumerableElements<TCollection, T>
+	{
+		public static ConvertObjectDelegate ConvertFn;
+
+		static SpecializedEnumerableElements()
+		{
+			foreach (var ctorInfo in typeof(TCollection).GetConstructors())
+			{
+				var ctorParams = ctorInfo.GetParameters();
+				if (ctorParams.Length != 1) continue;
+				var ctorParam = ctorParams[0];
+				if (typeof(IEnumerable).IsAssignableFrom(ctorParam.ParameterType)
+					|| ctorParam.ParameterType.IsOrHasGenericInterfaceTypeOf(typeof(IEnumerable<>)))
+				{
+					ConvertFn = fromObject => {
+						var to = Activator.CreateInstance(typeof(TCollection), fromObject);
+						return to;
+					};
+					return;
+				}
+			}
+
+			if (typeof(TCollection).IsOrHasGenericInterfaceTypeOf(typeof(ICollection<>)))
+			{
+				ConvertFn = ConvertFromCollection;
+			}
+		}
+
+		public static object Convert(object enumerable)
+		{
+			return ConvertFn(enumerable);
+		}
+
+		public static object ConvertFromCollection(object enumerable)
+		{
+			var to = (ICollection<T>)typeof(TCollection).CreateInstance();
+			var from = (IEnumerable<T>)enumerable;
+			foreach (var item in from)
+			{
+				to.Add(item);
+			}
+			return to;
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeType.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeType.cs
new file mode 100644
index 0000000..118a37c
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeType.cs
@@ -0,0 +1,259 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+#if !XBOX && !MONOTOUCH && !SILVERLIGHT
+using System.Reflection.Emit;
+#endif
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Runtime.Serialization;
+using System.Linq;
+
+namespace ServiceStack.Text.Common
+{
+	internal static class DeserializeType<TSerializer>
+		where TSerializer : ITypeSerializer
+	{
+		private static readonly ITypeSerializer Serializer = JsWriter.GetTypeSerializer<TSerializer>();
+
+		private static readonly string TypeAttrInObject = Serializer.TypeAttrInObject;
+
+		public static ParseStringDelegate GetParseMethod(TypeConfig typeConfig)
+		{
+			var type = typeConfig.Type;
+
+			if (!type.IsClass || type.IsAbstract || type.IsInterface) return null;
+
+			var propertyInfos = type.GetSerializableProperties();
+			if (propertyInfos.Length == 0)
+			{
+				var emptyCtorFn = ReflectionExtensions.GetConstructorMethodToCache(type);
+				return value => emptyCtorFn();
+			}
+
+			var map = new Dictionary<string, TypeAccessor>(StringComparer.OrdinalIgnoreCase);
+
+			var isDataContract = type.GetCustomAttributes(typeof(DataContractAttribute), false).Any();
+
+			foreach (var propertyInfo in propertyInfos)
+			{
+				var propertyName = propertyInfo.Name;
+				if (isDataContract)
+				{
+					var dcsDataMember = propertyInfo.GetCustomAttributes(typeof(DataMemberAttribute), false).FirstOrDefault() as DataMemberAttribute;
+					if (dcsDataMember != null && dcsDataMember.Name != null)
+					{
+						propertyName = dcsDataMember.Name;
+					}
+				}
+				map[propertyName] = TypeAccessor.Create(Serializer, typeConfig, propertyInfo);
+			}
+
+			var ctorFn = ReflectionExtensions.GetConstructorMethodToCache(type);
+
+			return typeof(TSerializer) == typeof(Json.JsonTypeSerializer)
+				? (ParseStringDelegate)(value => DeserializeTypeRefJson.StringToType(type, value, ctorFn, map))
+				: value => DeserializeTypeRefJsv.StringToType(type, value, ctorFn, map);
+		}
+
+		public static object ObjectStringToType(string strType)
+		{
+			var type = ExtractType(strType);
+			if (type != null)
+			{
+				var parseFn = Serializer.GetParseFn(type);
+				var propertyValue = parseFn(strType);
+				return propertyValue;
+			}
+
+			return strType;
+		}
+
+		public static Type ExtractType(string strType)
+		{
+			if (strType != null
+				&& strType.Length > TypeAttrInObject.Length
+				&& strType.Substring(0, TypeAttrInObject.Length) == TypeAttrInObject)
+			{
+				var propIndex = TypeAttrInObject.Length;
+				var typeName = Serializer.EatValue(strType, ref propIndex);
+				var type = AssemblyUtils.FindType(typeName);
+
+				if (type == null)
+					Tracer.Instance.WriteWarning("Could not find type: " + typeName);
+
+				return type;
+			}
+			return null;
+		}
+
+		public static object ParseAbstractType<T>(string value)
+		{
+			if (typeof(T).IsAbstract)
+			{
+				if (string.IsNullOrEmpty(value)) return null;
+				var concreteType = ExtractType(value);
+				if (concreteType != null)
+				{
+					return Serializer.GetParseFn(concreteType)(value);
+				}
+				Tracer.Instance.WriteWarning(
+					"Could not deserialize Abstract Type with unknown concrete type: " + typeof(T).FullName);
+			}
+			return null;
+		}
+
+	}
+
+	internal class TypeAccessor
+	{
+		internal ParseStringDelegate GetProperty;
+		internal SetPropertyDelegate SetProperty;
+
+		public static Type ExtractType(ITypeSerializer Serializer, string strType)
+		{
+			var TypeAttrInObject = Serializer.TypeAttrInObject;
+
+			if (strType != null
+				&& strType.Length > TypeAttrInObject.Length
+				&& strType.Substring(0, TypeAttrInObject.Length) == TypeAttrInObject)
+			{
+				var propIndex = TypeAttrInObject.Length;
+				var typeName = Serializer.EatValue(strType, ref propIndex);
+				var type = AssemblyUtils.FindType(typeName);
+
+				if (type == null)
+					Tracer.Instance.WriteWarning("Could not find type: " + typeName);
+
+				return type;
+			}
+			return null;
+		}
+
+		public static TypeAccessor Create(ITypeSerializer serializer, TypeConfig typeConfig, PropertyInfo propertyInfo)
+		{
+			return new TypeAccessor {
+				GetProperty = serializer.GetParseFn(propertyInfo.PropertyType),
+				SetProperty = GetSetPropertyMethod(typeConfig, propertyInfo),
+			};
+		}
+
+		private static SetPropertyDelegate GetSetPropertyMethod(TypeConfig typeConfig, PropertyInfo propertyInfo)
+		{
+			if (!propertyInfo.CanWrite && !typeConfig.EnableAnonymousFieldSetterses) return null;
+
+			FieldInfo fieldInfo = null;
+			if (!propertyInfo.CanWrite)
+			{
+				//TODO: What string comparison is used in SST?
+				var fieldName = string.Format("<{0}>i__Field", propertyInfo.Name);
+				var fieldInfos = typeConfig.Type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.SetField);
+				foreach (var f in fieldInfos)
+				{
+					if (f.IsInitOnly && f.FieldType == propertyInfo.PropertyType && f.Name == fieldName)
+					{
+						fieldInfo = f;
+						break;
+					}
+				}
+
+				if (fieldInfo == null) return null;
+			}
+
+#if SILVERLIGHT || MONOTOUCH || XBOX
+			if (propertyInfo.CanWrite)
+			{
+				var setMethodInfo = propertyInfo.GetSetMethod(true);
+				return (instance, value) => setMethodInfo.Invoke(instance, new[] { value });
+			}
+			if (fieldInfo == null) return null;
+			return (instance, value) => fieldInfo.SetValue(instance, value);
+#else
+			return propertyInfo.CanWrite
+				? CreateIlPropertySetter(propertyInfo)
+				: CreateIlFieldSetter(fieldInfo);
+#endif
+		}
+
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+
+		private static SetPropertyDelegate CreateIlPropertySetter(PropertyInfo propertyInfo)
+		{
+			var propSetMethod = propertyInfo.GetSetMethod(true);
+			if (propSetMethod == null)
+				return null;
+
+			var setter = CreateDynamicSetMethod(propertyInfo);
+
+			var generator = setter.GetILGenerator();
+			generator.Emit(OpCodes.Ldarg_0);
+			generator.Emit(OpCodes.Castclass, propertyInfo.DeclaringType);
+			generator.Emit(OpCodes.Ldarg_1);
+
+			generator.Emit(propertyInfo.PropertyType.IsClass
+				? OpCodes.Castclass
+				: OpCodes.Unbox_Any,
+				propertyInfo.PropertyType);
+
+			generator.EmitCall(OpCodes.Callvirt, propSetMethod, (Type[])null);
+			generator.Emit(OpCodes.Ret);
+
+			return (SetPropertyDelegate)setter.CreateDelegate(typeof(SetPropertyDelegate));
+		}
+
+		private static SetPropertyDelegate CreateIlFieldSetter(FieldInfo fieldInfo)
+		{
+			var setter = CreateDynamicSetMethod(fieldInfo);
+
+			var generator = setter.GetILGenerator();
+			generator.Emit(OpCodes.Ldarg_0);
+			generator.Emit(OpCodes.Castclass, fieldInfo.DeclaringType);
+			generator.Emit(OpCodes.Ldarg_1);
+
+			generator.Emit(fieldInfo.FieldType.IsClass
+				? OpCodes.Castclass
+				: OpCodes.Unbox_Any,
+				fieldInfo.FieldType);
+
+			generator.Emit(OpCodes.Stfld, fieldInfo);
+			generator.Emit(OpCodes.Ret);
+
+			return (SetPropertyDelegate)setter.CreateDelegate(typeof(SetPropertyDelegate));
+		}
+
+		private static DynamicMethod CreateDynamicSetMethod(MemberInfo memberInfo)
+		{
+			var args = new[] { typeof(object), typeof(object) };
+			var name = string.Format("_{0}{1}_", "Set", memberInfo.Name);
+			var returnType = typeof(void);
+
+			return !memberInfo.DeclaringType.IsInterface
+				? new DynamicMethod(name, returnType, args, memberInfo.DeclaringType, true)
+				: new DynamicMethod(name, returnType, args, memberInfo.Module, true);
+		}
+#endif
+
+		internal static SetPropertyDelegate GetSetPropertyMethod(Type type, PropertyInfo propertyInfo)
+		{
+			if (!propertyInfo.CanWrite) return null;
+
+#if SILVERLIGHT || MONOTOUCH || XBOX
+			var setMethodInfo = propertyInfo.GetSetMethod(true);
+			return (instance, value) => setMethodInfo.Invoke(instance, new[] { value });
+#else
+			return CreateIlPropertySetter(propertyInfo);
+#endif
+		}
+	}
+}
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeTypeRef.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeTypeRef.cs
new file mode 100644
index 0000000..93ff2ef
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeTypeRef.cs
@@ -0,0 +1,114 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace ServiceStack.Text.Common
+{
+	internal static class DeserializeTypeRef
+	{
+		internal static SerializationException CreateSerializationError(Type type, string strType)
+		{
+			return new SerializationException(String.Format(
+			"Type definitions should start with a '{0}', expecting serialized type '{1}', got string starting with: {2}",
+			JsWriter.MapStartChar, type.Name, strType.Substring(0, strType.Length < 50 ? strType.Length : 50)));
+		}
+
+		/* The old Reference generic implementation
+		internal static object StringToType(
+			ITypeSerializer Serializer, 
+			Type type, 
+			string strType, 
+			EmptyCtorDelegate ctorFn, 
+			Dictionary<string, TypeAccessor> typeAccessorMap)
+		{
+			var index = 0;
+
+			if (strType == null)
+				return null;
+
+			if (!Serializer.EatMapStartChar(strType, ref index))
+				throw DeserializeTypeRef.CreateSerializationError(type, strType);
+
+			if (strType == JsWriter.EmptyMap) return ctorFn();
+
+			object instance = null;
+
+			var strTypeLength = strType.Length;
+			while (index < strTypeLength)
+			{
+				var propertyName = Serializer.EatMapKey(strType, ref index);
+
+				Serializer.EatMapKeySeperator(strType, ref index);
+
+				var propertyValueStr = Serializer.EatValue(strType, ref index);
+				var possibleTypeInfo = propertyValueStr != null && propertyValueStr.Length > 1 && propertyValueStr[0] == '_';
+
+				if (possibleTypeInfo && propertyName == JsWriter.TypeAttr)
+				{
+					var typeName = Serializer.ParseString(propertyValueStr);
+					instance = ReflectionExtensions.CreateInstance(typeName);
+					if (instance == null)
+					{
+						Tracer.Instance.WriteWarning("Could not find type: " + propertyValueStr);
+					}
+					else
+					{
+						//If __type info doesn't match, ignore it.
+						if (!type.IsInstanceOfType(instance))
+							instance = null;
+					}
+
+					Serializer.EatItemSeperatorOrMapEndChar(strType, ref index);
+					continue;
+				}
+
+				if (instance == null) instance = ctorFn();
+
+				TypeAccessor typeAccessor;
+				typeAccessorMap.TryGetValue(propertyName, out typeAccessor);
+
+				var propType = possibleTypeInfo ? TypeAccessor.ExtractType(Serializer, propertyValueStr) : null;
+				if (propType != null)
+				{
+					try
+					{
+						if (typeAccessor != null)
+						{
+							var parseFn = Serializer.GetParseFn(propType);
+							var propertyValue = parseFn(propertyValueStr);
+							typeAccessor.SetProperty(instance, propertyValue);
+						}
+
+						Serializer.EatItemSeperatorOrMapEndChar(strType, ref index);
+
+						continue;
+					}
+					catch
+					{
+						Tracer.Instance.WriteWarning("WARN: failed to set dynamic property {0} with: {1}", propertyName, propertyValueStr);
+					}
+				}
+
+				if (typeAccessor != null && typeAccessor.GetProperty != null && typeAccessor.SetProperty != null)
+				{
+					try
+					{
+						var propertyValue = typeAccessor.GetProperty(propertyValueStr);
+						typeAccessor.SetProperty(instance, propertyValue);
+					}
+					catch
+					{
+						Tracer.Instance.WriteWarning("WARN: failed to set property {0} with: {1}", propertyName, propertyValueStr);
+					}
+				}
+
+				Serializer.EatItemSeperatorOrMapEndChar(strType, ref index);
+			}
+
+			return instance;
+		}
+		*/
+	}
+
+	//The same class above but JSON-specific to enable inlining in this hot class.
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeTypeRefJson.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeTypeRefJson.cs
new file mode 100644
index 0000000..8c17205
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeTypeRefJson.cs
@@ -0,0 +1,129 @@
+using System;
+using System.Collections.Generic;
+using ServiceStack.Text.Json;
+
+namespace ServiceStack.Text.Common
+{
+	internal static class DeserializeTypeRefJson
+	{
+		private static readonly JsonTypeSerializer Serializer = (JsonTypeSerializer)JsonTypeSerializer.Instance;
+
+		internal static object StringToType(
+		Type type,
+		string strType,
+		EmptyCtorDelegate ctorFn,
+		Dictionary<string, TypeAccessor> typeAccessorMap)
+		{
+			var index = 0;
+
+			if (strType == null)
+				return null;
+
+			//if (!Serializer.EatMapStartChar(strType, ref index))
+			for (; index < strType.Length; index++) { var c = strType[index]; if (c >= JsonTypeSerializer.WhiteSpaceFlags.Length || !JsonTypeSerializer.WhiteSpaceFlags[c]) break; } //Whitespace inline
+			if (strType[index++] != JsWriter.MapStartChar)
+				throw DeserializeTypeRef.CreateSerializationError(type, strType);
+
+			if (strType == JsWriter.EmptyMap) return ctorFn();
+
+			object instance = null;
+
+			var strTypeLength = strType.Length;
+			while (index < strTypeLength)
+			{
+				var propertyName = JsonTypeSerializer.ParseJsonString(strType, ref index);
+
+				//Serializer.EatMapKeySeperator(strType, ref index);
+				for (; index < strType.Length; index++) { var c = strType[index]; if (c >= JsonTypeSerializer.WhiteSpaceFlags.Length || !JsonTypeSerializer.WhiteSpaceFlags[c]) break; } //Whitespace inline
+				if (strType.Length != index) index++;
+
+				var propertyValueStr = Serializer.EatValue(strType, ref index);
+				var possibleTypeInfo = propertyValueStr != null && propertyValueStr.Length > 1 && propertyValueStr[0] == '_';
+
+				if (possibleTypeInfo && propertyName == JsWriter.TypeAttr)
+				{
+					var typeName = Serializer.ParseString(propertyValueStr);
+
+					instance = ReflectionExtensions.CreateInstance(typeName);
+					if (instance == null)
+					{
+						Tracer.Instance.WriteWarning("Could not find type: " + propertyValueStr);
+					}
+					else
+					{
+						//If __type info doesn't match, ignore it.
+						if (!type.IsInstanceOfType(instance))
+							instance = null;
+					}
+
+					Serializer.EatItemSeperatorOrMapEndChar(strType, ref index);
+					continue;
+				}
+
+				if (instance == null) instance = ctorFn();
+
+				TypeAccessor typeAccessor;
+				typeAccessorMap.TryGetValue(propertyName, out typeAccessor);
+
+				var propType = possibleTypeInfo ? TypeAccessor.ExtractType(Serializer, propertyValueStr) : null;
+				if (propType != null)
+				{
+					try
+					{
+						if (typeAccessor != null)
+						{
+							//var parseFn = Serializer.GetParseFn(propType);
+							var parseFn = JsonReader.GetParseFn(propType);
+
+							var propertyValue = parseFn(propertyValueStr);
+							typeAccessor.SetProperty(instance, propertyValue);
+						}
+
+						//Serializer.EatItemSeperatorOrMapEndChar(strType, ref index);
+						for (; index < strType.Length; index++) { var c = strType[index]; if (c >= JsonTypeSerializer.WhiteSpaceFlags.Length || !JsonTypeSerializer.WhiteSpaceFlags[c]) break; } //Whitespace inline
+						if (index != strType.Length)
+						{
+							var success = strType[index] == JsWriter.ItemSeperator || strType[index] == JsWriter.MapEndChar;
+							index++;
+							if (success)
+								for (; index < strType.Length; index++) { var c = strType[index]; if (c >= JsonTypeSerializer.WhiteSpaceFlags.Length || !JsonTypeSerializer.WhiteSpaceFlags[c]) break; } //Whitespace inline
+						}
+
+						continue;
+					}
+					catch
+					{
+						Tracer.Instance.WriteWarning("WARN: failed to set dynamic property {0} with: {1}", propertyName, propertyValueStr);
+					}
+				}
+
+				if (typeAccessor != null && typeAccessor.GetProperty != null && typeAccessor.SetProperty != null)
+				{
+					try
+					{
+						var propertyValue = typeAccessor.GetProperty(propertyValueStr);
+						typeAccessor.SetProperty(instance, propertyValue);
+					}
+					catch
+					{
+						Tracer.Instance.WriteWarning("WARN: failed to set property {0} with: {1}", propertyName, propertyValueStr);
+					}
+				}
+
+				//Serializer.EatItemSeperatorOrMapEndChar(strType, ref index);
+				for (; index < strType.Length; index++) { var c = strType[index]; if (c >= JsonTypeSerializer.WhiteSpaceFlags.Length || !JsonTypeSerializer.WhiteSpaceFlags[c]) break; } //Whitespace inline
+				if (index != strType.Length)
+				{
+					var success = strType[index] == JsWriter.ItemSeperator || strType[index] == JsWriter.MapEndChar;
+					index++;
+					if (success)
+						for (; index < strType.Length; index++) { var c = strType[index]; if (c >= JsonTypeSerializer.WhiteSpaceFlags.Length || !JsonTypeSerializer.WhiteSpaceFlags[c]) break; } //Whitespace inline
+				}
+
+			}
+
+			return instance;
+		}
+
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeTypeRefJsv.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeTypeRefJsv.cs
new file mode 100644
index 0000000..32bfeed
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeTypeRefJsv.cs
@@ -0,0 +1,113 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using ServiceStack.Text.Jsv;
+
+namespace ServiceStack.Text.Common
+{
+	internal static class DeserializeTypeRefJsv
+	{
+		private static readonly JsvTypeSerializer Serializer = (JsvTypeSerializer)JsvTypeSerializer.Instance;
+
+		internal static object StringToType(
+			Type type, 
+			string strType, 
+			EmptyCtorDelegate ctorFn, 
+			Dictionary<string, TypeAccessor> typeAccessorMap)
+		{
+			var index = 0;
+
+			if (strType == null)
+				return null;
+
+			//if (!Serializer.EatMapStartChar(strType, ref index))
+			if (strType[index++] != JsWriter.MapStartChar)
+				throw DeserializeTypeRef.CreateSerializationError(type, strType);
+
+			if (strType == JsWriter.EmptyMap) return ctorFn();
+
+			object instance = null;
+
+			var strTypeLength = strType.Length;
+			while (index < strTypeLength)
+			{
+				var propertyName = Serializer.EatMapKey(strType, ref index);
+
+				//Serializer.EatMapKeySeperator(strType, ref index);
+				index++;
+
+				var propertyValueStr = Serializer.EatValue(strType, ref index);
+				var possibleTypeInfo = propertyValueStr != null && propertyValueStr.Length > 1 && propertyValueStr[0] == '_';
+
+				if (possibleTypeInfo && propertyName == JsWriter.TypeAttr)
+				{
+					var typeName = Serializer.ParseString(propertyValueStr);
+					instance = ReflectionExtensions.CreateInstance(typeName);
+					if (instance == null)
+					{
+						Tracer.Instance.WriteWarning("Could not find type: " + propertyValueStr);
+					}
+					else
+					{
+						//If __type info doesn't match, ignore it.
+						if (!type.IsInstanceOfType(instance))
+							instance = null;
+					}
+
+					//Serializer.EatItemSeperatorOrMapEndChar(strType, ref index);
+					if (index != strType.Length) index++;
+
+					continue;
+				}
+
+				if (instance == null) instance = ctorFn();
+
+				TypeAccessor typeAccessor;
+				typeAccessorMap.TryGetValue(propertyName, out typeAccessor);
+
+				var propType = possibleTypeInfo ? TypeAccessor.ExtractType(Serializer, propertyValueStr) : null;
+				if (propType != null)
+				{
+					try
+					{
+						if (typeAccessor != null)
+						{
+							var parseFn = Serializer.GetParseFn(propType);
+							var propertyValue = parseFn(propertyValueStr);
+							typeAccessor.SetProperty(instance, propertyValue);
+						}
+
+						//Serializer.EatItemSeperatorOrMapEndChar(strType, ref index);
+						if (index != strType.Length) index++;
+
+						continue;
+					}
+					catch
+					{
+						Tracer.Instance.WriteWarning("WARN: failed to set dynamic property {0} with: {1}", propertyName, propertyValueStr);
+					}
+				}
+
+				if (typeAccessor != null && typeAccessor.GetProperty != null && typeAccessor.SetProperty != null)
+				{
+					try
+					{
+						var propertyValue = typeAccessor.GetProperty(propertyValueStr);
+						typeAccessor.SetProperty(instance, propertyValue);
+					}
+					catch
+					{
+						Tracer.Instance.WriteWarning("WARN: failed to set property {0} with: {1}", propertyName, propertyValueStr);
+					}
+				}
+
+				//Serializer.EatItemSeperatorOrMapEndChar(strType, ref index);
+				if (index != strType.Length) index++;
+			}
+
+			return instance;
+		}
+	}
+
+	//The same class above but JSON-specific to enable inlining in this hot class.
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeTypeUtils.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeTypeUtils.cs
new file mode 100644
index 0000000..cbf2a8d
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeTypeUtils.cs
@@ -0,0 +1,51 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.Reflection;
+
+namespace ServiceStack.Text.Common
+{
+	public class DeserializeTypeUtils
+	{
+		public static ParseStringDelegate GetParseMethod(Type type)
+		{
+			var typeConstructor = GetTypeStringConstructor(type);
+			if (typeConstructor != null)
+			{
+				return value => typeConstructor.Invoke(new object[] { value });
+			}
+
+			return null;
+		}
+
+		/// <summary>
+		/// Get the type(string) constructor if exists
+		/// </summary>
+		/// <param name="type">The type.</param>
+		/// <returns></returns>
+		public static ConstructorInfo GetTypeStringConstructor(Type type)
+		{
+			foreach (var ci in type.GetConstructors())
+			{
+				var paramInfos = ci.GetParameters();
+				var matchFound = (paramInfos.Length == 1 && paramInfos[0].ParameterType == typeof(string));
+				if (matchFound)
+				{
+					return ci;
+				}
+			}
+			return null;
+		}
+
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Common/ITypeSerializer.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/ITypeSerializer.cs
new file mode 100644
index 0000000..3deacc8
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/ITypeSerializer.cs
@@ -0,0 +1,57 @@
+using System;
+using System.IO;
+using ServiceStack.Text.Json;
+
+namespace ServiceStack.Text.Common
+{
+	internal interface ITypeSerializer
+	{
+		string TypeAttrInObject { get; }
+
+		WriteObjectDelegate GetWriteFn<T>();
+		WriteObjectDelegate GetWriteFn(Type type);
+		TypeInfo GetTypeInfo(Type type);
+
+		void WriteRawString(TextWriter writer, string value);
+		void WritePropertyName(TextWriter writer, string value);
+
+		void WriteBuiltIn(TextWriter writer, object value);
+		void WriteObjectString(TextWriter writer, object value);
+		void WriteException(TextWriter writer, object value);
+		void WriteString(TextWriter writer, string value);
+		void WriteDateTime(TextWriter writer, object oDateTime);
+		void WriteNullableDateTime(TextWriter writer, object dateTime);
+		void WriteGuid(TextWriter writer, object oValue);
+		void WriteNullableGuid(TextWriter writer, object oValue);
+		void WriteBytes(TextWriter writer, object oByteValue);
+		void WriteChar(TextWriter writer, object charValue);
+		void WriteByte(TextWriter writer, object byteValue);
+		void WriteInt16(TextWriter writer, object intValue);
+		void WriteUInt16(TextWriter writer, object intValue);
+		void WriteInt32(TextWriter writer, object intValue);
+		void WriteUInt32(TextWriter writer, object uintValue);
+		void WriteInt64(TextWriter writer, object longValue);
+		void WriteUInt64(TextWriter writer, object ulongValue);
+		void WriteBool(TextWriter writer, object boolValue);
+		void WriteFloat(TextWriter writer, object floatValue);
+		void WriteDouble(TextWriter writer, object doubleValue);
+        void WriteDecimal(TextWriter writer, object decimalValue);
+        void WriteEnum(TextWriter writer, object enumValue);
+        void WriteEnumFlags(TextWriter writer, object enumFlagValue);
+		void WriteLinqBinary(TextWriter writer, object linqBinaryValue);
+
+		//object EncodeMapKey(object value);
+
+		ParseStringDelegate GetParseFn<T>();
+		ParseStringDelegate GetParseFn(Type type);
+
+		string ParseRawString(string value);
+		string ParseString(string value);
+		string EatTypeValue(string value, ref int i);
+		bool EatMapStartChar(string value, ref int i);
+		string EatMapKey(string value, ref int i);
+		bool EatMapKeySeperator(string value, ref int i);
+		string EatValue(string value, ref int i);
+		bool EatItemSeperatorOrMapEndChar(string value, ref int i);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Common/JsDelegates.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/JsDelegates.cs
new file mode 100644
index 0000000..08ebf1c
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/JsDelegates.cs
@@ -0,0 +1,36 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+
+namespace ServiceStack.Text.Common
+{
+	internal delegate void WriteListDelegate(TextWriter writer, object oList, WriteObjectDelegate toStringFn);
+
+	internal delegate void WriteGenericListDelegate<T>(TextWriter writer, IList<T> list, WriteObjectDelegate toStringFn);
+
+	internal delegate void WriteDelegate(TextWriter writer, object value);
+
+	internal delegate ParseStringDelegate ParseFactoryDelegate();
+
+	internal delegate void WriteObjectDelegate(TextWriter writer, object obj);
+
+	public delegate void SetPropertyDelegate(object instance, object propertyValue);
+
+	public delegate object ParseStringDelegate(string stringValue);
+
+	public delegate object ConvertObjectDelegate(object fromObject);
+
+    public delegate object ConvertInstanceDelegate(object obj, Type type);
+}
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Common/JsReader.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/JsReader.cs
new file mode 100644
index 0000000..78d918b
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/JsReader.cs
@@ -0,0 +1,104 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace ServiceStack.Text.Common
+{
+	internal class JsReader<TSerializer>
+		where TSerializer : ITypeSerializer
+	{
+		private static readonly ITypeSerializer Serializer = JsWriter.GetTypeSerializer<TSerializer>();
+
+		public ParseStringDelegate GetParseFn<T>()
+		{
+			var type = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T);
+
+			if (type.IsEnum)
+			{
+				return x => Enum.Parse(type, x, true);
+			}
+
+			if (type == typeof(string))
+				return Serializer.ParseString;
+
+			if (type == typeof(object))
+				return DeserializeType<TSerializer>.ObjectStringToType;
+
+			var specialParseFn = ParseUtils.GetSpecialParseMethod(type);
+			if (specialParseFn != null)
+				return specialParseFn;
+
+			if (type.IsEnum)
+				return x => Enum.Parse(type, x, true);
+
+			if (type.IsArray)
+			{
+				return DeserializeArray<T, TSerializer>.Parse;
+			}
+
+			var builtInMethod = DeserializeBuiltin<T>.Parse;
+			if (builtInMethod != null)
+				return value => builtInMethod(Serializer.ParseRawString(value));
+
+			if (JsConfig<T>.SerializeFn != null)
+				return value => JsConfig<T>.ParseFn(Serializer.ParseRawString(value));
+
+			if (type.IsGenericType())
+			{
+				if (type.IsOrHasGenericInterfaceTypeOf(typeof(IList<>)))
+					return DeserializeList<T, TSerializer>.Parse;
+
+				if (type.IsOrHasGenericInterfaceTypeOf(typeof(IDictionary<,>)))
+					return DeserializeDictionary<TSerializer>.GetParseMethod(type);
+
+				if (type.IsOrHasGenericInterfaceTypeOf(typeof(ICollection<>)))
+					return DeserializeCollection<TSerializer>.GetParseMethod(type);
+
+				if (type.HasAnyTypeDefinitionsOf(typeof(Queue<>))
+					|| type.HasAnyTypeDefinitionsOf(typeof(Stack<>)))
+					return DeserializeSpecializedCollections<T, TSerializer>.Parse;
+
+				if (type.IsOrHasGenericInterfaceTypeOf(typeof(IEnumerable<>)))
+					return DeserializeEnumerable<T, TSerializer>.Parse;
+			}
+
+			var isCollection = typeof(T).IsOrHasGenericInterfaceTypeOf(typeof(ICollection));
+			if (isCollection)
+			{
+				var isDictionary = typeof(T).IsAssignableFrom(typeof(IDictionary))
+					|| typeof(T).HasInterface(typeof(IDictionary));
+				if (isDictionary)
+				{
+					return DeserializeDictionary<TSerializer>.GetParseMethod(type);
+				}
+
+				return DeserializeEnumerable<T, TSerializer>.Parse;
+			}
+
+			var isEnumerable = typeof(T).IsAssignableFrom(typeof(IEnumerable))
+				|| typeof(T).HasInterface(typeof(IEnumerable));
+
+			if (isEnumerable)
+			{
+				var parseFn = DeserializeSpecializedCollections<T, TSerializer>.Parse;
+				if (parseFn != null) return parseFn;
+			}
+
+			if (type.IsValueType) {
+				var staticParseMethod = StaticParseMethod<T>.Parse;
+				if (staticParseMethod != null)
+					return value => staticParseMethod(Serializer.ParseRawString(value));
+			}
+
+			var typeConstructor = DeserializeType<TSerializer>.GetParseMethod(TypeConfig<T>.GetState());
+			if (typeConstructor != null)
+				return typeConstructor;
+
+			var stringConstructor = DeserializeTypeUtils.GetParseMethod(type);
+			if (stringConstructor != null) return stringConstructor;
+
+			return DeserializeType<TSerializer>.ParseAbstractType<T>;
+		}
+		
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Common/JsState.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/JsState.cs
new file mode 100644
index 0000000..ca138aa
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/JsState.cs
@@ -0,0 +1,14 @@
+using System;
+
+namespace ServiceStack.Text.Common
+{
+	internal static class JsState
+	{
+		//Exposing field for perf
+		[ThreadStatic] internal static int WritingKeyCount = 0;
+
+		[ThreadStatic] internal static bool IsWritingValue = false;
+
+		[ThreadStatic] internal static bool IsWritingDynamic = false;
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Common/JsWriter.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/JsWriter.cs
new file mode 100644
index 0000000..e323d08
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/JsWriter.cs
@@ -0,0 +1,313 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+
+using ServiceStack.Text.Json;
+using ServiceStack.Text.Jsv;
+
+namespace ServiceStack.Text.Common
+{
+    public static class JsWriter
+    {
+        public const string TypeAttr = "__type";
+
+        public const char MapStartChar = '{';
+        public const char MapKeySeperator = ':';
+        public const char ItemSeperator = ',';
+        public const char MapEndChar = '}';
+        public const string MapNullValue = "\"\"";
+        public const string EmptyMap = "{}";
+
+        public const char ListStartChar = '[';
+        public const char ListEndChar = ']';
+        public const char ReturnChar = '\r';
+        public const char LineFeedChar = '\n';
+
+        public const char QuoteChar = '"';
+        public const string QuoteString = "\"";
+        public const string EscapedQuoteString = "\\\"";
+        public const string ItemSeperatorString = ",";
+        public const string MapKeySeperatorString = ":";
+
+        public static readonly char[] CsvChars = new[] { ItemSeperator, QuoteChar };
+        public static readonly char[] EscapeChars = new[] { QuoteChar, MapKeySeperator, ItemSeperator, MapStartChar, MapEndChar, ListStartChar, ListEndChar, ReturnChar, LineFeedChar };
+
+        private const int LengthFromLargestChar = '}' + 1;
+        private static readonly bool[] EscapeCharFlags = new bool[LengthFromLargestChar];
+
+        static JsWriter()
+        {
+            foreach (var escapeChar in EscapeChars)
+            {
+                EscapeCharFlags[escapeChar] = true;
+            }
+            var loadConfig = JsConfig.IncludeNullValues;
+        }
+
+        public static void WriteDynamic(Action callback)
+        {
+            JsState.IsWritingDynamic = true;
+            try
+            {
+                callback();
+            }
+            finally
+            {
+                JsState.IsWritingDynamic = false;
+            }
+        }
+
+        /// <summary>
+        /// micro optimizations: using flags instead of value.IndexOfAny(EscapeChars)
+        /// </summary>
+        /// <param name="value"></param>
+        /// <returns></returns>
+        public static bool HasAnyEscapeChars(string value)
+        {
+            var len = value.Length;
+            for (var i = 0; i < len; i++)
+            {
+                var c = value[i];
+                if (c >= LengthFromLargestChar || !EscapeCharFlags[c]) continue;
+                return true;
+            }
+            return false;
+        }
+
+        internal static void WriteItemSeperatorIfRanOnce(TextWriter writer, ref bool ranOnce)
+        {
+            if (ranOnce)
+                writer.Write(ItemSeperator);
+            else
+                ranOnce = true;
+
+            foreach (var escapeChar in EscapeChars)
+            {
+                EscapeCharFlags[escapeChar] = true;
+            }
+        }
+
+        internal static bool ShouldUseDefaultToStringMethod(Type type)
+        {
+            return type == typeof(byte) || type == typeof(byte?)
+                || type == typeof(short) || type == typeof(short?)
+                || type == typeof(ushort) || type == typeof(ushort?)
+                || type == typeof(int) || type == typeof(int?)
+                || type == typeof(uint) || type == typeof(uint?)
+                || type == typeof(long) || type == typeof(long?)
+                || type == typeof(ulong) || type == typeof(ulong?)
+                || type == typeof(bool) || type == typeof(bool?)
+                || type == typeof(DateTime) || type == typeof(DateTime?)
+                || type == typeof(Guid) || type == typeof(Guid?)
+                || type == typeof(float) || type == typeof(float?)
+                || type == typeof(double) || type == typeof(double?)
+                || type == typeof(decimal) || type == typeof(decimal?);
+        }
+
+        internal static ITypeSerializer GetTypeSerializer<TSerializer>()
+        {
+            if (typeof(TSerializer) == typeof(JsvTypeSerializer))
+                return JsvTypeSerializer.Instance;
+
+            if (typeof(TSerializer) == typeof(JsonTypeSerializer))
+                return JsonTypeSerializer.Instance;
+
+            throw new NotSupportedException(typeof(TSerializer).Name);
+        }
+    }
+
+    internal class JsWriter<TSerializer>
+        where TSerializer : ITypeSerializer
+    {
+        private static readonly ITypeSerializer Serializer = JsWriter.GetTypeSerializer<TSerializer>();
+
+        public JsWriter()
+        {
+            this.SpecialTypes = new Dictionary<Type, WriteObjectDelegate>
+        	{
+        		{ typeof(Uri), Serializer.WriteObjectString },
+        		{ typeof(Type), WriteType },
+        		{ typeof(Exception), Serializer.WriteException },
+#if !MONOTOUCH && !SILVERLIGHT && !XBOX
+                { typeof(System.Data.Linq.Binary), Serializer.WriteLinqBinary },
+#endif
+        	};
+        }
+
+        public WriteObjectDelegate GetValueTypeToStringMethod(Type type)
+        {
+			if (type == typeof(char) || type == typeof(char?))
+				return Serializer.WriteChar;
+			if (type == typeof(int) || type == typeof(int?))
+				return Serializer.WriteInt32;
+			if (type == typeof(long) || type == typeof(long?))
+				return Serializer.WriteInt64;
+			if (type == typeof(ulong) || type == typeof(ulong?))
+				return Serializer.WriteUInt64;
+			if (type == typeof(uint) || type == typeof(uint?))
+				return Serializer.WriteUInt32;
+
+			if (type == typeof(byte) || type == typeof(byte?))
+				return Serializer.WriteByte;
+
+			if (type == typeof(short) || type == typeof(short?))
+				return Serializer.WriteInt16;
+            if (type == typeof(ushort) || type == typeof(ushort?))
+				return Serializer.WriteUInt16;
+
+            if (type == typeof(bool) || type == typeof(bool?))
+                return Serializer.WriteBool;
+
+            if (type == typeof(DateTime))
+                return Serializer.WriteDateTime;
+
+            if (type == typeof(DateTime?))
+                return Serializer.WriteNullableDateTime;
+
+            if (type == typeof(Guid))
+                return Serializer.WriteGuid;
+
+            if (type == typeof(Guid?))
+                return Serializer.WriteNullableGuid;
+
+            if (type == typeof(float) || type == typeof(float?))
+                return Serializer.WriteFloat;
+
+            if (type == typeof(double) || type == typeof(double?))
+                return Serializer.WriteDouble;
+
+            if (type == typeof(decimal) || type == typeof(decimal?))
+                return Serializer.WriteDecimal;
+
+            if (type.IsEnum || type.UnderlyingSystemType.IsEnum)
+                return type.GetCustomAttributes(typeof(FlagsAttribute), false).Length > 0
+                    ? (WriteObjectDelegate)Serializer.WriteEnumFlags
+                    : Serializer.WriteEnum;
+
+            return Serializer.WriteObjectString;
+        }
+
+        internal WriteObjectDelegate GetWriteFn<T>()
+        {
+            if (typeof(T) == typeof(string))
+            {
+                return Serializer.WriteObjectString;
+            }
+
+            if (typeof(T).IsValueType)
+            {
+                return JsConfig<T>.SerializeFn != null
+                    ? JsConfig<T>.WriteFn<TSerializer>
+                    : GetValueTypeToStringMethod(typeof(T));
+            }
+
+            var specialWriteFn = GetSpecialWriteFn(typeof(T));
+            if (specialWriteFn != null)
+            {
+                return specialWriteFn;
+            }
+
+            if (typeof(T).IsArray)
+            {
+                if (typeof(T) == typeof(byte[]))
+                    return (w, x) => WriteLists.WriteBytes(Serializer, w, x);
+
+                if (typeof(T) == typeof(string[]))
+                    return (w, x) => WriteLists.WriteStringArray(Serializer, w, x);
+
+                if (typeof(T) == typeof(int[]))
+                    return WriteListsOfElements<int, TSerializer>.WriteGenericArrayValueType;
+                if (typeof(T) == typeof(long[]))
+                    return WriteListsOfElements<long, TSerializer>.WriteGenericArrayValueType;
+
+                var elementType = typeof(T).GetElementType();
+                var writeFn = WriteListsOfElements<TSerializer>.GetGenericWriteArray(elementType);
+                return writeFn;
+            }
+
+            if (typeof(T).IsGenericType())
+            {
+                if (typeof(T).IsOrHasGenericInterfaceTypeOf(typeof(IList<>)))
+                    return WriteLists<T, TSerializer>.Write;
+
+                var mapInterface = typeof(T).GetTypeWithGenericTypeDefinitionOf(typeof(IDictionary<,>));
+                if (mapInterface != null)
+                {
+                    var mapTypeArgs = mapInterface.GetGenericArguments();
+                    var writeFn = WriteDictionary<TSerializer>.GetWriteGenericDictionary(
+                        mapTypeArgs[0], mapTypeArgs[1]);
+
+                    var keyWriteFn = Serializer.GetWriteFn(mapTypeArgs[0]);
+                    var valueWriteFn = Serializer.GetWriteFn(mapTypeArgs[1]);
+
+                    return (w, x) => writeFn(w, x, keyWriteFn, valueWriteFn);
+                }
+
+                var enumerableInterface = typeof(T).GetTypeWithGenericTypeDefinitionOf(typeof(IEnumerable<>));
+                if (enumerableInterface != null)
+                {
+                    var elementType = enumerableInterface.GetGenericArguments()[0];
+                    var writeFn = WriteListsOfElements<TSerializer>.GetGenericWriteEnumerable(elementType);
+                    return writeFn;
+                }
+            }
+
+            var isCollection = typeof(T).IsOrHasGenericInterfaceTypeOf(typeof(ICollection));
+            if (isCollection)
+            {
+                var isDictionary = typeof(T).IsAssignableFrom(typeof(IDictionary))
+                    || typeof(T).HasInterface(typeof(IDictionary));
+                if (isDictionary)
+                {
+                    return WriteDictionary<TSerializer>.WriteIDictionary;
+                }
+
+                return WriteListsOfElements<TSerializer>.WriteIEnumerable;
+            }
+
+            var isEnumerable = typeof(T).IsAssignableFrom(typeof(IEnumerable))
+                || typeof(T).HasInterface(typeof(IEnumerable));
+
+            if (isEnumerable)
+            {
+                return WriteListsOfElements<TSerializer>.WriteIEnumerable;
+            }
+
+            if (typeof(T).IsClass || typeof(T).IsInterface)
+            {
+                var typeToStringMethod = WriteType<T, TSerializer>.Write;
+                if (typeToStringMethod != null)
+                {
+                    return typeToStringMethod;
+                }
+            }
+
+            return Serializer.WriteBuiltIn;
+        }
+
+
+        public Dictionary<Type, WriteObjectDelegate> SpecialTypes;
+
+        public WriteObjectDelegate GetSpecialWriteFn(Type type)
+        {
+            WriteObjectDelegate writeFn = null;
+            if (SpecialTypes.TryGetValue(type, out writeFn))
+                return writeFn;
+
+            if (type.IsInstanceOfType(typeof(Type)))
+                return WriteType;
+
+            if (type.IsInstanceOf(typeof(Exception)))
+                return Serializer.WriteException;
+
+            return null;
+        }
+
+        public void WriteType(TextWriter writer, object value)
+        {
+            Serializer.WriteRawString(writer, ((Type)value).ToTypeString());
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Common/ParseUtils.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/ParseUtils.cs
new file mode 100644
index 0000000..16b04b4
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/ParseUtils.cs
@@ -0,0 +1,60 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+
+namespace ServiceStack.Text.Common
+{
+	internal static class ParseUtils
+	{
+		public static object NullValueType(Type type)
+		{
+			return ReflectionExtensions.GetDefaultValue(type);
+		}
+
+		public static object ParseObject(string value)
+		{
+			return value;
+		}
+
+		public static object ParseEnum(Type type, string value)
+		{
+			return Enum.Parse(type, value, false);
+		}
+
+		public static ParseStringDelegate GetSpecialParseMethod(Type type)
+		{
+			if (type == typeof(Uri))
+				return x => new Uri(x.FromCsvField());
+
+			//Warning: typeof(object).IsInstanceOfType(typeof(Type)) == True??
+			if (type.IsInstanceOfType(typeof(Type)))
+				return ParseType;
+
+			if (type == typeof(Exception))
+				return x => new Exception(x);
+
+			if (type.IsInstanceOf(typeof(Exception)))
+				return DeserializeTypeUtils.GetParseMethod(type);
+
+			return null;
+		}
+
+		public static Type ParseType(string assemblyQualifiedName)
+		{
+			return Type.GetType(assemblyQualifiedName.FromCsvField());
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Common/StaticParseMethod.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/StaticParseMethod.cs
new file mode 100644
index 0000000..2d00c2d
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/StaticParseMethod.cs
@@ -0,0 +1,63 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.Reflection;
+
+namespace ServiceStack.Text.Common
+{
+	internal delegate object ParseDelegate(string value);
+
+	public static class StaticParseMethod<T>
+	{
+		const string ParseMethod = "Parse";
+
+		private static readonly ParseStringDelegate CacheFn;
+
+		public static ParseStringDelegate Parse
+		{
+			get { return CacheFn; }
+		}
+
+		static StaticParseMethod()
+		{
+			CacheFn = GetParseFn();
+		}
+
+		public static ParseStringDelegate GetParseFn()
+		{
+			// Get the static Parse(string) method on the type supplied
+			var parseMethodInfo = typeof(T).GetMethod(
+				ParseMethod, BindingFlags.Public | BindingFlags.Static, null,
+				new[] { typeof(string) }, null);
+
+			if (parseMethodInfo == null) return null;
+
+			ParseDelegate parseDelegate;
+			try
+			{
+				parseDelegate = (ParseDelegate)Delegate.CreateDelegate(typeof(ParseDelegate), parseMethodInfo);
+			}
+			catch ( ArgumentException )
+			{
+				//Try wrapping strongly-typed return with wrapper fn.
+				var typedParseDelegate = (Func<string,T>)Delegate.CreateDelegate(typeof(Func<string,T>), parseMethodInfo);
+				parseDelegate = x => typedParseDelegate(x);
+			}
+			if (parseDelegate != null)
+				return value => parseDelegate(value.FromCsvField());
+
+			return null;
+		}
+
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Common/WriteDictionary.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/WriteDictionary.cs
new file mode 100644
index 0000000..ba3d64e
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/WriteDictionary.cs
@@ -0,0 +1,231 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using System.Threading;
+using ServiceStack.Text.Json;
+
+namespace ServiceStack.Text.Common
+{
+	internal delegate void WriteMapDelegate(
+		TextWriter writer,
+		object oMap,
+		WriteObjectDelegate writeKeyFn,
+		WriteObjectDelegate writeValueFn);
+
+	internal static class WriteDictionary<TSerializer>
+		where TSerializer : ITypeSerializer
+	{
+		private static readonly ITypeSerializer Serializer = JsWriter.GetTypeSerializer<TSerializer>();
+
+		internal class MapKey
+		{
+			internal Type KeyType;
+			internal Type ValueType;
+
+			public MapKey(Type keyType, Type valueType)
+			{
+				KeyType = keyType;
+				ValueType = valueType;
+			}
+
+			public bool Equals(MapKey other)
+			{
+				if (ReferenceEquals(null, other)) return false;
+				if (ReferenceEquals(this, other)) return true;
+				return Equals(other.KeyType, KeyType) && Equals(other.ValueType, ValueType);
+			}
+
+			public override bool Equals(object obj)
+			{
+				if (ReferenceEquals(null, obj)) return false;
+				if (ReferenceEquals(this, obj)) return true;
+				if (obj.GetType() != typeof(MapKey)) return false;
+				return Equals((MapKey)obj);
+			}
+
+			public override int GetHashCode()
+			{
+				unchecked
+				{
+					return ((KeyType != null ? KeyType.GetHashCode() : 0) * 397) ^ (ValueType != null ? ValueType.GetHashCode() : 0);
+				}
+			}
+		}
+
+		static Dictionary<MapKey, WriteMapDelegate> CacheFns = new Dictionary<MapKey, WriteMapDelegate>();
+
+		public static Action<TextWriter, object, WriteObjectDelegate, WriteObjectDelegate>
+			GetWriteGenericDictionary(Type keyType, Type valueType)
+		{
+			WriteMapDelegate writeFn;
+            var mapKey = new MapKey(keyType, valueType);
+            if (CacheFns.TryGetValue(mapKey, out writeFn)) return writeFn.Invoke;
+
+            var genericType = typeof(ToStringDictionaryMethods<,,>).MakeGenericType(keyType, valueType, typeof(TSerializer));
+            var mi = genericType.GetMethod("WriteIDictionary", BindingFlags.Static | BindingFlags.Public);
+            writeFn = (WriteMapDelegate)Delegate.CreateDelegate(typeof(WriteMapDelegate), mi);
+
+            Dictionary<MapKey, WriteMapDelegate> snapshot, newCache;
+            do
+            {
+                snapshot = CacheFns;
+                newCache = new Dictionary<MapKey, WriteMapDelegate>(CacheFns);
+                newCache[mapKey] = writeFn;
+
+            } while (!ReferenceEquals(
+                Interlocked.CompareExchange(ref CacheFns, newCache, snapshot), snapshot));
+            
+            return writeFn.Invoke;
+		}
+
+		public static void WriteIDictionary(TextWriter writer, object oMap)
+		{
+			WriteObjectDelegate writeKeyFn = null;
+			WriteObjectDelegate writeValueFn = null;
+
+			writer.Write(JsWriter.MapStartChar);
+			var encodeMapKey = false;
+
+			var map = (IDictionary)oMap;
+			var ranOnce = false;
+			foreach (var key in map.Keys)
+			{
+				var dictionaryValue = map[key];
+
+                var isNull = (dictionaryValue == null);
+                if (isNull && !JsConfig.IncludeNullValues) continue;
+
+				if (writeKeyFn == null)
+				{
+					var keyType = key.GetType();
+					writeKeyFn = Serializer.GetWriteFn(keyType);
+					encodeMapKey = Serializer.GetTypeInfo(keyType).EncodeMapKey;
+				}
+
+				if (writeValueFn == null)
+					writeValueFn = Serializer.GetWriteFn(dictionaryValue.GetType());
+
+				JsWriter.WriteItemSeperatorIfRanOnce(writer, ref ranOnce);
+
+				JsState.WritingKeyCount++;
+				JsState.IsWritingValue = false;
+
+				if (encodeMapKey)
+				{
+					JsState.IsWritingValue = true; //prevent ""null""
+					writer.Write(JsWriter.QuoteChar);
+					writeKeyFn(writer, key);
+					writer.Write(JsWriter.QuoteChar);
+				}
+				else
+				{
+					writeKeyFn(writer, key);
+				}
+
+				JsState.WritingKeyCount--;
+
+				writer.Write(JsWriter.MapKeySeperator);
+
+                if (isNull)
+                {
+                    writer.Write(JsonUtils.Null);
+                }
+                else
+                {
+                    JsState.IsWritingValue = true;
+                    writeValueFn(writer, dictionaryValue);
+                    JsState.IsWritingValue = false;
+                }
+			}
+
+			writer.Write(JsWriter.MapEndChar);
+		}
+	}
+
+	internal static class ToStringDictionaryMethods<TKey, TValue, TSerializer>
+		where TSerializer : ITypeSerializer
+	{
+		private static readonly ITypeSerializer Serializer = JsWriter.GetTypeSerializer<TSerializer>();
+
+		public static void WriteIDictionary(
+			TextWriter writer,
+			object oMap,
+			WriteObjectDelegate writeKeyFn,
+			WriteObjectDelegate writeValueFn)
+		{
+			if (writer == null) return; //AOT
+			WriteGenericIDictionary(writer, (IDictionary<TKey, TValue>)oMap, writeKeyFn, writeValueFn);
+		}
+
+		public static void WriteGenericIDictionary(
+			TextWriter writer,
+			IDictionary<TKey, TValue> map,
+			WriteObjectDelegate writeKeyFn,
+			WriteObjectDelegate writeValueFn)
+		{
+		    if (map == null)
+		    {
+		        writer.Write(JsonUtils.Null);
+                return;
+		    }
+			writer.Write(JsWriter.MapStartChar);
+
+			var encodeMapKey = Serializer.GetTypeInfo(typeof(TKey)).EncodeMapKey;
+
+			var ranOnce = false;
+			foreach (var kvp in map)
+			{
+                var isNull = (kvp.Value == null);
+                if (isNull && !JsConfig.IncludeNullValues) continue;
+
+				JsWriter.WriteItemSeperatorIfRanOnce(writer, ref ranOnce);
+
+				JsState.WritingKeyCount++;
+                JsState.IsWritingValue = false;
+
+				if (encodeMapKey)
+				{
+					JsState.IsWritingValue = true; //prevent ""null""
+					writer.Write(JsWriter.QuoteChar);
+					writeKeyFn(writer, kvp.Key);
+					writer.Write(JsWriter.QuoteChar);
+				}
+				else
+				{
+					writeKeyFn(writer, kvp.Key);
+				}
+				
+				JsState.WritingKeyCount--;
+
+				writer.Write(JsWriter.MapKeySeperator);
+
+                if (isNull)
+                {
+                    writer.Write(JsonUtils.Null);
+                }
+                else
+                {
+                    JsState.IsWritingValue = true;
+                    writeValueFn(writer, kvp.Value);
+                    JsState.IsWritingValue = false;
+                }
+			}
+
+			writer.Write(JsWriter.MapEndChar);
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Common/WriteLists.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/WriteLists.cs
new file mode 100644
index 0000000..806bc0a
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/WriteLists.cs
@@ -0,0 +1,495 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using System.Threading;
+
+namespace ServiceStack.Text.Common
+{
+	internal static class WriteListsOfElements<TSerializer>
+		where TSerializer : ITypeSerializer
+	{
+		private static readonly ITypeSerializer Serializer = JsWriter.GetTypeSerializer<TSerializer>();
+
+		static Dictionary<Type, WriteObjectDelegate> ListCacheFns = new Dictionary<Type, WriteObjectDelegate>();
+
+		public static WriteObjectDelegate GetListWriteFn(Type elementType)
+		{
+			WriteObjectDelegate writeFn;
+            if (ListCacheFns.TryGetValue(elementType, out writeFn)) return writeFn;
+
+            var genericType = typeof(WriteListsOfElements<,>).MakeGenericType(elementType, typeof(TSerializer));
+            var mi = genericType.GetMethod("WriteList", BindingFlags.Static | BindingFlags.Public);
+            writeFn = (WriteObjectDelegate)Delegate.CreateDelegate(typeof(WriteObjectDelegate), mi);
+
+            Dictionary<Type, WriteObjectDelegate> snapshot, newCache;
+            do
+            {
+                snapshot = ListCacheFns;
+                newCache = new Dictionary<Type, WriteObjectDelegate>(ListCacheFns);
+                newCache[elementType] = writeFn;
+
+            } while (!ReferenceEquals(
+                Interlocked.CompareExchange(ref ListCacheFns, newCache, snapshot), snapshot));
+            
+            return writeFn;
+		}
+
+
+		static Dictionary<Type, WriteObjectDelegate> IListCacheFns = new Dictionary<Type, WriteObjectDelegate>();
+
+		public static WriteObjectDelegate GetIListWriteFn(Type elementType)
+		{
+			WriteObjectDelegate writeFn;
+            if (IListCacheFns.TryGetValue(elementType, out writeFn)) return writeFn;
+
+            var genericType = typeof(WriteListsOfElements<,>).MakeGenericType(elementType, typeof(TSerializer));
+            var mi = genericType.GetMethod("WriteIList", BindingFlags.Static | BindingFlags.Public);
+            writeFn = (WriteObjectDelegate)Delegate.CreateDelegate(typeof(WriteObjectDelegate), mi);
+
+            Dictionary<Type, WriteObjectDelegate> snapshot, newCache;
+            do
+            {
+                snapshot = IListCacheFns;
+                newCache = new Dictionary<Type, WriteObjectDelegate>(IListCacheFns);
+                newCache[elementType] = writeFn;
+
+            } while (!ReferenceEquals(
+                Interlocked.CompareExchange(ref IListCacheFns, newCache, snapshot), snapshot));
+            
+            return writeFn;
+		}
+
+		static Dictionary<Type, WriteObjectDelegate> CacheFns = new Dictionary<Type, WriteObjectDelegate>();
+
+		public static WriteObjectDelegate GetGenericWriteArray(Type elementType)
+		{
+			WriteObjectDelegate writeFn;
+            if (CacheFns.TryGetValue(elementType, out writeFn)) return writeFn;
+
+            var genericType = typeof(WriteListsOfElements<,>).MakeGenericType(elementType, typeof(TSerializer));
+            var mi = genericType.GetMethod("WriteArray", BindingFlags.Static | BindingFlags.Public);
+            writeFn = (WriteObjectDelegate)Delegate.CreateDelegate(typeof(WriteObjectDelegate), mi);
+
+            Dictionary<Type, WriteObjectDelegate> snapshot, newCache;
+            do
+            {
+                snapshot = CacheFns;
+                newCache = new Dictionary<Type, WriteObjectDelegate>(CacheFns);
+                newCache[elementType] = writeFn;
+
+            } while (!ReferenceEquals(
+                Interlocked.CompareExchange(ref CacheFns, newCache, snapshot), snapshot));
+
+			return writeFn;
+		}
+
+		static Dictionary<Type, WriteObjectDelegate> EnumerableCacheFns = new Dictionary<Type, WriteObjectDelegate>();
+
+		public static WriteObjectDelegate GetGenericWriteEnumerable(Type elementType)
+		{
+			WriteObjectDelegate writeFn;
+            if (EnumerableCacheFns.TryGetValue(elementType, out writeFn)) return writeFn;
+
+            var genericType = typeof(WriteListsOfElements<,>).MakeGenericType(elementType, typeof(TSerializer));
+            var mi = genericType.GetMethod("WriteEnumerable", BindingFlags.Static | BindingFlags.Public);
+            writeFn = (WriteObjectDelegate)Delegate.CreateDelegate(typeof(WriteObjectDelegate), mi);
+
+            Dictionary<Type, WriteObjectDelegate> snapshot, newCache;
+            do
+            {
+                snapshot = EnumerableCacheFns;
+                newCache = new Dictionary<Type, WriteObjectDelegate>(EnumerableCacheFns);
+                newCache[elementType] = writeFn;
+
+            } while (!ReferenceEquals(
+                Interlocked.CompareExchange(ref EnumerableCacheFns, newCache, snapshot), snapshot));
+
+			return writeFn;
+		}
+
+		static Dictionary<Type, WriteObjectDelegate> ListValueTypeCacheFns = new Dictionary<Type, WriteObjectDelegate>();
+
+		public static WriteObjectDelegate GetWriteListValueType(Type elementType)
+		{
+			WriteObjectDelegate writeFn;
+            if (ListValueTypeCacheFns.TryGetValue(elementType, out writeFn)) return writeFn;
+
+            var genericType = typeof(WriteListsOfElements<,>).MakeGenericType(elementType, typeof(TSerializer));
+            var mi = genericType.GetMethod("WriteListValueType", BindingFlags.Static | BindingFlags.Public);
+            writeFn = (WriteObjectDelegate)Delegate.CreateDelegate(typeof(WriteObjectDelegate), mi);
+
+            Dictionary<Type, WriteObjectDelegate> snapshot, newCache;
+            do
+            {
+                snapshot = ListValueTypeCacheFns;
+                newCache = new Dictionary<Type, WriteObjectDelegate>(ListValueTypeCacheFns);
+                newCache[elementType] = writeFn;
+
+            } while (!ReferenceEquals(
+                Interlocked.CompareExchange(ref ListValueTypeCacheFns, newCache, snapshot), snapshot));
+
+			return writeFn;
+		}
+
+		static Dictionary<Type, WriteObjectDelegate> IListValueTypeCacheFns = new Dictionary<Type, WriteObjectDelegate>();
+
+		public static WriteObjectDelegate GetWriteIListValueType(Type elementType)
+		{
+			WriteObjectDelegate writeFn;
+
+            if (IListValueTypeCacheFns.TryGetValue(elementType, out writeFn)) return writeFn;
+
+            var genericType = typeof(WriteListsOfElements<,>).MakeGenericType(elementType, typeof(TSerializer));
+            var mi = genericType.GetMethod("WriteIListValueType", BindingFlags.Static | BindingFlags.Public);
+            writeFn = (WriteObjectDelegate)Delegate.CreateDelegate(typeof(WriteObjectDelegate), mi);
+
+            Dictionary<Type, WriteObjectDelegate> snapshot, newCache;
+            do
+            {
+                snapshot = IListValueTypeCacheFns;
+                newCache = new Dictionary<Type, WriteObjectDelegate>(IListValueTypeCacheFns);
+                newCache[elementType] = writeFn;
+
+            } while (!ReferenceEquals(
+                Interlocked.CompareExchange(ref IListValueTypeCacheFns, newCache, snapshot), snapshot));
+
+			return writeFn;
+		}
+
+		public static void WriteIEnumerable(TextWriter writer, object oValueCollection)
+		{
+			WriteObjectDelegate toStringFn = null;
+
+			writer.Write(JsWriter.ListStartChar);
+
+			var valueCollection = (IEnumerable)oValueCollection;
+			var ranOnce = false;
+			foreach (var valueItem in valueCollection)
+			{
+				if (toStringFn == null)
+					toStringFn = Serializer.GetWriteFn(valueItem.GetType());
+
+				JsWriter.WriteItemSeperatorIfRanOnce(writer, ref ranOnce);
+
+				toStringFn(writer, valueItem);
+			}
+
+			writer.Write(JsWriter.ListEndChar);
+		}
+	}
+
+	internal static class WriteListsOfElements<T, TSerializer>
+		where TSerializer : ITypeSerializer
+	{
+		private static readonly WriteObjectDelegate ElementWriteFn;
+
+		static WriteListsOfElements()
+		{
+			ElementWriteFn = JsWriter.GetTypeSerializer<TSerializer>().GetWriteFn<T>();
+		}
+
+		public static void WriteList(TextWriter writer, object oList)
+		{
+			if (oList == null) return;
+			WriteGenericIList(writer, (IList<T>)oList);
+		}
+
+		public static void WriteGenericList(TextWriter writer, List<T> list)
+		{
+			writer.Write(JsWriter.ListStartChar);
+
+			var ranOnce = false;
+			var listLength = list.Count;
+			for (var i = 0; i < listLength; i++)
+			{
+				JsWriter.WriteItemSeperatorIfRanOnce(writer, ref ranOnce);
+				ElementWriteFn(writer, list[i]);
+			}
+
+			writer.Write(JsWriter.ListEndChar);
+		}
+
+		public static void WriteListValueType(TextWriter writer, object list)
+		{
+			WriteGenericListValueType(writer, (List<T>)list);
+		}
+
+		public static void WriteGenericListValueType(TextWriter writer, List<T> list)
+		{
+			if (list == null) return; //AOT
+
+			writer.Write(JsWriter.ListStartChar);
+
+			var ranOnce = false;
+			var listLength = list.Count;
+			for (var i = 0; i < listLength; i++)
+			{
+				JsWriter.WriteItemSeperatorIfRanOnce(writer, ref ranOnce);
+				ElementWriteFn(writer, list[i]);
+			}
+
+			writer.Write(JsWriter.ListEndChar);
+		}
+
+		public static void WriteIList(TextWriter writer, object oList)
+		{
+			if (oList == null) return;
+			WriteGenericIList(writer, (IList<T>)oList);
+		}
+
+		public static void WriteGenericIList(TextWriter writer, IList<T> list)
+		{
+			writer.Write(JsWriter.ListStartChar);
+
+			var ranOnce = false;
+			var listLength = list.Count;
+			try
+			{
+				for (var i = 0; i < listLength; i++)
+				{
+					JsWriter.WriteItemSeperatorIfRanOnce(writer, ref ranOnce);
+					ElementWriteFn(writer, list[i]);
+				}
+
+			}
+			catch (Exception ex)
+			{
+				Tracer.Instance.WriteError(ex);
+				throw;
+			}
+			writer.Write(JsWriter.ListEndChar);
+		}
+
+		public static void WriteIListValueType(TextWriter writer, object list)
+		{
+			WriteGenericIListValueType(writer, (IList<T>)list);
+		}
+
+		public static void WriteGenericIListValueType(TextWriter writer, IList<T> list)
+		{
+			if (list == null) return; //AOT
+
+			writer.Write(JsWriter.ListStartChar);
+
+			var ranOnce = false;
+			var listLength = list.Count;
+			for (var i = 0; i < listLength; i++)
+			{
+				JsWriter.WriteItemSeperatorIfRanOnce(writer, ref ranOnce);
+				ElementWriteFn(writer, list[i]);
+			}
+
+			writer.Write(JsWriter.ListEndChar);
+		}
+
+		public static void WriteArray(TextWriter writer, object oArrayValue)
+		{
+			if (oArrayValue == null) return;
+			WriteGenericArray(writer, (T[])oArrayValue);
+		}
+
+		public static void WriteGenericArrayValueType(TextWriter writer, object oArray)
+		{
+			writer.Write(JsWriter.ListStartChar);
+
+			var array = (T[])oArray;
+			var ranOnce = false;
+			var arrayLength = array.Length;
+			for (var i = 0; i < arrayLength; i++)
+			{
+				JsWriter.WriteItemSeperatorIfRanOnce(writer, ref ranOnce);
+				ElementWriteFn(writer, array[i]);
+			}
+
+			writer.Write(JsWriter.ListEndChar);
+		}
+
+		public static void WriteGenericArray(TextWriter writer, T[] array)
+		{
+			writer.Write(JsWriter.ListStartChar);
+
+			var ranOnce = false;
+			var arrayLength = array.Length;
+			for (var i = 0; i < arrayLength; i++)
+			{
+				JsWriter.WriteItemSeperatorIfRanOnce(writer, ref ranOnce);
+				ElementWriteFn(writer, array[i]);
+			}
+
+			writer.Write(JsWriter.ListEndChar);
+		}
+
+		public static void WriteEnumerable(TextWriter writer, object oEnumerable)
+		{
+			if (oEnumerable == null) return;
+			WriteGenericEnumerable(writer, (IEnumerable<T>)oEnumerable);
+		}
+
+		public static void WriteGenericEnumerable(TextWriter writer, IEnumerable<T> enumerable)
+		{
+			writer.Write(JsWriter.ListStartChar);
+
+			var ranOnce = false;
+			foreach (var value in enumerable)
+			{
+				JsWriter.WriteItemSeperatorIfRanOnce(writer, ref ranOnce);
+				ElementWriteFn(writer, value);
+			}
+
+			writer.Write(JsWriter.ListEndChar);
+		}
+
+		public static void WriteGenericEnumerableValueType(TextWriter writer, IEnumerable<T> enumerable)
+		{
+			writer.Write(JsWriter.ListStartChar);
+
+			var ranOnce = false;
+			foreach (var value in enumerable)
+			{
+				JsWriter.WriteItemSeperatorIfRanOnce(writer, ref ranOnce);
+				ElementWriteFn(writer, value);
+			}
+
+			writer.Write(JsWriter.ListEndChar);
+		}
+	}
+
+	internal static class WriteLists
+	{
+		public static void WriteListString(ITypeSerializer serializer, TextWriter writer, object list)
+		{
+			WriteListString(serializer, writer, (List<string>)list);
+		}
+
+		public static void WriteListString(ITypeSerializer serializer, TextWriter writer, List<string> list)
+		{
+			writer.Write(JsWriter.ListStartChar);
+
+			var ranOnce = false;
+			list.ForEach(x =>
+			{
+				JsWriter.WriteItemSeperatorIfRanOnce(writer, ref ranOnce);
+				serializer.WriteString(writer, x);
+			});
+
+			writer.Write(JsWriter.ListEndChar);
+		}
+
+		public static void WriteIListString(ITypeSerializer serializer, TextWriter writer, object list)
+		{
+			WriteIListString(serializer, writer, (IList<string>)list);
+		}
+
+		public static void WriteIListString(ITypeSerializer serializer, TextWriter writer, IList<string> list)
+		{
+			writer.Write(JsWriter.ListStartChar);
+
+			var ranOnce = false;
+			var listLength = list.Count;
+			for (var i = 0; i < listLength; i++)
+			{
+				JsWriter.WriteItemSeperatorIfRanOnce(writer, ref ranOnce);
+				serializer.WriteString(writer, list[i]);
+			}
+
+			writer.Write(JsWriter.ListEndChar);
+		}
+
+		public static void WriteBytes(ITypeSerializer serializer, TextWriter writer, object byteValue)
+		{
+			if (byteValue == null) return;
+			serializer.WriteBytes(writer, byteValue);
+		}
+
+		public static void WriteStringArray(ITypeSerializer serializer, TextWriter writer, object oList)
+		{
+			writer.Write(JsWriter.ListStartChar);
+
+			var list = (string[])oList;
+			var ranOnce = false;
+			var listLength = list.Length;
+			for (var i = 0; i < listLength; i++)
+			{
+				JsWriter.WriteItemSeperatorIfRanOnce(writer, ref ranOnce);
+				serializer.WriteString(writer, list[i]);
+			}
+
+			writer.Write(JsWriter.ListEndChar);
+		}
+	}
+
+	internal static class WriteLists<T, TSerializer>
+		where TSerializer : ITypeSerializer
+	{
+		private static readonly WriteObjectDelegate CacheFn;
+		private static readonly ITypeSerializer Serializer = JsWriter.GetTypeSerializer<TSerializer>();
+
+		static WriteLists()
+		{
+			CacheFn = GetWriteFn();
+		}
+
+		public static WriteObjectDelegate Write
+		{
+			get { return CacheFn; }
+		}
+
+		public static WriteObjectDelegate GetWriteFn()
+		{
+			var type = typeof(T);
+
+			var listInterface = type.GetTypeWithGenericTypeDefinitionOf(typeof(IList<>));
+			if (listInterface == null)
+				throw new ArgumentException(string.Format("Type {0} is not of type IList<>", type.FullName));
+
+			//optimized access for regularly used types
+			if (type == typeof(List<string>))
+				return (w, x) => WriteLists.WriteListString(Serializer, w, x);
+			if (type == typeof(IList<string>))
+				return (w, x) => WriteLists.WriteIListString(Serializer, w, x);
+
+			if (type == typeof(List<int>))
+				return WriteListsOfElements<int, TSerializer>.WriteListValueType;
+			if (type == typeof(IList<int>))
+				return WriteListsOfElements<int, TSerializer>.WriteIListValueType;
+
+			if (type == typeof(List<long>))
+				return WriteListsOfElements<long, TSerializer>.WriteListValueType;
+			if (type == typeof(IList<long>))
+				return WriteListsOfElements<long, TSerializer>.WriteIListValueType;
+
+			var elementType = listInterface.GetGenericArguments()[0];
+
+			var isGenericList = typeof(T).IsGenericType
+				&& typeof(T).GetGenericTypeDefinition() == typeof(List<>);
+
+			if (elementType.IsValueType
+				&& JsWriter.ShouldUseDefaultToStringMethod(elementType))
+			{
+				if (isGenericList)
+					return WriteListsOfElements<TSerializer>.GetWriteListValueType(elementType);
+
+				return WriteListsOfElements<TSerializer>.GetWriteIListValueType(elementType);
+			}
+
+			return isGenericList
+				? WriteListsOfElements<TSerializer>.GetListWriteFn(elementType)
+				: WriteListsOfElements<TSerializer>.GetIListWriteFn(elementType);
+		}
+
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Common/WriteType.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/WriteType.cs
new file mode 100644
index 0000000..deb1e8f
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Common/WriteType.cs
@@ -0,0 +1,249 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.IO;
+using System.Threading;
+using ServiceStack.Text.Json;
+using ServiceStack.Text.Reflection;
+using System.Linq;
+using System.Runtime.Serialization;
+
+namespace ServiceStack.Text.Common
+{
+	internal static class WriteType<T, TSerializer>
+		where TSerializer : ITypeSerializer
+	{
+		private static readonly ITypeSerializer Serializer = JsWriter.GetTypeSerializer<TSerializer>();
+
+		private static readonly WriteObjectDelegate CacheFn;
+		internal static TypePropertyWriter[] PropertyWriters;
+		private static WriteObjectDelegate WriteTypeInfo;
+
+		static WriteType()
+		{
+			CacheFn = Init() ? GetWriteFn() : WriteEmptyType;
+
+			if (typeof(T).IsAbstract)
+			{
+				WriteTypeInfo = TypeInfoWriter;
+				if (!typeof(T).IsInterface)
+				{
+					CacheFn = WriteAbstractProperties;
+				}
+			}
+		}
+
+		public static void TypeInfoWriter(TextWriter writer, object obj)
+		{
+			DidWriteTypeInfo(writer, obj);
+		}
+
+		private static bool DidWriteTypeInfo(TextWriter writer, object obj)
+		{
+			if (obj == null
+				|| JsConfig.ExcludeTypeInfo
+				|| JsConfig<T>.ExcludeTypeInfo) return false;
+
+			Serializer.WriteRawString(writer, JsWriter.TypeAttr);
+			writer.Write(JsWriter.MapKeySeperator);
+			Serializer.WriteRawString(writer, obj.GetType().ToTypeString());
+			return true;
+		}
+
+		public static WriteObjectDelegate Write
+		{
+			get { return CacheFn; }
+		}
+
+		private static WriteObjectDelegate GetWriteFn()
+		{
+			return WriteProperties;
+		}
+
+		private static bool Init()
+		{
+			if (!typeof(T).IsClass && !typeof(T).IsInterface) return false;
+
+			var propertyInfos = TypeConfig<T>.Properties;
+			if (propertyInfos.Length == 0 && !JsState.IsWritingDynamic)
+			{
+				return typeof(T).IsDto();
+			}
+
+			var propertyNamesLength = propertyInfos.Length;
+
+			PropertyWriters = new TypePropertyWriter[propertyNamesLength];
+
+			// NOTE: very limited support for DataContractSerialization (DCS)
+			//	NOT supporting Serializable
+			//	support for DCS is intended for (re)Name of properties and Ignore by NOT having a DataMember present
+			var isDataContract = typeof(T).GetCustomAttributes(typeof(DataContractAttribute), false).Any();
+			for (var i = 0; i < propertyNamesLength; i++)
+			{
+				var propertyInfo = propertyInfos[i];
+
+				string propertyName, propertyNameCLSFriendly;
+
+				if (isDataContract)
+				{
+					var dcsDataMember = propertyInfo.GetCustomAttributes(typeof(DataMemberAttribute), false).FirstOrDefault() as DataMemberAttribute;
+					if (dcsDataMember == null) continue;
+
+					propertyName = dcsDataMember.Name ?? propertyInfo.Name;
+					propertyNameCLSFriendly = dcsDataMember.Name ?? propertyName.ToCamelCase();
+				}
+				else
+				{
+					propertyName = propertyInfo.Name;
+					propertyNameCLSFriendly = propertyName.ToCamelCase();
+				}
+
+			    var propertyType = propertyInfo.PropertyType;
+			    var suppressDefaultValue = propertyType.IsValueType && JsConfig.HasSerializeFn.Contains(propertyType)
+			        ? ReflectionExtensions.GetDefaultValue(propertyType)
+			        : null;
+
+				PropertyWriters[i] = new TypePropertyWriter
+				(
+					propertyName,
+					propertyNameCLSFriendly,
+					propertyInfo.GetValueGetter<T>(),
+                    Serializer.GetWriteFn(propertyType),
+                    suppressDefaultValue
+				);
+			}
+
+			return true;
+		}
+
+		internal struct TypePropertyWriter
+		{
+			internal string PropertyName
+			{
+				get
+				{
+					return (JsConfig.EmitCamelCaseNames)
+						? propertyNameCLSFriendly
+						: propertyName;
+				}
+			}
+			internal readonly string propertyName;
+			internal readonly string propertyNameCLSFriendly;
+			internal readonly Func<T, object> GetterFn;
+            internal readonly WriteObjectDelegate WriteFn;
+            internal readonly object DefaultValue;
+
+			public TypePropertyWriter(string propertyName, string propertyNameCLSFriendly,
+				Func<T, object> getterFn, WriteObjectDelegate writeFn, object defaultValue)
+			{
+				this.propertyName = propertyName;
+				this.propertyNameCLSFriendly = propertyNameCLSFriendly;
+				this.GetterFn = getterFn;
+				this.WriteFn = writeFn;
+			    this.DefaultValue = defaultValue;
+			}
+		}
+
+		public static void WriteEmptyType(TextWriter writer, object value)
+		{
+			writer.Write(JsWriter.EmptyMap);
+		}
+
+		public static void WriteAbstractProperties(TextWriter writer, object value)
+		{
+			if (value == null)
+			{
+				writer.Write(JsWriter.EmptyMap);
+				return;
+			}
+			var valueType = value.GetType();
+			if (valueType.IsAbstract)
+			{
+				WriteProperties(writer, value);
+				return;
+			}
+
+			var writeFn = Serializer.GetWriteFn(valueType);			
+			if (!JsConfig<T>.ExcludeTypeInfo) JsState.IsWritingDynamic = true;
+			writeFn(writer, value);
+			if (!JsConfig<T>.ExcludeTypeInfo) JsState.IsWritingDynamic = false;
+		}
+		 
+		public static void WriteProperties(TextWriter writer, object value)
+		{
+			if (typeof(TSerializer) == typeof(JsonTypeSerializer) && JsState.WritingKeyCount > 0)
+				writer.Write(JsWriter.QuoteChar);
+
+			writer.Write(JsWriter.MapStartChar);
+
+			var i = 0;
+			if (WriteTypeInfo != null || JsState.IsWritingDynamic)
+			{
+				if (DidWriteTypeInfo(writer, value)) i++;
+			}
+
+			if (PropertyWriters != null)
+			{
+				var len = PropertyWriters.Length;
+				for (int index = 0; index < len; index++)
+				{
+					var propertyWriter = PropertyWriters[index];
+					var propertyValue = value != null 
+						? propertyWriter.GetterFn((T)value)
+						: null;
+
+					if ((propertyValue == null
+					     || (propertyWriter.DefaultValue != null && propertyWriter.DefaultValue.Equals(propertyValue)))
+					    && !JsConfig.IncludeNullValues) continue;
+
+					if (i++ > 0)
+						writer.Write(JsWriter.ItemSeperator);
+
+					Serializer.WritePropertyName(writer, propertyWriter.PropertyName);
+					writer.Write(JsWriter.MapKeySeperator);
+
+					if (typeof (TSerializer) == typeof (JsonTypeSerializer)) JsState.IsWritingValue = true;
+					propertyWriter.WriteFn(writer, propertyValue);
+					if (typeof(TSerializer) == typeof(JsonTypeSerializer)) JsState.IsWritingValue = false;
+				}
+			}
+
+			writer.Write(JsWriter.MapEndChar);
+
+			if (typeof(TSerializer) == typeof(JsonTypeSerializer) && JsState.WritingKeyCount > 0)
+				writer.Write(JsWriter.QuoteChar);
+		}
+
+		public static void WriteQueryString(TextWriter writer, object value)
+		{
+			var i = 0;
+			foreach (var propertyWriter in PropertyWriters)
+			{
+				var propertyValue = propertyWriter.GetterFn((T)value);
+				if (propertyValue == null) continue;
+				var propertyValueString = propertyValue as string;
+				if (propertyValueString != null)
+				{
+					propertyValue = propertyValueString.UrlEncode();
+				}
+
+				if (i++ > 0)
+					writer.Write('&');
+
+				Serializer.WritePropertyName(writer, propertyWriter.PropertyName);
+				writer.Write('=');
+				propertyWriter.WriteFn(writer, propertyValue);
+			}
+		}
+	}
+}
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Controller/CommandProcessor.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Controller/CommandProcessor.cs
new file mode 100644
index 0000000..4fd8b5e
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Controller/CommandProcessor.cs
@@ -0,0 +1,79 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace ServiceStack.Text.Controller
+{
+	public class CommandProcessor 
+	{
+		private object[] Controllers { get; set; }
+
+		private readonly Dictionary<string, object> contextMap;
+
+		public CommandProcessor(object[] controllers)
+		{
+			this.Controllers = controllers;
+
+			this.contextMap = new Dictionary<string, object>();
+			controllers.ToList().ForEach(x => contextMap[x.GetType().Name] = x);
+		}
+
+		public void Invoke(string commandUri)
+		{
+			var actionParts = commandUri.Split(new[] { "://" }, StringSplitOptions.None);
+
+			var controllerName = actionParts[0];
+
+			var pathInfo = PathInfo.Parse(actionParts[1]);
+
+			object context;
+			if (!this.contextMap.TryGetValue(controllerName, out context))
+			{
+				throw new Exception("UnknownContext: " + controllerName);
+			}
+
+			var methodName = pathInfo.ActionName;
+
+			var method = context.GetType().GetMethods().First(
+				c => c.Name == methodName && c.GetParameters().Count() == pathInfo.Arguments.Count);
+
+			var methodParamTypes = method.GetParameters().Select(x => x.ParameterType);
+
+			var methodArgs = ConvertValuesToTypes(pathInfo.Arguments, methodParamTypes.ToList());
+
+			try
+			{
+				method.Invoke(context, methodArgs);
+			}
+			catch (Exception ex)
+			{
+				throw new Exception("InvalidCommand", ex);
+			}
+		}
+
+		private static object[] ConvertValuesToTypes(IList<string> values, IList<Type> types)
+		{
+			var convertedValues = new object[types.Count];
+			for (var i = 0; i < types.Count; i++)
+			{
+				var propertyValueType = types[i];
+				var propertyValueString = values[i];
+				var argValue = TypeSerializer.DeserializeFromString(propertyValueString, propertyValueType);
+				convertedValues[i] = argValue;
+			}
+			return convertedValues;
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Controller/PathInfo.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Controller/PathInfo.cs
new file mode 100644
index 0000000..2c659ad
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Controller/PathInfo.cs
@@ -0,0 +1,102 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace ServiceStack.Text.Controller
+{
+	/// <summary>
+	/// Class to hold  
+	/// </summary>
+	public class PathInfo
+	{
+		public string ControllerName { get; private set; }
+
+		public string ActionName { get; private set; }
+
+		public List<string> Arguments { get; private set; }
+
+		public Dictionary<string, string> Options { get; private set; }
+
+
+		public PathInfo(string actionName, params string[] arguments)
+			: this(actionName, arguments.ToList(), null)
+		{
+		}
+
+		public PathInfo(string actionName, List<string> arguments, Dictionary<string, string> options)
+		{
+			ActionName = actionName;
+			Arguments = arguments ?? new List<string>();
+			Options = options ?? new Dictionary<string, string>();
+		}
+
+		public string FirstArgument
+		{
+			get
+			{
+				return this.Arguments.Count > 0 ? this.Arguments[0] : null;
+			}
+		}
+
+		public T GetArgumentValue<T>(int index)
+		{
+			return TypeSerializer.DeserializeFromString<T>(this.Arguments[index]);
+		}
+
+		/// <summary>
+		/// Parses the specified path info.
+		/// e.g.
+		///		MusicPage/arg1/0/true?debug&showFlows=3 => PathInfo
+		///			.ActionName = 'MusicPage'
+		///			.Arguments = ['arg1','0','true']
+		///			.Options = { debug:'True', showFlows:'3' }
+		/// </summary>
+		/// <param name="pathUri">The path url.</param>
+		/// <returns></returns>
+		public static PathInfo Parse(string pathUri)
+		{
+			var actionParts = pathUri.Split(new[] { "://" }, StringSplitOptions.None);
+			var controllerName = actionParts.Length == 2
+									? actionParts[0]
+									: null;
+
+			var pathInfo = actionParts[actionParts.Length - 1];
+
+			var optionMap = new Dictionary<string, string>();
+
+			var optionsPos = pathInfo.LastIndexOf('?');
+			if (optionsPos != -1)
+			{
+				var options = pathInfo.Substring(optionsPos + 1).Split('&');
+				foreach (var option in options)
+				{
+					var keyValuePair = option.Split('=');
+
+					optionMap[keyValuePair[0]] = keyValuePair.Length == 1
+													? true.ToString()
+													: keyValuePair[1].UrlDecode();
+				}
+				pathInfo = pathInfo.Substring(0, optionsPos);
+			}
+
+			var args = pathInfo.Split('/');
+			var pageName = args[0];
+
+			return new PathInfo(pageName, args.Skip(1).ToList(), optionMap) {
+				ControllerName = controllerName
+			};
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/CsvConfig.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/CsvConfig.cs
new file mode 100644
index 0000000..bd9c25e
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/CsvConfig.cs
@@ -0,0 +1,56 @@
+using System;
+using System.Collections.Generic;
+
+namespace ServiceStack.Text
+{
+	public static class CsvConfig<T>
+	{
+		public static bool OmitHeaders { get; set; }
+
+		private static Dictionary<string, string> customHeadersMap;
+		public static Dictionary<string, string> CustomHeadersMap
+		{
+			get
+			{
+				return customHeadersMap;
+			}
+			set
+			{
+				customHeadersMap = value;
+				if (value == null) return;
+				CsvWriter<T>.ConfigureCustomHeaders(customHeadersMap);
+			}
+		}
+
+		public static object CustomHeaders
+		{
+			set
+			{
+				if (value == null) return;
+				if (value.GetType().IsValueType)
+					throw new ArgumentException("CustomHeaders is a ValueType");
+
+				var propertyInfos = value.GetType().GetProperties();
+				if (propertyInfos.Length == 0) return;
+
+				customHeadersMap = new Dictionary<string, string>();
+				foreach (var pi in propertyInfos)
+				{
+					var getMethod = pi.GetGetMethod();
+					if (getMethod == null) continue;
+
+					var oValue = getMethod.Invoke(value, new object[0]);
+					if (oValue == null) continue;
+					customHeadersMap[pi.Name] = oValue.ToString();
+				}
+				CsvWriter<T>.ConfigureCustomHeaders(customHeadersMap);
+			}
+		}
+
+		public static void Reset()
+		{
+			OmitHeaders = false;
+			CsvWriter<T>.Reset();
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/CsvSerializer.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/CsvSerializer.cs
new file mode 100644
index 0000000..1e25adf
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/CsvSerializer.cs
@@ -0,0 +1,274 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Reflection;
+using System.Text;
+using System.Threading;
+using ServiceStack.Text.Common;
+using ServiceStack.Text.Jsv;
+using ServiceStack.Text.Reflection;
+
+namespace ServiceStack.Text
+{
+	public class CsvSerializer
+	{
+		private static readonly UTF8Encoding UTF8EncodingWithoutBom = new UTF8Encoding(false);
+
+		private static Dictionary<Type, WriteObjectDelegate> WriteFnCache = new Dictionary<Type, WriteObjectDelegate>();
+
+		internal static WriteObjectDelegate GetWriteFn(Type type)
+		{
+			try
+			{
+				WriteObjectDelegate writeFn;
+                if (WriteFnCache.TryGetValue(type, out writeFn)) return writeFn;
+
+                var genericType = typeof(CsvSerializer<>).MakeGenericType(type);
+                var mi = genericType.GetMethod("WriteFn", BindingFlags.Public | BindingFlags.Static);
+                var writeFactoryFn = (Func<WriteObjectDelegate>)Delegate.CreateDelegate(
+                    typeof(Func<WriteObjectDelegate>), mi);
+                writeFn = writeFactoryFn();
+
+                Dictionary<Type, WriteObjectDelegate> snapshot, newCache;
+                do
+                {
+                    snapshot = WriteFnCache;
+                    newCache = new Dictionary<Type, WriteObjectDelegate>(WriteFnCache);
+                    newCache[type] = writeFn;
+
+                } while (!ReferenceEquals(
+                    Interlocked.CompareExchange(ref WriteFnCache, newCache, snapshot), snapshot));
+                
+                return writeFn;
+			}
+			catch (Exception ex)
+			{
+				Tracer.Instance.WriteError(ex);
+				throw;
+			}
+		}
+
+		public static string SerializeToCsv<T>(IEnumerable<T> records)
+		{
+			var sb = new StringBuilder();
+			using (var writer = new StringWriter(sb, CultureInfo.InvariantCulture))
+			{
+				writer.WriteCsv(records);
+				return sb.ToString();
+			}
+		}
+
+		public static string SerializeToString<T>(T value)
+		{
+			if (value == null) return null;
+			if (typeof(T) == typeof(string)) return value as string;
+
+			var sb = new StringBuilder();
+			using (var writer = new StringWriter(sb, CultureInfo.InvariantCulture))
+			{
+				CsvSerializer<T>.WriteObject(writer, value);
+			}
+			return sb.ToString();
+		}
+
+		public static void SerializeToWriter<T>(T value, TextWriter writer)
+		{
+			if (value == null) return;
+			if (typeof(T) == typeof(string))
+			{
+				writer.Write(value);
+				return;
+			}
+			CsvSerializer<T>.WriteObject(writer, value);
+		}
+
+		public static void SerializeToStream<T>(T value, Stream stream)
+		{
+			if (value == null) return;
+			using (var writer = new StreamWriter(stream, UTF8EncodingWithoutBom))
+			{
+				CsvSerializer<T>.WriteObject(writer, value);
+			}
+		}
+
+		public static void SerializeToStream(object obj, Stream stream)
+		{
+			if (obj == null) return;
+			using (var writer = new StreamWriter(stream, UTF8EncodingWithoutBom))
+			{
+				var writeFn = GetWriteFn(obj.GetType());
+				writeFn(writer, obj);
+			}
+		}
+
+		public static T DeserializeFromStream<T>(Stream stream)
+		{
+            throw new NotImplementedException();
+		}
+
+		public static object DeserializeFromStream(Type type, Stream stream)
+		{
+            throw new NotImplementedException();
+		}
+
+		public static void WriteLateBoundObject(TextWriter writer, object value)
+		{
+			if (value == null) return;
+			var writeFn = GetWriteFn(value.GetType());
+			writeFn(writer, value);
+		}
+	}
+
+	internal static class CsvSerializer<T>
+	{
+		private static readonly WriteObjectDelegate CacheFn;
+
+		public static WriteObjectDelegate WriteFn()
+		{
+			return CacheFn;
+		}
+
+		private const string IgnoreResponseStatus = "ResponseStatus";
+
+		private static Func<object, object> valueGetter = null;
+		private static WriteObjectDelegate writeElementFn = null;
+
+		private static WriteObjectDelegate GetWriteFn()
+		{
+			PropertyInfo firstCandidate = null;
+			Type bestCandidateEnumerableType = null;
+			PropertyInfo bestCandidate = null;
+
+			if (typeof(T).IsValueType)
+			{
+				return JsvWriter<T>.WriteObject;
+			}
+
+			//If type is an enumerable property itself write that
+			bestCandidateEnumerableType = typeof(T).GetTypeWithGenericTypeDefinitionOf(typeof(IEnumerable<>));
+			if (bestCandidateEnumerableType != null)
+			{
+				var elementType = bestCandidateEnumerableType.GetGenericArguments()[0];
+				writeElementFn = CreateWriteFn(elementType);
+
+				return WriteEnumerableType;
+			}
+
+			//Look for best candidate property if DTO
+			if (typeof(T).IsDto())
+			{
+				var properties = TypeConfig<T>.Properties;
+				foreach (var propertyInfo in properties)
+				{
+					if (propertyInfo.Name == IgnoreResponseStatus) continue;
+
+					if (propertyInfo.PropertyType == typeof(string)
+						|| propertyInfo.PropertyType.IsValueType
+						|| propertyInfo.PropertyType == typeof(byte[])) continue;
+
+					if (firstCandidate == null)
+					{
+						firstCandidate = propertyInfo;
+					}
+
+					var enumProperty = propertyInfo.PropertyType
+						.GetTypeWithGenericTypeDefinitionOf(typeof(IEnumerable<>));
+
+					if (enumProperty != null)
+					{
+						bestCandidateEnumerableType = enumProperty;
+						bestCandidate = propertyInfo;
+						break;
+					}
+				}
+			}
+
+			//If is not DTO or no candidates exist, write self
+			var noCandidatesExist = bestCandidate == null && firstCandidate == null;
+			if (noCandidatesExist)
+			{
+				return WriteSelf;
+			}
+
+			//If is DTO and has an enumerable property serialize that
+			if (bestCandidateEnumerableType != null)
+			{
+				valueGetter = bestCandidate.GetValueGetter(typeof(T));
+
+				var elementType = bestCandidateEnumerableType.GetGenericArguments()[0];
+				writeElementFn = CreateWriteFn(elementType);
+
+				return WriteEnumerableProperty;
+			}
+
+			//If is DTO and has non-enumerable, reference type property serialize that
+			valueGetter = firstCandidate.GetValueGetter(typeof(T));
+			writeElementFn = CreateWriteRowFn(firstCandidate.PropertyType);
+
+			return WriteNonEnumerableType;
+		}
+
+		private static WriteObjectDelegate CreateWriteFn(Type elementType)
+		{
+			return CreateCsvWriterFn(elementType, "WriteObject");
+		}
+
+		private static WriteObjectDelegate CreateWriteRowFn(Type elementType)
+		{
+			return CreateCsvWriterFn(elementType, "WriteObjectRow");
+		}
+
+		private static WriteObjectDelegate CreateCsvWriterFn(Type elementType, string methodName)
+		{
+			var genericType = typeof(CsvWriter<>).MakeGenericType(elementType);
+			var mi = genericType.GetMethod(methodName, 
+				BindingFlags.Static | BindingFlags.Public);
+
+			var writeFn = (WriteObjectDelegate)Delegate.CreateDelegate(typeof(WriteObjectDelegate), mi);
+
+			return writeFn;
+		}
+
+		public static void WriteEnumerableType(TextWriter writer, object obj)
+		{
+			writeElementFn(writer, obj);
+		}
+
+		public static void WriteSelf(TextWriter writer, object obj)
+		{
+			CsvWriter<T>.WriteRow(writer, (T)obj);
+		}
+
+		public static void WriteEnumerableProperty(TextWriter writer, object obj)
+		{
+			if (obj == null) return; //AOT
+
+			var enumerableProperty = valueGetter(obj);
+			writeElementFn(writer, enumerableProperty);
+		}
+
+		public static void WriteNonEnumerableType(TextWriter writer, object obj)
+		{
+			var nonEnumerableType = valueGetter(obj);
+			writeElementFn(writer, nonEnumerableType);
+		}
+
+		static CsvSerializer()
+		{
+			if (typeof(T) == typeof(object))
+			{
+				CacheFn = CsvSerializer.WriteLateBoundObject;
+			}
+			else
+			{
+				CacheFn = GetWriteFn();
+			}
+		}
+
+		public static void WriteObject(TextWriter writer, object value)
+		{
+			CacheFn(writer, value);
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/CsvStreamExtensions.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/CsvStreamExtensions.cs
new file mode 100644
index 0000000..13f7fc6
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/CsvStreamExtensions.cs
@@ -0,0 +1,34 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System.Collections.Generic;
+using System.IO;
+
+namespace ServiceStack.Text
+{
+	public static class CsvStreamExtensions
+	{
+		public static void WriteCsv<T>(this Stream outputStream, IEnumerable<T> records)
+		{
+			using (var textWriter = new StreamWriter(outputStream))
+			{
+				textWriter.WriteCsv(records);
+			}
+		}
+
+		public static void WriteCsv<T>(this TextWriter writer, IEnumerable<T> records)
+		{
+			CsvWriter<T>.Write(writer, records);
+		}
+
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/CsvWriter.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/CsvWriter.cs
new file mode 100644
index 0000000..e64c023
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/CsvWriter.cs
@@ -0,0 +1,209 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using ServiceStack.Text.Common;
+using ServiceStack.Text.Reflection;
+
+namespace ServiceStack.Text
+{
+	internal class CsvWriter<T>
+	{
+		public const char DelimiterChar = ',';
+
+		public static List<string> Headers { get; set; }
+
+		internal static List<Func<T, object>> PropertyGetters;
+
+		private static readonly WriteObjectDelegate OptimizedWriter;
+
+		static CsvWriter()
+		{
+			if (typeof(T) == typeof(string))
+			{
+				OptimizedWriter = (w, o) => WriteRow(w, (IEnumerable<string>)o);
+				return;
+			}
+
+			Reset();
+		}
+
+		internal static void Reset()
+		{
+			Headers = new List<string>();
+
+			PropertyGetters = new List<Func<T, object>>();
+			foreach (var propertyInfo in TypeConfig<T>.Properties)
+			{
+				if (!propertyInfo.CanRead || propertyInfo.GetGetMethod() == null) continue;
+				if (!TypeSerializer.CanCreateFromString(propertyInfo.PropertyType)) continue;
+
+				PropertyGetters.Add(propertyInfo.GetValueGetter<T>());
+				Headers.Add(propertyInfo.Name);
+			}
+		}
+
+		internal static void ConfigureCustomHeaders(Dictionary<string, string> customHeadersMap)
+		{
+			Reset();
+
+			for (var i = Headers.Count - 1; i >= 0; i--)
+			{
+				var oldHeader = Headers[i];
+				string newHeaderValue;
+				if (!customHeadersMap.TryGetValue(oldHeader, out newHeaderValue))
+				{
+					Headers.RemoveAt(i);
+					PropertyGetters.RemoveAt(i);
+				}
+				else
+				{
+					Headers[i] = newHeaderValue.EncodeJsv();
+				}
+			}
+		}
+
+		private static List<string> GetSingleRow(IEnumerable<T> records, Type recordType)
+		{
+			var row = new List<string>();
+			foreach (var value in records)
+			{
+				var strValue = recordType == typeof(string)
+				   ? value as string
+				   : TypeSerializer.SerializeToString(value);
+
+				row.Add(strValue);
+			}
+			return row;
+		}
+
+		public static List<List<string>> GetRows(IEnumerable<T> records)
+		{
+			var rows = new List<List<string>>();
+
+			if (records == null) return rows;
+
+			if (typeof(T).IsValueType || typeof(T) == typeof(string))
+			{
+				rows.Add(GetSingleRow(records, typeof(T)));
+				return rows;
+			}
+
+			foreach (var record in records)
+			{
+				var row = new List<string>();
+				foreach (var propertyGetter in PropertyGetters)
+				{
+					var value = propertyGetter(record) ?? "";
+
+					var strValue = value.GetType() == typeof(string)
+						? (string)value
+						: TypeSerializer.SerializeToString(value);
+
+					row.Add(strValue);
+				}
+				rows.Add(row);
+			}
+
+			return rows;
+		}
+
+		public static void WriteObject(TextWriter writer, object records)
+		{
+			Write(writer, (IEnumerable<T>)records);
+		}
+
+		public static void WriteObjectRow(TextWriter writer, object record)
+		{
+			WriteRow(writer, (T)record);
+		}
+
+		public static void Write(TextWriter writer, IEnumerable<T> records)
+		{
+			if (records == null) return; //AOT
+
+			if (OptimizedWriter != null)
+			{
+				OptimizedWriter(writer, records);
+				return;
+			}
+
+			if (!CsvConfig<T>.OmitHeaders && Headers.Count > 0)
+			{
+				var ranOnce = false;
+				foreach (var header in Headers)
+				{
+					JsWriter.WriteItemSeperatorIfRanOnce(writer, ref ranOnce);
+
+					writer.Write(header);
+				}
+				writer.WriteLine();
+			}
+
+			if (records == null) return;
+
+			if (typeof(T).IsValueType || typeof(T) == typeof(string))
+			{
+				var singleRow = GetSingleRow(records, typeof(T));
+				WriteRow(writer, singleRow);
+				return;
+			}
+
+			var row = new string[Headers.Count];
+			foreach (var record in records)
+			{
+				for (var i = 0; i < PropertyGetters.Count; i++)
+				{
+					var propertyGetter = PropertyGetters[i];
+					var value = propertyGetter(record) ?? "";
+
+					var strValue = value.GetType() == typeof(string)
+					   ? (string)value
+					   : TypeSerializer.SerializeToString(value);
+
+					row[i] = strValue;
+				}
+				WriteRow(writer, row);
+			}
+		}
+
+		public static void WriteRow(TextWriter writer, T row)
+		{
+			if (row == null) return; //AOT
+
+			Write(writer, new[] { row });
+		}
+
+		public static void WriteRow(TextWriter writer, IEnumerable<string> row)
+		{
+			var ranOnce = false;
+			foreach (var field in row)
+			{
+				JsWriter.WriteItemSeperatorIfRanOnce(writer, ref ranOnce);
+
+				writer.Write(field.ToCsvField());
+			}
+			writer.WriteLine();
+		}
+
+		public static void Write(TextWriter writer, IEnumerable<List<string>> rows)
+		{
+			if (Headers.Count > 0)
+			{
+				var ranOnce = false;
+				foreach (var header in Headers)
+				{
+					JsWriter.WriteItemSeperatorIfRanOnce(writer, ref ranOnce);
+
+					writer.Write(header);
+				}
+				writer.WriteLine();
+			}
+
+			foreach (var row in rows)
+			{
+				WriteRow(writer, row);
+			}
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/DateTimeExtensions.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/DateTimeExtensions.cs
new file mode 100644
index 0000000..9cd41eb
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/DateTimeExtensions.cs
@@ -0,0 +1,136 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using ServiceStack.Text.Common;
+
+namespace ServiceStack.Text
+{
+	/// <summary>
+	/// A fast, standards-based, serialization-issue free DateTime serailizer.
+	/// </summary>
+	public static class DateTimeExtensions
+	{
+		public const long UnixEpoch = 621355968000000000L;
+		private static readonly DateTime UnixEpochDateTimeUtc = new DateTime(UnixEpoch, DateTimeKind.Utc);
+		private static readonly DateTime UnixEpochDateTimeUnspecified = new DateTime(UnixEpoch, DateTimeKind.Unspecified);
+
+		public static long ToUnixTime(this DateTime dateTime)
+		{
+			return (dateTime.ToStableUniversalTime().Ticks - UnixEpoch) / TimeSpan.TicksPerSecond;
+		}
+
+		public static DateTime FromUnixTime(this double unixTime)
+		{
+			return UnixEpochDateTimeUtc + TimeSpan.FromSeconds(unixTime);
+		}
+
+		public static long ToUnixTimeMs(this DateTime dateTime)
+		{
+			return (dateTime.ToStableUniversalTime().Ticks - UnixEpoch) / TimeSpan.TicksPerMillisecond;
+		}
+
+		public static DateTime FromUnixTimeMs(this double msSince1970)
+		{
+			return UnixEpochDateTimeUtc + TimeSpan.FromMilliseconds(msSince1970);
+		}
+
+		public static DateTime FromUnixTimeMs(this long msSince1970)
+		{
+			return UnixEpochDateTimeUtc + TimeSpan.FromMilliseconds(msSince1970);
+		}
+
+		public static DateTime FromUnixTimeMs(this long msSince1970, TimeSpan offset)
+		{
+			return UnixEpochDateTimeUnspecified + TimeSpan.FromMilliseconds(msSince1970) + offset;
+		}
+
+		public static DateTime FromUnixTimeMs(this double msSince1970, TimeSpan offset)
+		{
+			return UnixEpochDateTimeUnspecified + TimeSpan.FromMilliseconds(msSince1970) + offset;
+		}
+
+		public static DateTime FromUnixTimeMs(string msSince1970)
+		{
+			long ms;
+			if (long.TryParse(msSince1970, out ms)) return ms.FromUnixTimeMs();
+
+			// Do we really need to support fractional unix time ms time strings??
+			return double.Parse(msSince1970).FromUnixTimeMs();
+		}
+
+		public static DateTime FromUnixTimeMs(string msSince1970, TimeSpan offset)
+		{
+			long ms;
+			if (long.TryParse(msSince1970, out ms)) return ms.FromUnixTimeMs(offset);
+
+			// Do we really need to support fractional unix time ms time strings??
+			return double.Parse(msSince1970).FromUnixTimeMs(offset);
+		}
+
+		public static DateTime RoundToMs(this DateTime dateTime)
+		{
+			return new DateTime((dateTime.Ticks / TimeSpan.TicksPerMillisecond) * TimeSpan.TicksPerMillisecond);
+		}
+
+		public static DateTime RoundToSecond(this DateTime dateTime)
+		{
+			return new DateTime((dateTime.Ticks / TimeSpan.TicksPerSecond) * TimeSpan.TicksPerSecond);
+		}
+
+		public static string ToShortestXsdDateTimeString(this DateTime dateTime)
+		{
+			return DateTimeSerializer.ToShortestXsdDateTimeString(dateTime);
+		}
+
+		public static DateTime FromShortestXsdDateTimeString(this string xsdDateTime)
+		{
+			return DateTimeSerializer.ParseShortestXsdDateTime(xsdDateTime);
+		}
+
+		public static bool IsEqualToTheSecond(this DateTime dateTime, DateTime otherDateTime)
+		{
+			return dateTime.ToStableUniversalTime().RoundToSecond().Equals(otherDateTime.ToStableUniversalTime().RoundToSecond());
+		}
+
+		public static string ToTimeOffsetString(this TimeSpan offset, bool includeColon = false)
+		{
+			var sign = offset < TimeSpan.Zero ? "-" : "+";
+			var hours = Math.Abs(offset.Hours);
+			var minutes = Math.Abs(offset.Minutes);
+			var separator = includeColon ? ":" : "";
+			return string.Format("{0}{1:00}{2}{3:00}", sign, hours, separator, minutes);
+		}
+
+		public static TimeSpan FromTimeOffsetString(this string offsetString)
+		{
+			if (!offsetString.Contains(":"))
+				offsetString = offsetString.Insert(offsetString.Length - 2, ":");
+
+			offsetString = offsetString.TrimStart('+');
+
+			return TimeSpan.Parse(offsetString);
+		}
+
+		public static DateTime ToStableUniversalTime(this DateTime dateTime)
+		{
+#if SILVERLIGHT
+			// Silverlight 3, 4 and 5 all work ok with DateTime.ToUniversalTime, but have no TimeZoneInfo.ConverTimeToUtc implementation.
+			return dateTime.ToUniversalTime();
+#else
+			// .Net 2.0 - 3.5 has an issue with DateTime.ToUniversalTime, but works ok with TimeZoneInfo.ConvertTimeToUtc.
+			// .Net 4.0+ does this under the hood anyway.
+			return TimeZoneInfo.ConvertTimeToUtc(dateTime);
+#endif
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Env.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Env.cs
new file mode 100644
index 0000000..c71b736
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Env.cs
@@ -0,0 +1,40 @@
+
+using System;
+
+namespace ServiceStack.Text
+{
+	public static class Env
+	{
+		static Env()
+		{
+			var platform = (int)Environment.OSVersion.Platform;
+			IsUnix = (platform == 4) || (platform == 6) || (platform == 128);
+
+			IsMono = Type.GetType("Mono.Runtime") != null;
+
+			IsMonoTouch = Type.GetType("MonoTouch.Foundation.NSObject") != null;
+
+			SupportsExpressions = SupportsEmit = !IsMonoTouch;
+
+			ServerUserAgent = "ServiceStack/" +
+				ServiceStackVersion + " "
+				+ Environment.OSVersion.Platform
+				+ (IsMono ? "/Mono" : "/.NET")
+				+ (IsMonoTouch ? " MonoTouch" : "");
+		}
+
+		public static decimal ServiceStackVersion = 3.55m;
+
+		public static bool IsUnix { get; set; }
+
+		public static bool IsMono { get; set; }
+
+		public static bool IsMonoTouch { get; set; }
+
+		public static bool SupportsExpressions { get; set; }
+
+		public static bool SupportsEmit { get; set; }
+
+		public static string ServerUserAgent { get; set; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/ITracer.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/ITracer.cs
new file mode 100644
index 0000000..5659600
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/ITracer.cs
@@ -0,0 +1,16 @@
+using System;
+
+namespace ServiceStack.Text
+{
+	public interface ITracer
+	{
+        void WriteDebug(string error);
+        void WriteDebug(string format, params object[] args);
+        void WriteWarning(string warning);
+        void WriteWarning(string format, params object[] args);
+		
+		void WriteError(Exception ex);
+		void WriteError(string error);
+		void WriteError(string format, params object[] args);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/ITypeSerializer.Generic.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/ITypeSerializer.Generic.cs
new file mode 100644
index 0000000..62708bb
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/ITypeSerializer.Generic.cs
@@ -0,0 +1,57 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.IO;
+
+namespace ServiceStack.Text
+{
+	public interface ITypeSerializer<T>
+	{
+		/// <summary>
+		/// Determines whether this serializer can create the specified type from a string.
+		/// </summary>
+		/// <param name="type">The type.</param>
+		/// <returns>
+		/// 	<c>true</c> if this instance [can create from string] the specified type; otherwise, <c>false</c>.
+		/// </returns>
+		bool CanCreateFromString(Type type);
+
+		/// <summary>
+		/// Parses the specified value.
+		/// </summary>
+		/// <param name="value">The value.</param>
+		/// <returns></returns>
+		T DeserializeFromString(string value);
+
+		/// <summary>
+		/// Deserializes from reader.
+		/// </summary>
+		/// <param name="reader">The reader.</param>
+		/// <returns></returns>
+		T DeserializeFromReader(TextReader reader);
+
+		/// <summary>
+		/// Serializes to string.
+		/// </summary>
+		/// <param name="value">The value.</param>
+		/// <returns></returns>
+		string SerializeToString(T value);
+
+		/// <summary>
+		/// Serializes to writer.
+		/// </summary>
+		/// <param name="value">The value.</param>
+		/// <param name="writer">The writer.</param>
+		void SerializeToWriter(T value, TextWriter writer);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/JsConfig.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/JsConfig.cs
new file mode 100644
index 0000000..43f8a9f
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/JsConfig.cs
@@ -0,0 +1,338 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using ServiceStack.Text.Common;
+using ServiceStack.Text.Json;
+using ServiceStack.Text.Jsv;
+
+namespace ServiceStack.Text
+{
+	public static class
+		JsConfig
+	{
+		static JsConfig()
+		{
+			//In-built default serialization, to Deserialize Color struct do:
+			//JsConfig<System.Drawing.Color>.SerializeFn = c => c.ToString().Replace("Color ", "").Replace("[", "").Replace("]", "");
+			//JsConfig<System.Drawing.Color>.DeSerializeFn = System.Drawing.Color.FromName;
+		}
+		
+		[ThreadStatic]
+		private static bool? tsConvertObjectTypesIntoStringDictionary;
+		private static bool? sConvertObjectTypesIntoStringDictionary;
+		public static bool ConvertObjectTypesIntoStringDictionary
+		{
+			get
+			{
+				return tsConvertObjectTypesIntoStringDictionary ?? sConvertObjectTypesIntoStringDictionary ?? false;
+			}
+			set
+			{
+				if (!tsConvertObjectTypesIntoStringDictionary.HasValue) tsConvertObjectTypesIntoStringDictionary = value;
+				if (!sConvertObjectTypesIntoStringDictionary.HasValue) sConvertObjectTypesIntoStringDictionary = value;
+			}
+		}
+
+		[ThreadStatic]
+		private static bool? tsIncludeNullValues;
+		private static bool? sIncludeNullValues;
+		public static bool IncludeNullValues
+		{
+			get
+			{
+				return tsIncludeNullValues ?? sIncludeNullValues ?? false;
+			}
+			set
+			{
+				if (!tsIncludeNullValues.HasValue) tsIncludeNullValues = value;
+				if (!sIncludeNullValues.HasValue) sIncludeNullValues = value;
+			}
+		}
+
+		[ThreadStatic]
+		private static bool? tsExcludeTypeInfo;
+		private static bool? sExcludeTypeInfo;
+		public static bool ExcludeTypeInfo
+		{
+			get
+			{
+				return tsExcludeTypeInfo ?? sExcludeTypeInfo ?? false;
+			}
+			set
+			{
+				if (!tsExcludeTypeInfo.HasValue) tsExcludeTypeInfo = value;
+				if (!sExcludeTypeInfo.HasValue) sExcludeTypeInfo = value;
+			}
+		}
+
+		[ThreadStatic]
+		private static JsonDateHandler? tsDateHandler;
+		private static JsonDateHandler? sDateHandler;
+		public static JsonDateHandler DateHandler
+		{
+			get
+			{
+				return tsDateHandler ?? sDateHandler ?? JsonDateHandler.TimestampOffset;
+			}
+			set
+			{
+				if (!tsDateHandler.HasValue) tsDateHandler = value;
+				if (!sDateHandler.HasValue) sDateHandler = value;
+			}
+		}
+
+
+		/// <summary>
+		/// <see langword="true"/> if the <see cref="ITypeSerializer"/> is configured
+		/// to take advantage of <see cref="CLSCompliantAttribute"/> specification,
+		/// to support user-friendly serialized formats, ie emitting camelCasing for JSON
+		/// and parsing member names and enum values in a case-insensitive manner.
+		/// </summary>
+		[ThreadStatic]
+		private static bool? tsEmitCamelCaseNames;
+		private static bool? sEmitCamelCaseNames;
+		public static bool EmitCamelCaseNames
+		{
+			// obeying the use of ThreadStatic, but allowing for setting JsConfig once as is the normal case
+			get
+			{
+				return tsEmitCamelCaseNames ?? sEmitCamelCaseNames ?? false;
+			}
+			set
+			{
+				if (!tsEmitCamelCaseNames.HasValue) tsEmitCamelCaseNames = value;
+				if (!sEmitCamelCaseNames.HasValue) sEmitCamelCaseNames = value;
+			}
+		}
+
+		internal static HashSet<Type> HasSerializeFn = new HashSet<Type>();
+
+		public static void Reset()
+		{
+			tsConvertObjectTypesIntoStringDictionary = sConvertObjectTypesIntoStringDictionary = null;
+			tsIncludeNullValues = sIncludeNullValues = null;
+			tsExcludeTypeInfo = sExcludeTypeInfo = null;
+			tsEmitCamelCaseNames = sEmitCamelCaseNames = null;
+			tsDateHandler = sDateHandler = null;
+			HasSerializeFn = new HashSet<Type>();
+		}
+
+#if SILVERLIGHT || MONOTOUCH
+        /// <summary>
+        /// Provide hint to MonoTouch AOT compiler to pre-compile generic classes for all your DTOs.
+        /// Just needs to be called once in a static constructor.
+        /// </summary>
+        public static void InitForAot() { }
+
+        public static void RegisterForAot()
+        {
+            JsonAotConfig.Register<Poco>();
+
+            RegisterElement<Poco, string>();
+
+            RegisterElement<Poco, bool>();
+            RegisterElement<Poco, char>();
+            RegisterElement<Poco, byte>();
+            RegisterElement<Poco, sbyte>();
+            RegisterElement<Poco, short>();
+            RegisterElement<Poco, ushort>();
+            RegisterElement<Poco, int>();
+            RegisterElement<Poco, uint>();
+            RegisterElement<Poco, long>();
+            RegisterElement<Poco, ulong>();
+            RegisterElement<Poco, float>();
+            RegisterElement<Poco, double>();
+            RegisterElement<Poco, decimal>();
+            RegisterElement<Poco, Guid>();
+            RegisterElement<Poco, DateTime>();
+            RegisterElement<Poco, TimeSpan>();
+
+            RegisterElement<Poco, bool?>();
+            RegisterElement<Poco, char?>();
+            RegisterElement<Poco, byte?>();
+            RegisterElement<Poco, sbyte?>();
+            RegisterElement<Poco, short?>();
+            RegisterElement<Poco, ushort?>();
+            RegisterElement<Poco, int?>();
+            RegisterElement<Poco, uint?>();
+            RegisterElement<Poco, long?>();
+            RegisterElement<Poco, ulong?>();
+            RegisterElement<Poco, float?>();
+            RegisterElement<Poco, double?>();
+            RegisterElement<Poco, decimal?>();
+            RegisterElement<Poco, Guid?>();
+            RegisterElement<Poco, DateTime?>();
+            RegisterElement<Poco, TimeSpan?>();
+
+            RegisterQueryStringWriter();
+            RegisterCsvSerializer();
+        }
+
+        static void RegisterQueryStringWriter()
+        {
+            var i = 0;
+            if (QueryStringWriter<Poco>.WriteFn() != null) i++;
+        }
+
+        static void RegisterCsvSerializer()
+        {
+            CsvSerializer<Poco>.WriteFn();
+            CsvSerializer<Poco>.WriteObject(null, null);
+            CsvWriter<Poco>.WriteObject(null, null);
+            CsvWriter<Poco>.WriteObjectRow(null, null);
+        }
+
+        public static void RegisterElement<T, TElement>()
+        {
+            JsonAotConfig.RegisterElement<T, TElement>();
+        }
+#endif
+
+	}
+
+#if SILVERLIGHT || MONOTOUCH
+    internal class Poco
+    {
+        public string Dummy { get; set; }
+    }
+
+    internal class JsonAotConfig
+    {
+        static JsReader<JsonTypeSerializer> reader;
+        static JsonTypeSerializer serializer;
+
+        static JsonAotConfig()
+        {
+            serializer = new JsonTypeSerializer();
+            reader = new JsReader<JsonTypeSerializer>();
+        }
+
+        public static ParseStringDelegate GetParseFn(Type type)
+        {
+            var parseFn = JsonTypeSerializer.Instance.GetParseFn(type);
+            return parseFn;
+        }
+
+        internal static ParseStringDelegate RegisterBuiltin<T>()
+        {
+            var i = 0;
+            if (reader.GetParseFn<T>() != null) i++;
+            if (JsonReader<T>.GetParseFn() != null) i++;
+            if (JsonReader<T>.Parse(null) != null) i++;
+            if (JsonWriter<T>.WriteFn() != null) i++;
+
+            return serializer.GetParseFn<T>();
+        }
+
+        public static void Register<T>()
+        {
+            var i = 0;
+            var serializer = JsonTypeSerializer.Instance;
+            if (new List<T>() != null) i++;
+            if (new T[0] != null) i++;
+            if (serializer.GetParseFn<T>() != null) i++;
+            if (DeserializeArray<T[], JsonTypeSerializer>.Parse != null) i++;
+
+            JsConfig<T>.ExcludeTypeInfo = false;
+            //JsConfig<T>.SerializeFn = arg => "";
+            //JsConfig<T>.DeSerializeFn = arg => default(T);
+
+            DeserializeArrayWithElements<T, JsonTypeSerializer>.ParseGenericArray(null, null);
+            DeserializeCollection<JsonTypeSerializer>.ParseCollection<T>(null, null, null);
+            DeserializeListWithElements<T, JsonTypeSerializer>.ParseGenericList(null, null, null);
+
+            SpecializedQueueElements<T>.ConvertToQueue(null);
+            SpecializedQueueElements<T>.ConvertToStack(null);
+
+            WriteListsOfElements<T, JsonTypeSerializer>.WriteList(null, null);
+            WriteListsOfElements<T, JsonTypeSerializer>.WriteIList(null, null);
+            WriteListsOfElements<T, JsonTypeSerializer>.WriteEnumerable(null, null);
+            WriteListsOfElements<T, JsonTypeSerializer>.WriteListValueType(null, null);
+            WriteListsOfElements<T, JsonTypeSerializer>.WriteIListValueType(null, null);
+
+            JsonReader<T>.Parse(null);
+            JsonWriter<T>.WriteFn();
+
+            TranslateListWithElements<T>.LateBoundTranslateToGenericICollection(null, null);
+            TranslateListWithConvertibleElements<T, T>.LateBoundTranslateToGenericICollection(null, null);
+
+            QueryStringWriter<T>.WriteObject(null, null);
+        }
+
+        public static void RegisterElement<T, TElement>()
+        {
+            RegisterBuiltin<TElement>();
+            DeserializeDictionary<JsonTypeSerializer>.ParseDictionary<T, TElement>(null, null, null, null);
+            DeserializeDictionary<JsonTypeSerializer>.ParseDictionary<TElement, T>(null, null, null, null);
+
+            ToStringDictionaryMethods<T, TElement, JsonTypeSerializer>.WriteIDictionary(null, null, null, null);
+            ToStringDictionaryMethods<TElement, T, JsonTypeSerializer>.WriteIDictionary(null, null, null, null);
+
+            TranslateListWithElements<TElement>.LateBoundTranslateToGenericICollection(null, typeof(List<TElement>));
+            TranslateListWithConvertibleElements<TElement, TElement>.LateBoundTranslateToGenericICollection(null, typeof(List<TElement>));
+        }
+    }
+#endif
+
+	public class JsConfig<T> //where T : struct
+	{
+		/// <summary>
+		/// Never emit type info for this type
+		/// </summary>
+		public static bool ExcludeTypeInfo = false;
+
+		/// <summary>
+		/// <see langword="true"/> if the <see cref="ITypeSerializer"/> is configured
+		/// to take advantage of <see cref="CLSCompliantAttribute"/> specification,
+		/// to support user-friendly serialized formats, ie emitting camelCasing for JSON
+		/// and parsing member names and enum values in a case-insensitive manner.
+		/// </summary>
+		public static bool EmitCamelCaseNames = false;
+
+		/// <summary>
+		/// Define custom serialization fn for BCL Structs
+		/// </summary>
+		private static Func<T, string> serializeFn;
+		public static Func<T, string> SerializeFn
+		{
+			get { return serializeFn; }
+			set
+			{
+				serializeFn = value;
+				if (value != null)
+					JsConfig.HasSerializeFn.Add(typeof(T));
+				else
+					JsConfig.HasSerializeFn.Remove(typeof(T));
+			}
+		}
+
+		/// <summary>
+		/// Define custom deserialization fn for BCL Structs
+		/// </summary>
+		public static Func<string, T> DeSerializeFn;
+
+		/// <summary>
+		/// Exclude specific properties of this type from being serialized
+		/// </summary>
+		public static string[] ExcludePropertyNames;
+
+		public static void WriteFn<TSerializer>(TextWriter writer, object obj)
+		{
+			var serializer = JsWriter.GetTypeSerializer<TSerializer>();
+			serializer.WriteString(writer, SerializeFn((T)obj));
+		}
+
+		public static object ParseFn(string str)
+		{
+			return DeSerializeFn(str);
+		}
+	}
+
+	public enum JsonDateHandler
+	{
+		TimestampOffset,
+		DCJSCompatible,
+		ISO8601
+	}
+}
+
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Json/JsonReader.Generic.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Json/JsonReader.Generic.cs
new file mode 100644
index 0000000..cab7593
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Json/JsonReader.Generic.cs
@@ -0,0 +1,87 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Threading;
+using ServiceStack.Text.Common;
+
+namespace ServiceStack.Text.Json
+{
+	internal static class JsonReader
+	{
+		public static readonly JsReader<JsonTypeSerializer> Instance = new JsReader<JsonTypeSerializer>();
+
+		private static Dictionary<Type, ParseFactoryDelegate> ParseFnCache = new Dictionary<Type, ParseFactoryDelegate>();
+        
+		public static ParseStringDelegate GetParseFn(Type type)
+		{
+			ParseFactoryDelegate parseFactoryFn;
+            ParseFnCache.TryGetValue(type, out parseFactoryFn);
+
+            if (parseFactoryFn != null) return parseFactoryFn();
+
+            var genericType = typeof(JsonReader<>).MakeGenericType(type);
+            var mi = genericType.GetMethod("GetParseFn", BindingFlags.Public | BindingFlags.Static);
+            parseFactoryFn = (ParseFactoryDelegate)Delegate.CreateDelegate(typeof(ParseFactoryDelegate), mi);
+
+            Dictionary<Type, ParseFactoryDelegate> snapshot, newCache;
+            do
+            {
+                snapshot = ParseFnCache;
+                newCache = new Dictionary<Type, ParseFactoryDelegate>(ParseFnCache);
+                newCache[type] = parseFactoryFn;
+
+            } while (!ReferenceEquals(
+                Interlocked.CompareExchange(ref ParseFnCache, newCache, snapshot), snapshot));
+            
+            return parseFactoryFn();
+		}
+	}
+
+	public static class JsonReader<T>
+	{
+		private static readonly ParseStringDelegate ReadFn;
+
+		static JsonReader()
+		{
+			ReadFn = JsonReader.Instance.GetParseFn<T>();
+		}
+		
+		public static ParseStringDelegate GetParseFn()
+		{
+			return ReadFn ?? Parse;
+		}
+
+		public static object Parse(string value)
+		{
+			if (ReadFn == null)
+			{
+                if (typeof(T).IsAbstract || typeof(T).IsInterface)
+				{
+					if (string.IsNullOrEmpty(value)) return null;
+					var concreteType = DeserializeType<JsonTypeSerializer>.ExtractType(value);
+					if (concreteType != null)
+					{
+						return JsonReader.GetParseFn(concreteType)(value);
+					}
+					throw new NotSupportedException("Can not deserialize interface type: "
+						+ typeof(T).Name);
+				}
+			}
+			return value == null 
+			       	? null 
+			       	: ReadFn(value);
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Json/JsonTypeSerializer.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Json/JsonTypeSerializer.cs
new file mode 100644
index 0000000..9fc85b4
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Json/JsonTypeSerializer.cs
@@ -0,0 +1,539 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.Globalization;
+using System.IO;
+using System.Text;
+using ServiceStack.Text.Common;
+
+namespace ServiceStack.Text.Json
+{
+	internal class JsonTypeSerializer
+		: ITypeSerializer
+	{
+		public static ITypeSerializer Instance = new JsonTypeSerializer();
+
+		public string TypeAttrInObject { get { return "{\"__type\":"; } }
+
+		public static readonly bool[] WhiteSpaceFlags = new bool[(int)' ' + 1];
+
+		static JsonTypeSerializer()
+		{
+			WhiteSpaceFlags[(int)' '] = true;
+			WhiteSpaceFlags[(int)'\t'] = true;
+			WhiteSpaceFlags[(int)'\r'] = true;
+			WhiteSpaceFlags[(int)'\n'] = true;
+		}
+
+		public WriteObjectDelegate GetWriteFn<T>()
+		{
+			return JsonWriter<T>.WriteFn();
+		}
+
+		public WriteObjectDelegate GetWriteFn(Type type)
+		{
+			return JsonWriter.GetWriteFn(type);
+		}
+
+		public TypeInfo GetTypeInfo(Type type)
+		{
+			return JsonWriter.GetTypeInfo(type);
+		}
+
+		/// <summary>
+		/// Shortcut escape when we're sure value doesn't contain any escaped chars
+		/// </summary>
+		/// <param name="writer"></param>
+		/// <param name="value"></param>
+		public void WriteRawString(TextWriter writer, string value)
+		{
+			writer.Write(JsWriter.QuoteChar);
+			writer.Write(value);
+			writer.Write(JsWriter.QuoteChar);
+		}
+
+		public void WritePropertyName(TextWriter writer, string value)
+		{
+			if (JsState.WritingKeyCount > 0)
+			{
+				writer.Write(JsWriter.EscapedQuoteString);
+				writer.Write(value);
+				writer.Write(JsWriter.EscapedQuoteString);
+			}
+			else
+			{
+				WriteRawString(writer, value);
+			}
+		}
+
+		public void WriteString(TextWriter writer, string value)
+		{
+			JsonUtils.WriteString(writer, value);
+		}
+
+		public void WriteBuiltIn(TextWriter writer, object value)
+		{
+			if (JsState.WritingKeyCount > 0 && !JsState.IsWritingValue) writer.Write(JsonUtils.QuoteChar);
+
+			WriteRawString(writer, value.ToString());
+
+			if (JsState.WritingKeyCount > 0 && !JsState.IsWritingValue) writer.Write(JsonUtils.QuoteChar);
+		}
+
+		public void WriteObjectString(TextWriter writer, object value)
+		{
+			JsonUtils.WriteString(writer, value != null ? value.ToString() : null);
+		}
+
+		public void WriteException(TextWriter writer, object value)
+		{
+			WriteString(writer, ((Exception)value).Message);
+		}
+
+		public void WriteDateTime(TextWriter writer, object oDateTime)
+		{
+			WriteRawString(writer, DateTimeSerializer.ToWcfJsonDate((DateTime)oDateTime));
+		}
+
+		public void WriteNullableDateTime(TextWriter writer, object dateTime)
+		{
+			if (dateTime == null)
+				writer.Write( JsonUtils.Null );
+			else
+				WriteDateTime(writer, dateTime);
+		}
+
+		public void WriteGuid(TextWriter writer, object oValue)
+		{
+			WriteRawString(writer, ((Guid)oValue).ToString("N"));
+		}
+
+		public void WriteNullableGuid(TextWriter writer, object oValue)
+		{
+			if (oValue == null) return;
+			WriteRawString(writer, ((Guid)oValue).ToString("N"));
+		}
+
+		public void WriteBytes(TextWriter writer, object oByteValue)
+		{
+			if (oByteValue == null) return;
+			WriteRawString(writer, Convert.ToBase64String((byte[])oByteValue));
+		}
+
+		public void WriteChar(TextWriter writer, object charValue)
+		{
+			if (charValue == null)
+				writer.Write(JsonUtils.Null);
+			else
+				WriteRawString(writer, ((char)charValue).ToString(CultureInfo.InvariantCulture));
+		}
+
+		public void WriteByte(TextWriter writer, object byteValue)
+		{
+			if (byteValue == null)
+				writer.Write(JsonUtils.Null);
+			else
+				writer.Write((byte)byteValue);
+		}
+
+		public void WriteInt16(TextWriter writer, object intValue)
+		{
+			if (intValue == null)
+				writer.Write(JsonUtils.Null);
+			else
+				writer.Write((short)intValue);
+		}
+
+		public void WriteUInt16(TextWriter writer, object intValue)
+		{
+			if (intValue == null)
+				writer.Write(JsonUtils.Null);
+			else
+				writer.Write((ushort)intValue);
+		}
+
+		public void WriteInt32(TextWriter writer, object intValue)
+		{
+			if (intValue == null)
+				writer.Write(JsonUtils.Null);
+			else
+				writer.Write((int)intValue);
+		}
+
+		public void WriteUInt32(TextWriter writer, object uintValue)
+		{
+			if (uintValue == null)
+				writer.Write(JsonUtils.Null);
+			else
+				writer.Write((uint)uintValue);
+		}
+
+		public void WriteInt64(TextWriter writer, object integerValue)
+		{
+			if (integerValue == null)
+				writer.Write(JsonUtils.Null);
+			else
+				writer.Write((long)integerValue);
+		}
+
+		public void WriteUInt64(TextWriter writer, object ulongValue)
+		{
+			if (ulongValue == null)
+			{
+				writer.Write(JsonUtils.Null);
+			}
+			else
+				writer.Write((ulong)ulongValue);
+		}
+
+		public void WriteBool(TextWriter writer, object boolValue)
+		{
+			if (boolValue == null)
+				writer.Write(JsonUtils.Null);
+			else
+				writer.Write(((bool)boolValue) ? JsonUtils.True : JsonUtils.False);
+		}
+
+		public void WriteFloat(TextWriter writer, object floatValue)
+		{
+			if (floatValue == null)
+				writer.Write(JsonUtils.Null);
+			else
+			{
+				var floatVal = (float)floatValue;
+				if (Equals(floatVal, float.MaxValue) || Equals(floatVal, float.MinValue))
+					writer.Write(floatVal.ToString("r", CultureInfo.InvariantCulture));
+				else
+					writer.Write(floatVal.ToString(CultureInfo.InvariantCulture));
+			}
+		}
+
+		public void WriteDouble(TextWriter writer, object doubleValue)
+		{
+			if (doubleValue == null)
+				writer.Write(JsonUtils.Null);
+			else
+			{
+				var doubleVal = (double)doubleValue;
+				if (Equals(doubleVal, double.MaxValue) || Equals(doubleVal, double.MinValue))
+					writer.Write(doubleVal.ToString("r", CultureInfo.InvariantCulture));
+				else
+					writer.Write(doubleVal.ToString(CultureInfo.InvariantCulture));
+			}
+		}
+
+		public void WriteDecimal(TextWriter writer, object decimalValue)
+		{
+			if (decimalValue == null)
+				writer.Write(JsonUtils.Null);
+			else
+				writer.Write(((decimal)decimalValue).ToString(CultureInfo.InvariantCulture));
+		}
+
+		public void WriteEnum(TextWriter writer, object enumValue)
+		{
+			if (enumValue == null) return;
+			WriteRawString(writer, enumValue.ToString());
+		}
+
+		public void WriteEnumFlags(TextWriter writer, object enumFlagValue)
+		{
+			if (enumFlagValue == null) return;
+			var intVal = (int)enumFlagValue;
+			writer.Write(intVal);
+		}
+
+		public void WriteLinqBinary(TextWriter writer, object linqBinaryValue)
+		{
+#if !MONOTOUCH && !SILVERLIGHT && !XBOX
+			WriteRawString(writer, Convert.ToBase64String(((System.Data.Linq.Binary)linqBinaryValue).ToArray()));
+#endif
+		}
+
+		public ParseStringDelegate GetParseFn<T>()
+		{
+			return JsonReader.Instance.GetParseFn<T>();
+		}
+
+		public ParseStringDelegate GetParseFn(Type type)
+		{
+			return JsonReader.GetParseFn(type);
+		}
+
+		public string ParseRawString(string value)
+		{
+			if (String.IsNullOrEmpty(value)) return value;
+
+			return value[0] == JsonUtils.QuoteChar
+				? value.Substring(1, value.Length - 2)
+				: value;
+		}
+
+		public string ParseString(string value)
+		{
+			return string.IsNullOrEmpty(value) ? value : ParseRawString(value);
+		}
+
+		static readonly char[] IsSafeJsonChars = new[] { JsonUtils.QuoteChar, JsonUtils.EscapeChar };
+
+		internal static string ParseJsonString(string json, ref int index)
+		{
+			var jsonLength = json.Length;
+
+			for (; index < json.Length; index++) { var ch = json[index]; if (ch >= WhiteSpaceFlags.Length || !WhiteSpaceFlags[ch]) break; } //Whitespace inline
+
+			if (json[index] == JsonUtils.QuoteChar)
+			{
+				index++;
+
+				//MicroOp: See if we can short-circuit evaluation (to avoid StringBuilder)
+				var strEndPos = json.IndexOfAny(IsSafeJsonChars, index);
+				if (strEndPos == -1) return json.Substring(index, jsonLength - index);
+				if (json[strEndPos] == JsonUtils.QuoteChar)
+				{
+					var potentialValue = json.Substring(index, strEndPos - index);
+					index = strEndPos + 1;
+					return potentialValue;
+				}
+			}
+
+			var sb = new StringBuilder(jsonLength);
+			char c;
+
+			while (true)
+			{
+				if (index == jsonLength) break;
+
+				c = json[index++];
+				if (c == JsonUtils.QuoteChar) break;
+
+				if (c == '\\')
+				{
+
+					if (index == jsonLength)
+					{
+						break;
+					}
+					c = json[index++];
+					switch (c)
+					{
+						case '"':
+							sb.Append('"');
+							break;
+						case '\\':
+							sb.Append('\\');
+							break;
+						case '/':
+							sb.Append('/');
+							break;
+						case 'b':
+							sb.Append('\b');
+							break;
+						case 'f':
+							sb.Append('\f');
+							break;
+						case 'n':
+							sb.Append('\n');
+							break;
+						case 'r':
+							sb.Append('\r');
+							break;
+						case 't':
+							sb.Append('\t');
+							break;
+						case 'u':
+							var remainingLength = jsonLength - index;
+							if (remainingLength >= 4)
+							{
+								var unicodeString = json.Substring(index, 4);
+								var unicodeIntVal = UInt32.Parse(unicodeString, NumberStyles.HexNumber);
+								sb.Append(ConvertFromUtf32((int)unicodeIntVal));
+								index += 4;
+							}
+							else
+							{
+								break;
+							}
+							break;
+					}
+				}
+				else
+				{
+					sb.Append(c);
+				}
+			}
+
+			var strValue = sb.ToString();
+			return strValue == JsonUtils.Null ? null : strValue;
+		}
+
+		/// <summary>
+		/// Since Silverlight doesn't have char.ConvertFromUtf32() so putting Mono's implemenation inline.
+		/// </summary>
+		/// <param name="utf32"></param>
+		/// <returns></returns>
+		private static string ConvertFromUtf32(int utf32)
+		{
+			if (utf32 < 0 || utf32 > 0x10FFFF)
+				throw new ArgumentOutOfRangeException("utf32", "The argument must be from 0 to 0x10FFFF.");
+			if (0xD800 <= utf32 && utf32 <= 0xDFFF)
+				throw new ArgumentOutOfRangeException("utf32", "The argument must not be in surrogate pair range.");
+			if (utf32 < 0x10000)
+				return new string((char)utf32, 1);
+			utf32 -= 0x10000;
+			return new string(new[] {(char) ((utf32 >> 10) + 0xD800),
+                                (char) (utf32 % 0x0400 + 0xDC00)});
+		}
+
+		private static void EatWhitespace(string json, ref int index)
+		{
+			int c;
+			for (; index < json.Length; index++)
+			{
+				c = json[index];
+				if (c >= WhiteSpaceFlags.Length || !WhiteSpaceFlags[c])
+				{
+					break;
+				}
+			}
+		}
+
+		public string EatTypeValue(string value, ref int i)
+		{
+			return EatValue(value, ref i);
+		}
+
+		public bool EatMapStartChar(string value, ref int i)
+		{
+			for (; i < value.Length; i++) { var c = value[i]; if (c >= WhiteSpaceFlags.Length || !WhiteSpaceFlags[c]) break; } //Whitespace inline
+			return value[i++] == JsWriter.MapStartChar;
+		}
+
+		public string EatMapKey(string value, ref int i)
+		{
+			return ParseJsonString(value, ref i);
+		}
+
+		public bool EatMapKeySeperator(string value, ref int i)
+		{
+			for (; i < value.Length; i++) { var c = value[i]; if (c >= WhiteSpaceFlags.Length || !WhiteSpaceFlags[c]) break; } //Whitespace inline
+			if (value.Length == i) return false;
+			return value[i++] == JsWriter.MapKeySeperator;
+		}
+
+		public bool EatItemSeperatorOrMapEndChar(string value, ref int i)
+		{
+			for (; i < value.Length; i++) { var c = value[i]; if (c >= WhiteSpaceFlags.Length || !WhiteSpaceFlags[c]) break; } //Whitespace inline
+
+			if (i == value.Length) return false;
+
+			var success = value[i] == JsWriter.ItemSeperator
+				|| value[i] == JsWriter.MapEndChar;
+
+			i++;
+
+			if (success)
+			{
+				for (; i < value.Length; i++) { var c = value[i]; if (c >= WhiteSpaceFlags.Length || !WhiteSpaceFlags[c]) break; } //Whitespace inline
+			}
+
+			return success;
+		}
+
+		public string EatValue(string value, ref int i)
+		{
+			var valueLength = value.Length;
+			if (i == valueLength) return null;
+
+			for (; i < value.Length; i++) { var c = value[i]; if (c >= WhiteSpaceFlags.Length || !WhiteSpaceFlags[c]) break; } //Whitespace inline
+
+			var tokenStartPos = i;
+			var valueChar = value[i];
+			var withinQuotes = false;
+			var endsToEat = 1;
+
+			switch (valueChar)
+			{
+				//If we are at the end, return.
+				case JsWriter.ItemSeperator:
+				case JsWriter.MapEndChar:
+					return null;
+
+				//Is Within Quotes, i.e. "..."
+				case JsWriter.QuoteChar:
+					return ParseJsonString(value, ref i);
+
+				//Is Type/Map, i.e. {...}
+				case JsWriter.MapStartChar:
+					while (++i < valueLength && endsToEat > 0)
+					{
+						valueChar = value[i];
+
+						if (valueChar == JsWriter.QuoteChar
+							&& value[i - 1] != JsonUtils.EscapeChar)
+							withinQuotes = !withinQuotes;
+
+						if (withinQuotes)
+							continue;
+
+						if (valueChar == JsWriter.MapStartChar)
+							endsToEat++;
+
+						if (valueChar == JsWriter.MapEndChar)
+							endsToEat--;
+					}
+					return value.Substring(tokenStartPos, i - tokenStartPos);
+
+				//Is List, i.e. [...]
+				case JsWriter.ListStartChar:
+					while (++i < valueLength && endsToEat > 0)
+					{
+						valueChar = value[i];
+
+						if (valueChar == JsWriter.QuoteChar
+							&& value[i - 1] != JsonUtils.EscapeChar)
+							withinQuotes = !withinQuotes;
+
+						if (withinQuotes)
+							continue;
+
+						if (valueChar == JsWriter.ListStartChar)
+							endsToEat++;
+
+						if (valueChar == JsWriter.ListEndChar)
+							endsToEat--;
+					}
+					return value.Substring(tokenStartPos, i - tokenStartPos);
+			}
+
+			//Is Value
+			while (++i < valueLength)
+			{
+				valueChar = value[i];
+
+				if (valueChar == JsWriter.ItemSeperator
+					|| valueChar == JsWriter.MapEndChar
+					//If it doesn't have quotes it's either a keyword or number so also has a ws boundary
+					|| (valueChar < WhiteSpaceFlags.Length && WhiteSpaceFlags[valueChar])
+				)
+				{
+					break;
+				}
+			}
+
+			var strValue = value.Substring(tokenStartPos, i - tokenStartPos);
+			return strValue == JsonUtils.Null ? null : strValue;
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Json/JsonUtils.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Json/JsonUtils.cs
new file mode 100644
index 0000000..d7111c4
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Json/JsonUtils.cs
@@ -0,0 +1,141 @@
+using System;
+using System.IO;
+
+namespace ServiceStack.Text.Json
+{
+	public static class JsonUtils
+	{
+		public const char EscapeChar = '\\';
+		public const char QuoteChar = '"';
+		public const string Null = "null";
+		public const string True = "true";
+		public const string False = "false";
+
+		static readonly char[] EscapeChars = new[]
+			{
+				QuoteChar, '\n', '\r', '\t', '"', '\\', '\f', '\b',
+			};
+
+		private const int LengthFromLargestChar = '\\' + 1;
+		private static readonly bool[] EscapeCharFlags = new bool[LengthFromLargestChar];
+
+		static JsonUtils()
+		{
+			foreach (var escapeChar in EscapeChars)
+			{
+				EscapeCharFlags[escapeChar] = true;
+			}
+		}
+
+		public static void WriteString(TextWriter writer, string value)
+		{
+			if (value == null)
+			{
+				writer.Write(JsonUtils.Null);
+				return;
+			}
+			if (!HasAnyEscapeChars(value))
+			{
+				writer.Write(QuoteChar);
+				writer.Write(value);
+				writer.Write(QuoteChar);
+				return;
+			}
+
+			var hexSeqBuffer = new char[4];
+			writer.Write(QuoteChar);
+
+			var len = value.Length;
+			for (var i = 0; i < len; i++)
+			{
+				switch (value[i])
+				{
+					case '\n':
+						writer.Write("\\n");
+						continue;
+
+					case '\r':
+						writer.Write("\\r");
+						continue;
+
+					case '\t':
+						writer.Write("\\t");
+						continue;
+
+					case '"':
+					case '\\':
+						writer.Write('\\');
+						writer.Write(value[i]);
+						continue;
+
+					case '\f':
+						writer.Write("\\f");
+						continue;
+
+					case '\b':
+						writer.Write("\\b");
+						continue;
+				}
+
+				//Is printable char?
+				if (value[i] >= 32 && value[i] <= 126)
+				{
+					writer.Write(value[i]);
+					continue;
+				}
+
+				var isValidSequence = value[i] < 0xD800 || value[i] > 0xDFFF;
+				if (isValidSequence)
+				{
+					// Default, turn into a \uXXXX sequence
+					IntToHex(value[i], hexSeqBuffer);
+					writer.Write("\\u");
+					writer.Write(hexSeqBuffer);
+				}
+			}
+
+			writer.Write(QuoteChar);
+		}
+
+		/// <summary>
+		/// micro optimizations: using flags instead of value.IndexOfAny(EscapeChars)
+		/// </summary>
+		/// <param name="value"></param>
+		/// <returns></returns>
+		private static bool HasAnyEscapeChars(string value)
+		{
+			var len = value.Length;
+			for (var i = 0; i < len; i++)
+			{
+				var c = value[i];
+				if (c >= LengthFromLargestChar || !EscapeCharFlags[c]) continue;
+				return true;
+			}
+			return false;
+		}
+
+		public static void IntToHex(int intValue, char[] hex)
+		{
+			for (var i = 0; i < 4; i++)
+			{
+				var num = intValue % 16;
+
+				if (num < 10)
+					hex[3 - i] = (char)('0' + num);
+				else
+					hex[3 - i] = (char)('A' + (num - 10));
+
+				intValue >>= 4;
+			}
+		}
+
+		public static bool IsJsObject(string value)
+		{
+			return !string.IsNullOrEmpty(value)
+				&& value[0] == '{'
+				&& value[value.Length - 1] == '}';
+		}
+
+	}
+
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Json/JsonWriter.Generic.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Json/JsonWriter.Generic.cs
new file mode 100644
index 0000000..8297c0d
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Json/JsonWriter.Generic.cs
@@ -0,0 +1,157 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using System.Threading;
+using ServiceStack.Text.Common;
+
+namespace ServiceStack.Text.Json
+{
+	internal static class JsonWriter
+	{
+		public static readonly JsWriter<JsonTypeSerializer> Instance = new JsWriter<JsonTypeSerializer>();
+
+		private static Dictionary<Type, WriteObjectDelegate> WriteFnCache = new Dictionary<Type, WriteObjectDelegate>();
+
+		public static WriteObjectDelegate GetWriteFn(Type type)
+		{
+			try
+			{
+				WriteObjectDelegate writeFn;
+				if (WriteFnCache.TryGetValue(type, out writeFn)) return writeFn;
+
+				var genericType = typeof(JsonWriter<>).MakeGenericType(type);
+				var mi = genericType.GetMethod("WriteFn", BindingFlags.Public | BindingFlags.Static);
+				var writeFactoryFn = (Func<WriteObjectDelegate>)Delegate.CreateDelegate(typeof(Func<WriteObjectDelegate>), mi);
+				writeFn = writeFactoryFn();
+
+				Dictionary<Type, WriteObjectDelegate> snapshot, newCache;
+				do
+				{
+					snapshot = WriteFnCache;
+					newCache = new Dictionary<Type, WriteObjectDelegate>(WriteFnCache);
+					newCache[type] = writeFn;
+
+				} while (!ReferenceEquals(
+					Interlocked.CompareExchange(ref WriteFnCache, newCache, snapshot), snapshot));
+
+				return writeFn;
+			}
+			catch (Exception ex)
+			{
+				Tracer.Instance.WriteError(ex);
+				throw;
+			}
+		}
+
+		private static Dictionary<Type, TypeInfo> JsonTypeInfoCache = new Dictionary<Type, TypeInfo>();
+
+		public static TypeInfo GetTypeInfo(Type type)
+		{
+			try
+			{
+				TypeInfo writeFn;
+				if (JsonTypeInfoCache.TryGetValue(type, out writeFn)) return writeFn;
+
+				var genericType = typeof(JsonWriter<>).MakeGenericType(type);
+				var mi = genericType.GetMethod("GetTypeInfo", BindingFlags.Public | BindingFlags.Static);
+				var writeFactoryFn = (Func<TypeInfo>)Delegate.CreateDelegate(typeof(Func<TypeInfo>), mi);
+				writeFn = writeFactoryFn();
+
+				Dictionary<Type, TypeInfo> snapshot, newCache;
+				do
+				{
+					snapshot = JsonTypeInfoCache;
+					newCache = new Dictionary<Type, TypeInfo>(JsonTypeInfoCache);
+					newCache[type] = writeFn;
+
+				} while (!ReferenceEquals(
+					Interlocked.CompareExchange(ref JsonTypeInfoCache, newCache, snapshot), snapshot));
+
+				return writeFn;
+			}
+			catch (Exception ex)
+			{
+				Tracer.Instance.WriteError(ex);
+				throw;
+			}
+		}
+
+		public static void WriteLateBoundObject(TextWriter writer, object value)
+		{
+			if (value == null)
+			{
+				if (JsConfig.IncludeNullValues)
+				{
+					writer.Write(JsonUtils.Null);
+				}
+				return;
+			}
+			var writeFn = GetWriteFn(value.GetType());
+
+			var prevState = JsState.IsWritingDynamic;
+			JsState.IsWritingDynamic = true;
+			writeFn(writer, value);
+			JsState.IsWritingDynamic = prevState;
+		}
+
+		public static WriteObjectDelegate GetValueTypeToStringMethod(Type type)
+		{
+			return Instance.GetValueTypeToStringMethod(type);
+		}
+	}
+
+	internal class TypeInfo
+	{
+		internal bool EncodeMapKey;
+	}
+
+	/// <summary>
+	/// Implement the serializer using a more static approach
+	/// </summary>
+	/// <typeparam name="T"></typeparam>
+	internal static class JsonWriter<T>
+	{
+		internal static TypeInfo TypeInfo;
+		private static readonly WriteObjectDelegate CacheFn;
+
+		public static WriteObjectDelegate WriteFn()
+		{
+			return CacheFn ?? WriteObject;
+		}
+
+		public static TypeInfo GetTypeInfo()
+		{
+			return TypeInfo;
+		}
+
+		static JsonWriter()
+		{
+			TypeInfo = new TypeInfo {
+				EncodeMapKey = typeof(T) == typeof(bool) || typeof(T).IsNumericType()
+			};
+
+            CacheFn = typeof(T) == typeof(object) 
+                ? JsonWriter.WriteLateBoundObject 
+                : JsonWriter.Instance.GetWriteFn<T>();
+		}
+
+	    public static void WriteObject(TextWriter writer, object value)
+		{
+			CacheFn(writer, value);
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/JsonObject.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/JsonObject.cs
new file mode 100644
index 0000000..49b367b
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/JsonObject.cs
@@ -0,0 +1,89 @@
+using System;
+using System.Collections.Generic;
+
+namespace ServiceStack.Text
+{
+	public static class JsonExtensions
+	{
+		public static T JsonTo<T>(this Dictionary<string, string> map, string key)
+		{
+			return Get<T>(map, key);
+		}
+
+		public static T Get<T>(this Dictionary<string, string> map, string key)
+		{
+			string strVal;
+			return map.TryGetValue(key, out strVal) ? JsonSerializer.DeserializeFromString<T>(strVal) : default(T);
+		}
+
+		public static string Get(this Dictionary<string, string> map, string key)
+		{
+			string strVal;
+			return map.TryGetValue(key, out strVal) ? strVal : null;
+		}
+
+		public static JsonArrayObjects ArrayObjects(this string json, string propertyName)
+		{
+			return Text.JsonArrayObjects.Parse(json);
+		}
+
+		public static List<T> ConvertAll<T>(this JsonArrayObjects jsonArrayObjects, Func<JsonObject, T> converter)
+		{
+			var results = new List<T>();
+
+			foreach (var jsonObject in jsonArrayObjects)
+			{
+				results.Add(converter(jsonObject));
+			}
+
+			return results;
+		}
+
+		public static T ConvertTo<T>(this JsonObject jsonObject, Func<JsonObject, T> converFn)
+		{
+			return jsonObject == null 
+				? default(T) 
+				: converFn(jsonObject);
+		}
+
+		public static Dictionary<string, string> ToDictionary(this JsonObject jsonObject)
+		{
+			return jsonObject == null 
+				? new Dictionary<string, string>() 
+				: new Dictionary<string, string>(jsonObject);
+		}
+	}
+
+	public class JsonObject : Dictionary<string, string>
+	{
+		public static JsonObject Parse(string json)
+		{
+			return JsonSerializer.DeserializeFromString<JsonObject>(json);
+		}
+
+		public JsonArrayObjects ArrayObjects(string propertyName)
+		{
+			string strValue;
+			return this.TryGetValue(propertyName, out strValue)
+				? JsonArrayObjects.Parse(strValue)
+				: null;
+		}
+
+		public JsonObject Object(string propertyName)
+		{
+			string strValue;
+			return this.TryGetValue(propertyName, out strValue)
+				? Parse(strValue)
+				: null;
+		}
+	}
+
+	public class JsonArrayObjects : List<JsonObject>
+	{
+		public static JsonArrayObjects Parse(string json)
+		{
+			return JsonSerializer.DeserializeFromString<JsonArrayObjects>(json);
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/JsonSerializer.Generic.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/JsonSerializer.Generic.cs
new file mode 100644
index 0000000..4984e94
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/JsonSerializer.Generic.cs
@@ -0,0 +1,83 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.IO;
+using System.Text;
+using ServiceStack.Text.Common;
+using ServiceStack.Text.Json;
+
+namespace ServiceStack.Text
+{
+	public class JsonSerializer<T> : ITypeSerializer<T>
+	{
+		public bool CanCreateFromString(Type type)
+		{
+			return JsonReader.GetParseFn(type) != null;
+		}
+
+		/// <summary>
+		/// Parses the specified value.
+		/// </summary>
+		/// <param name="value">The value.</param>
+		/// <returns></returns>
+		public T DeserializeFromString(string value)
+		{
+			if (string.IsNullOrEmpty(value)) return default(T);
+			return (T)JsonReader<T>.Parse(value);
+		}
+
+		public T DeserializeFromReader(TextReader reader)
+		{
+			return DeserializeFromString(reader.ReadToEnd());
+		}
+
+		public string SerializeToString(T value)
+		{
+			if (value == null) return null;
+			if (typeof(T) == typeof(string)) return value as string;
+            if (typeof(T) == typeof(object) || typeof(T).IsAbstract || typeof(T).IsInterface)
+            {
+                if (typeof(T).IsAbstract || typeof(T).IsInterface) JsState.IsWritingDynamic = true;
+                var result = JsonSerializer.SerializeToString(value, value.GetType());
+                if (typeof(T).IsAbstract || typeof(T).IsInterface) JsState.IsWritingDynamic = false;
+                return result;
+            }
+
+			var sb = new StringBuilder();
+			using (var writer = new StringWriter(sb))
+			{
+				JsonWriter<T>.WriteObject(writer, value);
+			}
+			return sb.ToString();
+		}
+
+		public void SerializeToWriter(T value, TextWriter writer)
+		{
+			if (value == null) return;
+			if (typeof(T) == typeof(string))
+			{
+				writer.Write(value);
+				return;
+			}
+            if (typeof(T) == typeof(object) || typeof(T).IsAbstract || typeof(T).IsInterface)
+            {
+                if (typeof(T).IsAbstract || typeof(T).IsInterface) JsState.IsWritingDynamic = true;
+                JsonSerializer.SerializeToWriter(value, value.GetType(), writer);
+                if (typeof(T).IsAbstract || typeof(T).IsInterface) JsState.IsWritingDynamic = false;
+                return;
+            }
+           
+            JsonWriter<T>.WriteObject(writer, value);
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/JsonSerializer.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/JsonSerializer.cs
new file mode 100644
index 0000000..77ab027
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/JsonSerializer.cs
@@ -0,0 +1,168 @@
+
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.Globalization;
+using System.IO;
+using System.Text;
+using ServiceStack.Text.Common;
+using ServiceStack.Text.Json;
+
+namespace ServiceStack.Text
+{
+	/// <summary>
+	/// Creates an instance of a Type from a string value
+	/// </summary>
+	public static class JsonSerializer
+	{
+		private static readonly UTF8Encoding UTF8EncodingWithoutBom = new UTF8Encoding(false);
+
+		public static T DeserializeFromString<T>(string value)
+		{
+			if (string.IsNullOrEmpty(value)) return default(T);
+			return (T)JsonReader<T>.Parse(value);
+		}
+
+		public static T DeserializeFromReader<T>(TextReader reader)
+		{
+			return DeserializeFromString<T>(reader.ReadToEnd());
+		}
+
+		public static object DeserializeFromString(string value, Type type)
+		{
+			return value == null
+					? null
+					: JsonReader.GetParseFn(type)(value);
+		}
+
+		public static object DeserializeFromReader(TextReader reader, Type type)
+		{
+			return DeserializeFromString(reader.ReadToEnd(), type);
+		}
+
+		public static string SerializeToString<T>(T value)
+		{
+			if (value == null) return null;
+            if (typeof(T) == typeof(object) || typeof(T).IsAbstract || typeof(T).IsInterface)
+            {
+                if (typeof(T).IsAbstract || typeof(T).IsInterface) JsState.IsWritingDynamic = true;
+                var result = SerializeToString(value, value.GetType());
+                if (typeof(T).IsAbstract || typeof(T).IsInterface) JsState.IsWritingDynamic = false;
+                return result;
+            }
+
+			var sb = new StringBuilder();
+			using (var writer = new StringWriter(sb, CultureInfo.InvariantCulture))
+			{
+				if (typeof(T) == typeof(string))
+				{
+					JsonUtils.WriteString(writer, value as string);
+				}
+				else
+				{
+					JsonWriter<T>.WriteObject(writer, value);
+				}
+			}
+			return sb.ToString();
+		}
+
+		public static string SerializeToString(object value, Type type)
+		{
+			if (value == null) return null;
+
+			var sb = new StringBuilder();
+			using (var writer = new StringWriter(sb, CultureInfo.InvariantCulture))
+			{
+				if (type == typeof(string))
+				{
+					JsonUtils.WriteString(writer, value as string);
+				}
+				else
+				{
+					JsonWriter.GetWriteFn(type)(writer, value);
+				}
+			}
+			return sb.ToString();
+		}
+
+		public static void SerializeToWriter<T>(T value, TextWriter writer)
+		{
+			if (value == null) return;
+			if (typeof(T) == typeof(string))
+			{
+				writer.Write(value);
+				return;
+			}
+            if (typeof(T) == typeof(object) || typeof(T).IsAbstract || typeof(T).IsInterface)
+			{
+                if (typeof(T).IsAbstract || typeof(T).IsInterface) JsState.IsWritingDynamic = true;
+                SerializeToWriter(value, value.GetType(), writer);
+                if (typeof(T).IsAbstract || typeof(T).IsInterface) JsState.IsWritingDynamic = false;
+                return;
+			}
+
+			JsonWriter<T>.WriteObject(writer, value);
+		}
+
+		public static void SerializeToWriter(object value, Type type, TextWriter writer)
+		{
+			if (value == null) return;
+			if (type == typeof(string))
+			{
+				writer.Write(value);
+				return;
+			}
+
+			JsonWriter.GetWriteFn(type)(writer, value);
+		}
+
+		public static void SerializeToStream<T>(T value, Stream stream)
+		{
+			if (value == null) return;
+			if (typeof(T) == typeof(object) || typeof(T).IsAbstract || typeof(T).IsInterface)
+			{
+                if (typeof(T).IsAbstract || typeof(T).IsInterface) JsState.IsWritingDynamic = true;
+                SerializeToStream(value, value.GetType(), stream);
+                if (typeof(T).IsAbstract || typeof(T).IsInterface) JsState.IsWritingDynamic = false;
+				return;
+			}
+
+			var writer = new StreamWriter(stream, UTF8EncodingWithoutBom);
+			JsonWriter<T>.WriteObject(writer, value);
+			writer.Flush();
+		}
+
+		public static void SerializeToStream(object value, Type type, Stream stream)
+		{
+			var writer = new StreamWriter(stream, UTF8EncodingWithoutBom);
+			JsonWriter.GetWriteFn(type)(writer, value);
+			writer.Flush();
+		}
+
+		public static T DeserializeFromStream<T>(Stream stream)
+		{
+			using (var reader = new StreamReader(stream, UTF8EncodingWithoutBom))
+			{
+				return DeserializeFromString<T>(reader.ReadToEnd());
+			}
+		}
+
+		public static object DeserializeFromStream(Type type, Stream stream)
+		{
+			using (var reader = new StreamReader(stream, UTF8EncodingWithoutBom))
+			{
+				return DeserializeFromString(reader.ReadToEnd(), type);
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Jsv/JsvDeserializeType.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Jsv/JsvDeserializeType.cs
new file mode 100644
index 0000000..a7b0268
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Jsv/JsvDeserializeType.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Reflection;
+using ServiceStack.Text.Common;
+
+namespace ServiceStack.Text.Jsv
+{
+	public static class JsvDeserializeType
+	{
+		public static SetPropertyDelegate GetSetPropertyMethod(Type type, PropertyInfo propertyInfo)
+		{
+			return TypeAccessor.GetSetPropertyMethod(type, propertyInfo);
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Jsv/JsvReader.Generic.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Jsv/JsvReader.Generic.cs
new file mode 100644
index 0000000..2150b57
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Jsv/JsvReader.Generic.cs
@@ -0,0 +1,81 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Threading;
+using ServiceStack.Text.Common;
+
+namespace ServiceStack.Text.Jsv
+{
+	public static class JsvReader
+	{ 
+		internal static readonly JsReader<JsvTypeSerializer> Instance = new JsReader<JsvTypeSerializer>();
+
+        private static Dictionary<Type, ParseFactoryDelegate> ParseFnCache = new Dictionary<Type, ParseFactoryDelegate>();
+
+		public static ParseStringDelegate GetParseFn(Type type)
+		{
+			ParseFactoryDelegate parseFactoryFn;
+            ParseFnCache.TryGetValue(type, out parseFactoryFn);
+
+            if (parseFactoryFn != null) return parseFactoryFn();
+
+            var genericType = typeof(JsvReader<>).MakeGenericType(type);
+            var mi = genericType.GetMethod("GetParseFn", BindingFlags.Public | BindingFlags.Static);
+            parseFactoryFn = (ParseFactoryDelegate)Delegate.CreateDelegate(typeof(ParseFactoryDelegate), mi);
+
+            Dictionary<Type, ParseFactoryDelegate> snapshot, newCache;
+            do
+            {
+                snapshot = ParseFnCache;
+                newCache = new Dictionary<Type, ParseFactoryDelegate>(ParseFnCache);
+                newCache[type] = parseFactoryFn;
+
+            } while (!ReferenceEquals(
+                Interlocked.CompareExchange(ref ParseFnCache, newCache, snapshot), snapshot));
+            
+            return parseFactoryFn();
+		}
+	}
+
+	public static class JsvReader<T>
+	{
+		private static readonly ParseStringDelegate ReadFn;
+
+		static JsvReader()
+		{
+			ReadFn = JsvReader.Instance.GetParseFn<T>();
+		}
+		
+		public static ParseStringDelegate GetParseFn()
+		{
+			return ReadFn ?? Parse;
+		}
+
+		public static object Parse(string value)
+		{
+			if (ReadFn == null)
+			{
+				if (typeof(T).IsInterface)
+				{
+					throw new NotSupportedException("Can not deserialize interface type: "
+						+ typeof(T).Name);
+				}
+			}
+			return value == null 
+			       	? null 
+			       	: ReadFn(value);
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Jsv/JsvSerializer.Generic.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Jsv/JsvSerializer.Generic.cs
new file mode 100644
index 0000000..a6d68f8
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Jsv/JsvSerializer.Generic.cs
@@ -0,0 +1,73 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Threading;
+using ServiceStack.Text.Common;
+
+namespace ServiceStack.Text.Jsv
+{
+	public class JsvSerializer<T>
+	{
+		Dictionary<Type, ParseStringDelegate> DeserializerCache = new Dictionary<Type, ParseStringDelegate>();
+
+		public T DeserializeFromString(string value, Type type)
+		{
+			ParseStringDelegate parseFn;
+            if (DeserializerCache.TryGetValue(type, out parseFn)) return (T)parseFn(value);
+
+            var genericType = typeof(T).MakeGenericType(type);
+            var mi = genericType.GetMethod("DeserializeFromString", new[] { typeof(string) });
+            parseFn = (ParseStringDelegate)Delegate.CreateDelegate(typeof(ParseStringDelegate), mi);
+
+            Dictionary<Type, ParseStringDelegate> snapshot, newCache;
+            do
+            {
+                snapshot = DeserializerCache;
+                newCache = new Dictionary<Type, ParseStringDelegate>(DeserializerCache);
+                newCache[type] = parseFn;
+
+            } while (!ReferenceEquals(
+                Interlocked.CompareExchange(ref DeserializerCache, newCache, snapshot), snapshot));
+            
+            return (T)parseFn(value);
+		}
+
+		public T DeserializeFromString(string value)
+		{
+			if (typeof(T) == typeof(string)) return (T)(object)value;
+
+			return (T)JsvReader<T>.Parse(value);
+		}
+
+		public void SerializeToWriter(T value, TextWriter writer)
+		{
+			JsvWriter<T>.WriteObject(writer, value);
+		}
+
+		public string SerializeToString(T value)
+		{
+			if (value == null) return null;
+			if (value is string) return value as string;
+
+			var sb = new StringBuilder();
+			using (var writer = new StringWriter(sb))
+			{
+				JsvWriter<T>.WriteObject(writer, value);
+			}
+			return sb.ToString();
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Jsv/JsvTypeSerializer.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Jsv/JsvTypeSerializer.cs
new file mode 100644
index 0000000..0fbe22a
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Jsv/JsvTypeSerializer.cs
@@ -0,0 +1,399 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.Globalization;
+using System.IO;
+using ServiceStack.Text.Common;
+using ServiceStack.Text.Json;
+
+namespace ServiceStack.Text.Jsv
+{
+	internal class JsvTypeSerializer
+		: ITypeSerializer
+	{
+		public static ITypeSerializer Instance = new JsvTypeSerializer();
+
+		public string TypeAttrInObject { get { return "{__type:"; } }
+
+		public WriteObjectDelegate GetWriteFn<T>()
+		{
+			return JsvWriter<T>.WriteFn();
+		}
+
+		public WriteObjectDelegate GetWriteFn(Type type)
+		{
+			return JsvWriter.GetWriteFn(type);
+		}
+
+		static readonly TypeInfo DefaultTypeInfo = new TypeInfo { EncodeMapKey = false };
+
+		public TypeInfo GetTypeInfo(Type type)
+		{
+			return DefaultTypeInfo;
+		}
+
+		public void WriteRawString(TextWriter writer, string value)
+		{
+			writer.Write(value.ToCsvField());
+		}
+
+		public void WritePropertyName(TextWriter writer, string value)
+		{
+			writer.Write(value);
+		}
+
+		public void WriteBuiltIn(TextWriter writer, object value)
+		{
+			writer.Write(value);
+		}
+
+		public void WriteObjectString(TextWriter writer, object value)
+		{
+			if (value != null)
+			{
+				writer.Write(value.ToString().ToCsvField());
+			}
+		}
+
+		public void WriteException(TextWriter writer, object value)
+		{
+			writer.Write(((Exception)value).Message.ToCsvField());
+		}
+
+		public void WriteString(TextWriter writer, string value)
+		{
+			writer.Write(value.ToCsvField());
+		}
+
+		public void WriteDateTime(TextWriter writer, object oDateTime)
+		{
+			writer.Write(DateTimeSerializer.ToShortestXsdDateTimeString((DateTime)oDateTime));
+		}
+
+		public void WriteNullableDateTime(TextWriter writer, object dateTime)
+		{
+			if (dateTime == null) return;
+			writer.Write(DateTimeSerializer.ToShortestXsdDateTimeString((DateTime)dateTime));
+		}
+
+		public void WriteGuid(TextWriter writer, object oValue)
+		{
+			writer.Write(((Guid)oValue).ToString("N"));
+		}
+
+		public void WriteNullableGuid(TextWriter writer, object oValue)
+		{
+			if (oValue == null) return;
+			writer.Write(((Guid)oValue).ToString("N"));
+		}
+
+		public void WriteBytes(TextWriter writer, object oByteValue)
+		{
+			if (oByteValue == null) return;
+			writer.Write(Convert.ToBase64String((byte[])oByteValue));
+		}
+
+		public void WriteChar(TextWriter writer, object charValue)
+		{
+			if (charValue == null) return;
+			writer.Write((char)charValue);
+		}
+
+		public void WriteByte(TextWriter writer, object byteValue)
+		{
+			if (byteValue == null) return;
+			writer.Write((byte)byteValue);
+		}
+
+		public void WriteInt16(TextWriter writer, object intValue)
+		{
+			if (intValue == null) return;
+			writer.Write((short)intValue);
+		}
+
+		public void WriteUInt16(TextWriter writer, object intValue)
+		{
+			if (intValue == null) return;
+			writer.Write((ushort)intValue);
+		}
+
+		public void WriteInt32(TextWriter writer, object intValue)
+		{
+			if (intValue == null) return;
+			writer.Write((int)intValue);
+		}
+
+		public void WriteUInt32(TextWriter writer, object uintValue)
+		{
+			if (uintValue == null) return;
+			writer.Write((uint)uintValue);
+		}
+
+		public void WriteUInt64(TextWriter writer, object ulongValue)
+		{
+			if (ulongValue == null) return;
+			writer.Write((ulong)ulongValue);
+		}
+
+		public void WriteInt64(TextWriter writer, object longValue)
+		{
+			if (longValue == null) return;
+			writer.Write((long)longValue);
+		}
+
+		public void WriteBool(TextWriter writer, object boolValue)
+		{
+			if (boolValue == null) return;
+			writer.Write((bool)boolValue);
+		}
+
+		public void WriteFloat(TextWriter writer, object floatValue)
+		{
+			if (floatValue == null) return;
+			var floatVal = (float)floatValue;
+			if (Equals(floatVal, float.MaxValue) || Equals(floatVal, float.MinValue))
+				writer.Write(floatVal.ToString("r", CultureInfo.InvariantCulture));
+			else
+				writer.Write(floatVal.ToString(CultureInfo.InvariantCulture));
+		}
+
+		public void WriteDouble(TextWriter writer, object doubleValue)
+		{
+			if (doubleValue == null) return;
+			var doubleVal = (double)doubleValue;
+			if (Equals(doubleVal, double.MaxValue) || Equals(doubleVal, double.MinValue))
+				writer.Write(doubleVal.ToString("r", CultureInfo.InvariantCulture));
+			else
+				writer.Write(doubleVal.ToString(CultureInfo.InvariantCulture));
+		}
+
+		public void WriteDecimal(TextWriter writer, object decimalValue)
+		{
+			if (decimalValue == null) return;
+			writer.Write(((decimal)decimalValue).ToString(CultureInfo.InvariantCulture));
+		}
+
+		public void WriteEnum(TextWriter writer, object enumValue)
+		{
+			if (enumValue == null) return;
+			writer.Write(enumValue.ToString());
+		}
+
+		public void WriteEnumFlags(TextWriter writer, object enumFlagValue)
+		{
+			if (enumFlagValue == null) return;
+			var intVal = (int)enumFlagValue;
+			writer.Write(intVal);
+		}
+
+		public void WriteLinqBinary(TextWriter writer, object linqBinaryValue)
+		{
+#if !MONOTOUCH && !SILVERLIGHT && !XBOX
+			WriteRawString(writer, Convert.ToBase64String(((System.Data.Linq.Binary)linqBinaryValue).ToArray()));
+#endif
+		}
+
+		public object EncodeMapKey(object value)
+		{
+			return value;
+		}
+
+		public ParseStringDelegate GetParseFn<T>()
+		{
+			return JsvReader.Instance.GetParseFn<T>();
+		}
+
+		public ParseStringDelegate GetParseFn(Type type)
+		{
+			return JsvReader.GetParseFn(type);
+		}
+
+		public string ParseRawString(string value)
+		{
+			return value;
+		}
+
+		public string ParseString(string value)
+		{
+			return value.FromCsvField();
+		}
+
+		public string EatTypeValue(string value, ref int i)
+		{
+			return EatValue(value, ref i);
+		}
+
+		public bool EatMapStartChar(string value, ref int i)
+		{
+			var success = value[i] == JsWriter.MapStartChar;
+			if (success) i++;
+			return success;
+		}
+
+		public string EatMapKey(string value, ref int i)
+		{
+			var tokenStartPos = i;
+
+			var valueLength = value.Length;
+
+			var valueChar = value[tokenStartPos];
+
+			switch (valueChar)
+			{
+				case JsWriter.QuoteChar:
+					while (++i < valueLength)
+					{
+						valueChar = value[i];
+
+						if (valueChar != JsWriter.QuoteChar) continue;
+
+						var isLiteralQuote = i + 1 < valueLength && value[i + 1] == JsWriter.QuoteChar;
+
+						i++; //skip quote
+						if (!isLiteralQuote)
+							break;
+					}
+					return value.Substring(tokenStartPos, i - tokenStartPos);
+
+				//Is Type/Map, i.e. {...}
+				case JsWriter.MapStartChar:
+					var endsToEat = 1;
+					var withinQuotes = false;
+					while (++i < valueLength && endsToEat > 0)
+					{
+						valueChar = value[i];
+
+						if (valueChar == JsWriter.QuoteChar)
+							withinQuotes = !withinQuotes;
+
+						if (withinQuotes)
+							continue;
+
+						if (valueChar == JsWriter.MapStartChar)
+							endsToEat++;
+
+						if (valueChar == JsWriter.MapEndChar)
+							endsToEat--;
+					}
+					return value.Substring(tokenStartPos, i - tokenStartPos);
+			}
+
+			while (value[++i] != JsWriter.MapKeySeperator) { }
+			return value.Substring(tokenStartPos, i - tokenStartPos);
+		}
+
+		public bool EatMapKeySeperator(string value, ref int i)
+		{
+			return value[i++] == JsWriter.MapKeySeperator;
+		}
+
+		public bool EatItemSeperatorOrMapEndChar(string value, ref int i)
+		{
+			if (i == value.Length) return false;
+
+			var success = value[i] == JsWriter.ItemSeperator
+				|| value[i] == JsWriter.MapEndChar;
+			i++;
+			return success;
+		}
+
+		public string EatValue(string value, ref int i)
+		{
+			var tokenStartPos = i;
+			var valueLength = value.Length;
+			if (i == valueLength) return null;
+
+			var valueChar = value[i];
+			var withinQuotes = false;
+			var endsToEat = 1;
+
+			switch (valueChar)
+			{
+				//If we are at the end, return.
+				case JsWriter.ItemSeperator:
+				case JsWriter.MapEndChar:
+					return null;
+
+				//Is Within Quotes, i.e. "..."
+				case JsWriter.QuoteChar:
+					while (++i < valueLength)
+					{
+						valueChar = value[i];
+
+						if (valueChar != JsWriter.QuoteChar) continue;
+
+						var isLiteralQuote = i + 1 < valueLength && value[i + 1] == JsWriter.QuoteChar;
+
+						i++; //skip quote
+						if (!isLiteralQuote)
+							break;
+					}
+					return value.Substring(tokenStartPos, i - tokenStartPos).FromCsvField();
+
+				//Is Type/Map, i.e. {...}
+				case JsWriter.MapStartChar:
+					while (++i < valueLength && endsToEat > 0)
+					{
+						valueChar = value[i];
+
+						if (valueChar == JsWriter.QuoteChar)
+							withinQuotes = !withinQuotes;
+
+						if (withinQuotes)
+							continue;
+
+						if (valueChar == JsWriter.MapStartChar)
+							endsToEat++;
+
+						if (valueChar == JsWriter.MapEndChar)
+							endsToEat--;
+					}
+					return value.Substring(tokenStartPos, i - tokenStartPos);
+
+				//Is List, i.e. [...]
+				case JsWriter.ListStartChar:
+					while (++i < valueLength && endsToEat > 0)
+					{
+						valueChar = value[i];
+
+						if (valueChar == JsWriter.QuoteChar)
+							withinQuotes = !withinQuotes;
+
+						if (withinQuotes)
+							continue;
+
+						if (valueChar == JsWriter.ListStartChar)
+							endsToEat++;
+
+						if (valueChar == JsWriter.ListEndChar)
+							endsToEat--;
+					}
+					return value.Substring(tokenStartPos, i - tokenStartPos);
+			}
+
+			//Is Value
+			while (++i < valueLength)
+			{
+				valueChar = value[i];
+
+				if (valueChar == JsWriter.ItemSeperator
+					|| valueChar == JsWriter.MapEndChar)
+				{
+					break;
+				}
+			}
+
+			return value.Substring(tokenStartPos, i - tokenStartPos);
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Jsv/JsvWriter.Generic.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Jsv/JsvWriter.Generic.cs
new file mode 100644
index 0000000..83b7488
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Jsv/JsvWriter.Generic.cs
@@ -0,0 +1,102 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using System.Threading;
+using ServiceStack.Text.Common;
+
+namespace ServiceStack.Text.Jsv
+{
+	internal static class JsvWriter
+	{
+		public static readonly JsWriter<JsvTypeSerializer> Instance = new JsWriter<JsvTypeSerializer>();
+
+        private static Dictionary<Type, WriteObjectDelegate> WriteFnCache = new Dictionary<Type, WriteObjectDelegate>();
+
+		public static WriteObjectDelegate GetWriteFn(Type type)
+		{
+			try
+			{
+                WriteObjectDelegate writeFn;
+                if (WriteFnCache.TryGetValue(type, out writeFn)) return writeFn;
+
+                var genericType = typeof(JsvWriter<>).MakeGenericType(type);
+                var mi = genericType.GetMethod("WriteFn", BindingFlags.Public | BindingFlags.Static);
+                var writeFactoryFn = (Func<WriteObjectDelegate>)Delegate.CreateDelegate(typeof(Func<WriteObjectDelegate>), mi);
+                writeFn = writeFactoryFn();
+
+                Dictionary<Type, WriteObjectDelegate> snapshot, newCache;
+                do
+                {
+                    snapshot = WriteFnCache;
+                    newCache = new Dictionary<Type, WriteObjectDelegate>(WriteFnCache);
+                    newCache[type] = writeFn;
+
+                } while (!ReferenceEquals(
+                    Interlocked.CompareExchange(ref WriteFnCache, newCache, snapshot), snapshot));
+
+                return writeFn;
+			}
+			catch (Exception ex)
+			{
+				Tracer.Instance.WriteError(ex);
+				throw;
+			}
+		}
+
+		public static void WriteLateBoundObject(TextWriter writer, object value)
+		{
+			if (value == null) return;
+			var writeFn = GetWriteFn(value.GetType());
+
+			var prevState = JsState.IsWritingDynamic;
+			JsState.IsWritingDynamic = true;
+			writeFn(writer, value);
+			JsState.IsWritingDynamic = prevState;
+		}
+
+		public static WriteObjectDelegate GetValueTypeToStringMethod(Type type)
+		{
+			return Instance.GetValueTypeToStringMethod(type);
+		}
+	}
+
+	/// <summary>
+	/// Implement the serializer using a more static approach
+	/// </summary>
+	/// <typeparam name="T"></typeparam>
+	internal static class JsvWriter<T>
+	{
+		private static readonly WriteObjectDelegate CacheFn;
+
+		public static WriteObjectDelegate WriteFn()
+		{
+			return CacheFn ?? WriteObject;
+		}
+
+		static JsvWriter()
+		{
+		    CacheFn = typeof(T) == typeof(object) 
+                ? JsvWriter.WriteLateBoundObject 
+                : JsvWriter.Instance.GetWriteFn<T>();
+		}
+
+	    public static void WriteObject(TextWriter writer, object value)
+		{
+			CacheFn(writer, value);
+		}
+
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/JsvFormatter.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/JsvFormatter.cs
new file mode 100644
index 0000000..d5a7308
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/JsvFormatter.cs
@@ -0,0 +1,95 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//	 Peter Townsend (townsend.pete at gmail.com)
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using ServiceStack.Text.Common;
+
+namespace ServiceStack.Text
+{
+	public static class JsvFormatter
+	{
+		public static string Format(string serializedText)
+		{
+			if (string.IsNullOrEmpty(serializedText)) return null;
+
+			var tabCount = 0;
+			var sb = new StringBuilder();
+			var firstKeySeparator = true;
+
+			for (var i = 0; i < serializedText.Length; i++)
+			{
+				var current = serializedText[i];
+				var previous = i - 1 >= 0 ? serializedText[i - 1] : 0;
+				var next = i < serializedText.Length - 1 ? serializedText[i + 1] : 0;
+
+				if (current == JsWriter.MapStartChar || current == JsWriter.ListStartChar)
+				{
+					if (previous == JsWriter.MapKeySeperator)
+					{
+						if (next == JsWriter.MapEndChar || next == JsWriter.ListEndChar)
+						{
+							sb.Append(current);
+							sb.Append(serializedText[++i]); //eat next
+							continue;
+						}
+
+						AppendTabLine(sb, tabCount);
+					}
+
+					sb.Append(current);
+					AppendTabLine(sb, ++tabCount);
+					firstKeySeparator = true;
+					continue;
+				}
+
+				if (current == JsWriter.MapEndChar || current == JsWriter.ListEndChar)
+				{
+					AppendTabLine(sb, --tabCount);
+					sb.Append(current);
+					firstKeySeparator = true;
+					continue;
+				}
+
+				if (current == JsWriter.ItemSeperator)
+				{
+					sb.Append(current);
+					AppendTabLine(sb, tabCount);
+					firstKeySeparator = true;
+					continue;
+				}
+
+				sb.Append(current);
+
+				if (current == JsWriter.MapKeySeperator && firstKeySeparator)
+				{
+					sb.Append(" ");
+					firstKeySeparator = false;
+				}
+			}
+
+			return sb.ToString();
+		}
+
+		private static void AppendTabLine(StringBuilder sb, int tabCount)
+		{
+			sb.AppendLine();
+
+			if (tabCount > 0)
+			{
+				sb.Append(new string('\t', tabCount));
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/ListExtensions.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/ListExtensions.cs
new file mode 100644
index 0000000..eca7e78
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/ListExtensions.cs
@@ -0,0 +1,62 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using ServiceStack.Text.Common;
+
+namespace ServiceStack.Text
+{
+	public static class ListExtensions
+	{
+		public static string Join<T>(this IEnumerable<T> values)
+		{
+			return Join(values, JsWriter.ItemSeperatorString);
+		}
+
+		public static string Join<T>(this IEnumerable<T> values, string seperator)
+		{
+			var sb = new StringBuilder();
+			foreach (var value in values)
+			{
+				if (sb.Length > 0)
+					sb.Append(seperator);
+				sb.Append(value);
+			}
+			return sb.ToString();
+		}
+
+		public static bool IsNullOrEmpty<T>(this List<T> list)
+		{
+			return list == null || list.Count == 0;
+		}
+
+		//TODO: make it work
+		public static IEnumerable<TFrom> SafeWhere<TFrom>(this List<TFrom> list, Func<TFrom, bool> predicate)
+		{
+			return list.Where(predicate);
+		}
+
+		public static int NullableCount<T>(this List<T> list)
+		{
+			return list == null ? 0 : list.Count;
+		}
+
+		public static void AddIfNotExists<T>(this List<T> list, T item)
+		{
+			if (!list.Contains(item))
+				list.Add(item);
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/MapExtensions.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/MapExtensions.cs
new file mode 100644
index 0000000..936441d
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/MapExtensions.cs
@@ -0,0 +1,39 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System.Collections.Generic;
+using System.Text;
+using ServiceStack.Text.Common;
+
+namespace ServiceStack.Text
+{
+	public static class MapExtensions
+	{
+		public static string Join<K, V>(this Dictionary<K, V> values)
+		{
+			return Join(values, JsWriter.ItemSeperatorString, JsWriter.MapKeySeperatorString);
+		}
+
+		public static string Join<K, V>(this Dictionary<K, V> values, string itemSeperator, string keySeperator)
+		{
+			var sb = new StringBuilder();
+			foreach (var entry in values)
+			{
+				if (sb.Length > 0)
+					sb.Append(itemSeperator);
+
+				sb.Append(entry.Key).Append(keySeperator).Append(entry.Value);
+			}
+			return sb.ToString();
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Marc/Link.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Marc/Link.cs
new file mode 100644
index 0000000..7cdc3b5
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Marc/Link.cs
@@ -0,0 +1,61 @@
+using System.Threading;
+
+//Not using it here, but @marcgravell's stuff is too good not to include
+namespace ServiceStack.Text.Marc
+{
+	/// <summary>
+	/// Pretty Thread-Safe cache class from:
+	/// http://code.google.com/p/dapper-dot-net/source/browse/Dapper/SqlMapper.cs
+	/// 
+	/// This is a micro-cache; suitable when the number of terms is controllable (a few hundred, for example),
+	/// and strictly append-only; you cannot change existing values. All key matches are on **REFERENCE**
+	/// equality. The type is fully thread-safe.
+	/// </summary>
+	class Link<TKey, TValue> where TKey : class
+	{
+		public static bool TryGet(Link<TKey, TValue> link, TKey key, out TValue value)
+		{
+			while (link != null)
+			{
+				if ((object)key == (object)link.Key)
+				{
+					value = link.Value;
+					return true;
+				}
+				link = link.Tail;
+			}
+			value = default(TValue);
+			return false;
+		}
+
+		public static bool TryAdd(ref Link<TKey, TValue> head, TKey key, ref TValue value)
+		{
+			bool tryAgain;
+			do
+			{
+				var snapshot = Interlocked.CompareExchange(ref head, null, null);
+				TValue found;
+				if (TryGet(snapshot, key, out found))
+				{ // existing match; report the existing value instead
+					value = found;
+					return false;
+				}
+				var newNode = new Link<TKey, TValue>(key, value, snapshot);
+				// did somebody move our cheese?
+				tryAgain = Interlocked.CompareExchange(ref head, newNode, snapshot) != snapshot;
+			} while (tryAgain);
+			return true;
+		}
+
+		private Link(TKey key, TValue value, Link<TKey, TValue> tail)
+		{
+			Key = key;
+			Value = value;
+			Tail = tail;
+		}
+		
+		public TKey Key { get; private set; }
+		public TValue Value { get; private set; }
+		public Link<TKey, TValue> Tail { get; private set; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Marc/ObjectAccessor.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Marc/ObjectAccessor.cs
new file mode 100644
index 0000000..fb27b4f
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Marc/ObjectAccessor.cs
@@ -0,0 +1,95 @@
+using System;
+//using System.Dynamic;
+
+//Not using it here, but @marcgravell's stuff is too good not to include
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+namespace FastMember
+{
+    /// <summary>
+    /// Represents an individual object, allowing access to members by-name
+    /// </summary>
+    public abstract class ObjectAccessor
+    {
+        /// <summary>
+        /// Get or Set the value of a named member for the underlying object
+        /// </summary>
+        public abstract object this[string name] { get; set; }
+        /// <summary>
+        /// The object represented by this instance
+        /// </summary>
+        public abstract object Target { get; }
+        /// <summary>
+        /// Use the target types definition of equality
+        /// </summary>
+        public override bool Equals(object obj)
+        {
+            return Target.Equals(obj);
+        }
+        /// <summary>
+        /// Obtain the hash of the target object
+        /// </summary>
+        public override int GetHashCode()
+        {
+            return Target.GetHashCode();
+        }
+        /// <summary>
+        /// Use the target's definition of a string representation
+        /// </summary>
+        public override string ToString()
+        {
+            return Target.ToString();
+        }
+
+        /// <summary>
+        /// Wraps an individual object, allowing by-name access to that instance
+        /// </summary>
+        public static ObjectAccessor Create(object target)
+        {
+            if (target == null) throw new ArgumentNullException("target");
+            //IDynamicMetaObjectProvider dlr = target as IDynamicMetaObjectProvider;
+            //if (dlr != null) return new DynamicWrapper(dlr); // use the DLR
+            return new TypeAccessorWrapper(target, TypeAccessor.Create(target.GetType()));
+        }
+
+        sealed class TypeAccessorWrapper : ObjectAccessor
+        {
+            private readonly object target;
+            private readonly TypeAccessor accessor;
+            public TypeAccessorWrapper(object target, TypeAccessor accessor)
+            {
+                this.target = target;
+                this.accessor = accessor;
+            }
+            public override object this[string name]
+            {
+                get { return accessor[target, name.ToUpperInvariant()]; }
+				set { accessor[target, name.ToUpperInvariant()] = value; }
+            }
+            public override object Target
+            {
+                get { return target; }
+            }
+        }
+
+		//sealed class DynamicWrapper : ObjectAccessor
+		//{
+		//    private readonly IDynamicMetaObjectProvider target;
+		//    public override object Target
+		//    {
+		//        get { return target; }
+		//    }
+		//    public DynamicWrapper(IDynamicMetaObjectProvider target)
+		//    {
+		//        this.target = target;
+		//    }
+		//    public override object this[string name]
+		//    {
+		//        get { return CallSiteCache.GetValue(name, target); }
+		//        set { CallSiteCache.SetValue(name, target, value); }
+		//    }
+        //}
+    }
+
+}
+
+#endif
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Marc/TypeAccessor.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Marc/TypeAccessor.cs
new file mode 100644
index 0000000..056e457
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Marc/TypeAccessor.cs
@@ -0,0 +1,308 @@
+using System;
+using System.Collections;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Threading;
+//using System.Dynamic;
+
+//Not using it here, but @marcgravell's stuff is too good not to include
+// http://code.google.com/p/fast-member/ Apache License 2.0
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+namespace FastMember
+{
+    /// <summary>
+    /// Provides by-name member-access to objects of a given type
+    /// </summary>
+    public abstract class TypeAccessor
+    {
+        // hash-table has better read-without-locking semantics than dictionary
+        private static readonly Hashtable typeLookyp = new Hashtable();
+
+        /// <summary>
+        /// Does this type support new instances via a parameterless constructor?
+        /// </summary>
+        public virtual bool CreateNewSupported { get { return false; } }
+        /// <summary>
+        /// Create a new instance of this type
+        /// </summary>
+        public virtual object CreateNew() { throw new NotSupportedException();}
+
+        /// <summary>
+        /// Provides a type-specific accessor, allowing by-name access for all objects of that type
+        /// </summary>
+        /// <remarks>The accessor is cached internally; a pre-existing accessor may be returned</remarks>
+        public static TypeAccessor Create(Type type)
+        {
+            if(type == null) throw new ArgumentNullException("type");
+            TypeAccessor obj = (TypeAccessor)typeLookyp[type];
+            if (obj != null) return obj;
+
+            lock(typeLookyp)
+            {
+                // double-check
+                obj = (TypeAccessor)typeLookyp[type];
+                if (obj != null) return obj;
+
+                obj = CreateNew(type);
+
+                typeLookyp[type] = obj;
+                return obj;
+            }
+        }
+
+		//sealed class DynamicAccessor : TypeAccessor
+		//{
+		//    public static readonly DynamicAccessor Singleton = new DynamicAccessor();
+		//    private DynamicAccessor(){}
+		//    public override object this[object target, string name]
+		//    {
+		//        get { return CallSiteCache.GetValue(name, target); }
+		//        set { CallSiteCache.SetValue(name, target, value); }
+		//    }
+		//}
+
+        private static AssemblyBuilder assembly;
+        private static ModuleBuilder module;
+        private static int counter;
+
+        private static void WriteGetter(ILGenerator il, Type type, PropertyInfo[] props, FieldInfo[] fields, bool isStatic)
+        {
+            LocalBuilder loc = type.IsValueType ? il.DeclareLocal(type) : null;
+            OpCode propName = isStatic ? OpCodes.Ldarg_1 : OpCodes.Ldarg_2, target = isStatic ? OpCodes.Ldarg_0 : OpCodes.Ldarg_1;
+            foreach (PropertyInfo prop in props)
+            {
+                if (prop.GetIndexParameters().Length != 0 || !prop.CanRead) continue;
+
+                Label next = il.DefineLabel();
+                il.Emit(propName);
+                il.Emit(OpCodes.Ldstr, prop.Name);
+                il.EmitCall(OpCodes.Call, strinqEquals, null);
+                il.Emit(OpCodes.Brfalse_S, next);
+                // match:
+                il.Emit(target);
+                Cast(il, type, loc);
+                il.EmitCall(type.IsValueType ? OpCodes.Call : OpCodes.Callvirt, prop.GetGetMethod(), null);
+                if (prop.PropertyType.IsValueType)
+                {
+                    il.Emit(OpCodes.Box, prop.PropertyType);
+                }
+                il.Emit(OpCodes.Ret);
+                // not match:
+                il.MarkLabel(next);
+            }
+            foreach (FieldInfo field in fields)
+            {
+                Label next = il.DefineLabel();
+                il.Emit(propName);
+                il.Emit(OpCodes.Ldstr, field.Name);
+                il.EmitCall(OpCodes.Call, strinqEquals, null);
+                il.Emit(OpCodes.Brfalse_S, next);
+                // match:
+                il.Emit(target);
+                Cast(il, type, loc);
+                il.Emit(OpCodes.Ldfld, field);
+                if (field.FieldType.IsValueType)
+                {
+                    il.Emit(OpCodes.Box, field.FieldType);
+                }
+                il.Emit(OpCodes.Ret);
+                // not match:
+                il.MarkLabel(next);
+            }
+            il.Emit(OpCodes.Ldstr, "name");
+            il.Emit(OpCodes.Newobj, typeof(ArgumentOutOfRangeException).GetConstructor(new Type[] { typeof(string) }));
+            il.Emit(OpCodes.Throw);
+        }
+        private static void WriteSetter(ILGenerator il, Type type, PropertyInfo[] props, FieldInfo[] fields, bool isStatic)
+        {
+            if (type.IsValueType)
+            {
+                il.Emit(OpCodes.Ldstr, "Write is not supported for structs");
+                il.Emit(OpCodes.Newobj, typeof(NotSupportedException).GetConstructor(new Type[] { typeof(string) }));
+                il.Emit(OpCodes.Throw);
+            }
+            else
+            {
+                OpCode propName = isStatic ? OpCodes.Ldarg_1 : OpCodes.Ldarg_2,
+                       target = isStatic ? OpCodes.Ldarg_0 : OpCodes.Ldarg_1,
+                       value = isStatic ? OpCodes.Ldarg_2 : OpCodes.Ldarg_3;
+                LocalBuilder loc = type.IsValueType ? il.DeclareLocal(type) : null;
+                foreach (PropertyInfo prop in props)
+                {
+                    if (prop.GetIndexParameters().Length != 0 || !prop.CanWrite) continue;
+
+                    Label next = il.DefineLabel();
+                    il.Emit(propName);
+                    il.Emit(OpCodes.Ldstr, prop.Name);
+                    il.EmitCall(OpCodes.Call, strinqEquals, null);
+                    il.Emit(OpCodes.Brfalse_S, next);
+                    // match:
+                    il.Emit(target);
+                    Cast(il, type, loc);
+                    il.Emit(value);
+                    Cast(il, prop.PropertyType, null);
+                    il.EmitCall(type.IsValueType ? OpCodes.Call : OpCodes.Callvirt, prop.GetSetMethod(), null);
+                    il.Emit(OpCodes.Ret);
+                    // not match:
+                    il.MarkLabel(next);
+                }
+                foreach (FieldInfo field in fields)
+                {
+                    Label next = il.DefineLabel();
+                    il.Emit(propName);
+                    il.Emit(OpCodes.Ldstr, field.Name);
+                    il.EmitCall(OpCodes.Call, strinqEquals, null);
+                    il.Emit(OpCodes.Brfalse_S, next);
+                    // match:
+                    il.Emit(target);
+                    Cast(il, type, loc);
+                    il.Emit(value);
+                    Cast(il, field.FieldType, null);
+                    il.Emit(OpCodes.Stfld, field);
+                    il.Emit(OpCodes.Ret);
+                    // not match:
+                    il.MarkLabel(next);
+                }
+                il.Emit(OpCodes.Ldstr, "name");
+                il.Emit(OpCodes.Newobj, typeof(ArgumentOutOfRangeException).GetConstructor(new Type[] { typeof(string) }));
+                il.Emit(OpCodes.Throw);
+            }
+        }
+        private static readonly MethodInfo strinqEquals = typeof(string).GetMethod("op_Equality", new Type[] { typeof(string), typeof(string) });
+
+        sealed class DelegateAccessor : TypeAccessor
+        {
+            private readonly Func<object, string, object> getter;
+            private readonly Action<object, string, object> setter;
+            private readonly Func<object> ctor;
+            public DelegateAccessor(Func<object, string, object> getter, Action<object, string, object> setter, Func<object> ctor)
+            {
+                this.getter = getter;
+                this.setter = setter;
+                this.ctor = ctor;
+            }
+            public override bool CreateNewSupported { get { return ctor != null; } }
+            public override object CreateNew()
+            {
+                return ctor != null ? ctor() : base.CreateNew();
+            }
+            public override object this[object target, string name]
+            {
+                get { return getter(target, name); }
+                set { setter(target, name, value); }
+            }
+        }
+        private static bool IsFullyPublic(Type type)
+        {
+            while (type.IsNestedPublic) type = type.DeclaringType;
+            return type.IsPublic;
+        }
+        static TypeAccessor CreateNew(Type type)
+        {
+			//if (typeof(IDynamicMetaObjectProvider).IsAssignableFrom(type))
+			//{
+			//    return DynamicAccessor.Singleton;
+			//}
+
+            PropertyInfo[] props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
+            FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance);
+            ConstructorInfo ctor = null;
+            if(type.IsClass && !type.IsAbstract)
+            {
+                ctor = type.GetConstructor(Type.EmptyTypes);
+            }
+            ILGenerator il;
+            if(!IsFullyPublic(type))
+            {
+                DynamicMethod dynGetter = new DynamicMethod(type.FullName + "_get", typeof(object), new Type[] { typeof(object), typeof(string) }, type, true),
+                              dynSetter = new DynamicMethod(type.FullName + "_set", null, new Type[] { typeof(object), typeof(string), typeof(object) }, type, true);
+                WriteGetter(dynGetter.GetILGenerator(), type, props, fields, true);
+                WriteSetter(dynSetter.GetILGenerator(), type, props, fields, true);
+                DynamicMethod dynCtor = null;
+                if(ctor != null)
+                {
+                    dynCtor = new DynamicMethod(type.FullName + "_ctor", typeof(object), Type.EmptyTypes, type, true);
+                    il = dynCtor.GetILGenerator();
+                    il.Emit(OpCodes.Newobj, ctor);
+                    il.Emit(OpCodes.Ret);
+                }
+                return new DelegateAccessor(
+                    (Func<object,string,object>)dynGetter.CreateDelegate(typeof(Func<object,string,object>)),
+                    (Action<object,string,object>)dynSetter.CreateDelegate(typeof(Action<object,string,object>)),
+                    dynCtor == null ? null : (Func<object>)dynCtor.CreateDelegate(typeof(Func<object>)));
+            }
+
+            // note this region is synchronized; only one is being created at a time so we don't need to stress about the builders
+            if(assembly == null)
+            {
+                AssemblyName name = new AssemblyName("FastMember_dynamic");
+                assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run);
+                module = assembly.DefineDynamicModule(name.Name);
+            }
+            TypeBuilder tb = module.DefineType("FastMember_dynamic." + type.Name + "_" + Interlocked.Increment(ref counter),
+                (typeof(TypeAccessor).Attributes | TypeAttributes.Sealed) & ~TypeAttributes.Abstract, typeof(TypeAccessor) );
+
+            tb.DefineDefaultConstructor(MethodAttributes.Public);
+            PropertyInfo indexer = typeof (TypeAccessor).GetProperty("Item");
+            MethodInfo baseGetter = indexer.GetGetMethod(), baseSetter = indexer.GetSetMethod();
+            MethodBuilder body = tb.DefineMethod(baseGetter.Name, baseGetter.Attributes & ~MethodAttributes.Abstract, typeof(object), new Type[] {typeof(object), typeof(string)});
+            il = body.GetILGenerator();
+            WriteGetter(il, type, props, fields, false);
+            tb.DefineMethodOverride(body, baseGetter);
+
+            body = tb.DefineMethod(baseSetter.Name, baseSetter.Attributes & ~MethodAttributes.Abstract, null, new Type[] { typeof(object), typeof(string), typeof(object) });
+            il = body.GetILGenerator();
+            WriteSetter(il, type, props, fields, false);
+            tb.DefineMethodOverride(body, baseSetter);
+
+            if(ctor != null)
+            {
+                MethodInfo baseMethod = typeof (TypeAccessor).GetProperty("CreateNewSupported").GetGetMethod();
+                body = tb.DefineMethod(baseMethod.Name, baseMethod.Attributes, typeof (bool), Type.EmptyTypes);
+                il = body.GetILGenerator();
+                il.Emit(OpCodes.Ldc_I4_1);
+                il.Emit(OpCodes.Ret);
+                tb.DefineMethodOverride(body, baseMethod);
+
+                baseMethod = typeof (TypeAccessor).GetMethod("CreateNew");
+                body = tb.DefineMethod(baseMethod.Name, baseMethod.Attributes, typeof (object), Type.EmptyTypes);
+                il = body.GetILGenerator();
+                il.Emit(OpCodes.Newobj, ctor);
+                il.Emit(OpCodes.Ret);
+                tb.DefineMethodOverride(body, baseMethod);
+            }
+
+            return (TypeAccessor)Activator.CreateInstance(tb.CreateType());
+        }
+
+        private static void Cast(ILGenerator il, Type type, LocalBuilder addr)
+        {
+            if(type == typeof(object)) {}
+            else if(type.IsValueType)
+            {
+                il.Emit(OpCodes.Unbox_Any, type);
+                if (addr != null)
+                {
+                    il.Emit(OpCodes.Stloc, addr);
+                    il.Emit(OpCodes.Ldloca_S, addr);
+                }
+            }
+            else
+            {
+                il.Emit(OpCodes.Castclass, type);
+            }
+        }
+
+        /// <summary>
+        /// Get or set the value of a named member on the target instance
+        /// </summary>
+        public abstract object this[object target, string name]
+        {
+            get; set;
+        }
+    }
+}
+
+#endif
+
+
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Properties/AssemblyInfo.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..1007675
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+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("ServiceStack.Text")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("ServiceStack.Text")]
+[assembly: AssemblyCopyright("Copyright © ServiceStack 2012")]
+[assembly: AssemblyTrademark("")]
+[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("a352d4d3-df2a-4c78-b646-67181a6333a6")]
+
+// 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 Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("3.5.7.*")]
+//[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/QueryStringSerializer.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/QueryStringSerializer.cs
new file mode 100644
index 0000000..f863967
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/QueryStringSerializer.cs
@@ -0,0 +1,128 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Reflection;
+using System.Text;
+using System.Threading;
+using ServiceStack.Text.Common;
+using ServiceStack.Text.Jsv;
+
+namespace ServiceStack.Text
+{
+	public static class QueryStringSerializer
+	{
+		internal static readonly JsWriter<JsvTypeSerializer> Instance = new JsWriter<JsvTypeSerializer>();
+
+		private static Dictionary<Type, WriteObjectDelegate> WriteFnCache = new Dictionary<Type, WriteObjectDelegate>();
+
+		internal static WriteObjectDelegate GetWriteFn(Type type)
+		{
+			try
+			{
+				WriteObjectDelegate writeFn;
+                if (WriteFnCache.TryGetValue(type, out writeFn)) return writeFn;
+
+                var genericType = typeof(QueryStringWriter<>).MakeGenericType(type);
+                var mi = genericType.GetMethod("WriteFn", BindingFlags.NonPublic | BindingFlags.Static);
+                var writeFactoryFn = (Func<WriteObjectDelegate>)Delegate.CreateDelegate(
+                    typeof(Func<WriteObjectDelegate>), mi);
+                writeFn = writeFactoryFn();
+
+                Dictionary<Type, WriteObjectDelegate> snapshot, newCache;
+                do
+                {
+                    snapshot = WriteFnCache;
+                    newCache = new Dictionary<Type, WriteObjectDelegate>(WriteFnCache);
+                    newCache[type] = writeFn;
+
+                } while (!ReferenceEquals(
+                    Interlocked.CompareExchange(ref WriteFnCache, newCache, snapshot), snapshot));
+                
+                return writeFn;
+			}
+			catch (Exception ex)
+			{
+				Tracer.Instance.WriteError(ex);
+				throw;
+			}
+		}
+
+		public static void WriteLateBoundObject(TextWriter writer, object value)
+		{
+			if (value == null) return;
+			var writeFn = GetWriteFn(value.GetType());
+			writeFn(writer, value);
+		}
+
+		internal static WriteObjectDelegate GetValueTypeToStringMethod(Type type)
+		{
+			return Instance.GetValueTypeToStringMethod(type);
+		}
+
+		public static string SerializeToString<T>(T value)
+		{
+			var sb = new StringBuilder();
+			using (var writer = new StringWriter(sb, CultureInfo.InvariantCulture))
+			{
+				GetWriteFn(value.GetType())(writer, value);
+			}
+			return sb.ToString();
+		}
+	}
+
+	/// <summary>
+	/// Implement the serializer using a more static approach
+	/// </summary>
+	/// <typeparam name="T"></typeparam>
+	public static class QueryStringWriter<T>
+	{
+		private static readonly WriteObjectDelegate CacheFn;
+
+		internal static WriteObjectDelegate WriteFn()
+		{
+			return CacheFn;
+		}
+
+		static QueryStringWriter()
+		{
+			if (typeof(T) == typeof(object))
+			{
+				CacheFn = QueryStringSerializer.WriteLateBoundObject;
+			}
+			else
+			{
+				if (typeof(T).IsClass || typeof(T).IsInterface)
+				{
+					var canWriteType = WriteType<T, JsvTypeSerializer>.Write;
+					if (canWriteType != null)
+					{
+						CacheFn = WriteType<T, JsvTypeSerializer>.WriteQueryString;
+						return;
+					}
+				}
+
+				CacheFn = QueryStringSerializer.Instance.GetWriteFn<T>();
+			}
+		}
+
+		public static void WriteObject(TextWriter writer, object value)
+		{
+			if (writer == null) return;
+			CacheFn(writer, value);
+		}
+	}
+	
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Reflection/StaticAccessors.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Reflection/StaticAccessors.cs
new file mode 100644
index 0000000..49c05ee
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Reflection/StaticAccessors.cs
@@ -0,0 +1,76 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+using System;
+using System.Reflection;
+
+#if !XBOX
+using System.Linq.Expressions ;
+#endif
+namespace ServiceStack.Text.Reflection
+{
+	public static class StaticAccessors
+	{
+		public static Func<object, object> GetValueGetter(this PropertyInfo propertyInfo, Type type)
+		{
+#if SILVERLIGHT || MONOTOUCH || XBOX
+			var getMethodInfo = propertyInfo.GetGetMethod();
+			if (getMethodInfo == null) return null;
+			return x => getMethodInfo.Invoke(x, new object[0]);
+#else
+
+			var instance = Expression.Parameter(typeof(object), "i");
+			var convertInstance = Expression.TypeAs(instance, propertyInfo.DeclaringType);
+			var property = Expression.Property(convertInstance, propertyInfo);
+			var convertProperty = Expression.TypeAs(property, typeof(object));
+			return Expression.Lambda<Func<object, object>>(convertProperty, instance).Compile();
+#endif
+		}
+
+		public static Func<T, object> GetValueGetter<T>(this PropertyInfo propertyInfo)
+		{
+#if SILVERLIGHT || MONOTOUCH || XBOX
+			var getMethodInfo = propertyInfo.GetGetMethod();
+			if (getMethodInfo == null) return null;
+			return x => getMethodInfo.Invoke(x, new object[0]);
+#else
+			var instance = Expression.Parameter(propertyInfo.DeclaringType, "i");
+			var property = Expression.Property(instance, propertyInfo);
+			var convert = Expression.TypeAs(property, typeof(object));
+			return Expression.Lambda<Func<T, object>>(convert, instance).Compile();
+#endif
+		}
+
+#if !XBOX
+		public static Action<T, object> GetValueSetter<T>(this PropertyInfo propertyInfo)
+		{
+			if (typeof(T) != propertyInfo.DeclaringType)
+			{
+				throw new ArgumentException();
+			}
+
+			var instance = Expression.Parameter(propertyInfo.DeclaringType, "i");
+			var argument = Expression.Parameter(typeof(object), "a");
+			var setterCall = Expression.Call(
+				instance,
+				propertyInfo.GetSetMethod(),
+				Expression.Convert(argument, propertyInfo.PropertyType));
+
+			return Expression.Lambda<Action<T, object>>
+			(
+				setterCall, instance, argument
+			).Compile();
+		}
+#endif
+
+	}
+}
+
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/ReflectionExtensions.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/ReflectionExtensions.cs
new file mode 100644
index 0000000..9e99759
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/ReflectionExtensions.cs
@@ -0,0 +1,424 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.Serialization;
+using System.Threading;
+using ServiceStack.Text.Support;
+
+namespace ServiceStack.Text
+{
+	public delegate object EmptyCtorDelegate();
+
+	public static class ReflectionExtensions
+	{
+		private static Dictionary<Type, object> DefaultValueTypes = new Dictionary<Type, object>();
+
+		public static object GetDefaultValue(Type type)
+		{
+			if (!type.IsValueType) return null;
+
+			object defaultValue;
+			if (DefaultValueTypes.TryGetValue(type, out defaultValue)) return defaultValue;
+
+			defaultValue = Activator.CreateInstance(type);
+
+			Dictionary<Type, object> snapshot, newCache;
+			do
+			{
+				snapshot = DefaultValueTypes;
+				newCache = new Dictionary<Type, object>(DefaultValueTypes);
+				newCache[type] = defaultValue;
+
+			} while (!ReferenceEquals(
+				Interlocked.CompareExchange(ref DefaultValueTypes, newCache, snapshot), snapshot));
+
+			return defaultValue;
+		}
+
+		public static bool IsInstanceOf(this Type type, Type thisOrBaseType)
+		{
+			while (type != null)
+			{
+				if (type == thisOrBaseType)
+					return true;
+
+				type = type.BaseType;
+			}
+			return false;
+		}
+
+		public static bool IsGenericType(this Type type)
+		{
+			while (type != null)
+			{
+				if (type.IsGenericType)
+					return true;
+
+				type = type.BaseType;
+			}
+			return false;
+		}
+
+		public static Type GetGenericType(this Type type)
+		{
+			while (type != null)
+			{
+				if (type.IsGenericType)
+					return type;
+
+				type = type.BaseType;
+			}
+			return null;
+		}
+
+		public static bool IsOrHasGenericInterfaceTypeOf(this Type type, Type genericTypeDefinition)
+		{
+			return type.GetTypeWithGenericTypeDefinitionOf(genericTypeDefinition) != null;
+		}
+
+		public static Type GetTypeWithGenericTypeDefinitionOf(this Type type, Type genericTypeDefinition)
+		{
+			foreach (var t in type.GetInterfaces())
+			{
+				if (t.IsGenericType && t.GetGenericTypeDefinition() == genericTypeDefinition)
+				{
+					return t;
+				}
+			}
+
+			var genericType = type.GetGenericType();
+			if (genericType != null && genericType.GetGenericTypeDefinition() == genericTypeDefinition)
+			{
+				return genericType;
+			}
+
+			return null;
+		}
+
+		public static Type GetTypeWithInterfaceOf(this Type type, Type interfaceType)
+		{
+			if (type == interfaceType) return interfaceType;
+
+			foreach (var t in type.GetInterfaces())
+			{
+				if (t == interfaceType)
+					return t;
+			}
+
+			return null;
+		}
+
+		public static bool HasInterface(this Type type, Type interfaceType)
+		{
+			foreach (var t in type.GetInterfaces())
+			{
+				if (t == interfaceType)
+					return true;
+			}
+			return false;
+		}
+
+		public static bool AllHaveInterfacesOfType(
+			this Type assignableFromType, params Type[] types)
+		{
+			foreach (var type in types)
+			{
+				if (assignableFromType.GetTypeWithInterfaceOf(type) == null) return false;
+			}
+			return true;
+		}
+
+		public static bool IsNumericType(this Type type)
+		{
+			if (!type.IsValueType) return false;
+			return type.IsIntegerType() || type.IsRealNumberType();
+		}
+
+		public static bool IsIntegerType(this Type type)
+		{
+			if (!type.IsValueType) return false;
+			var underlyingType = Nullable.GetUnderlyingType(type) ?? type;
+			return underlyingType == typeof(byte)
+			   || underlyingType == typeof(sbyte)
+			   || underlyingType == typeof(short)
+			   || underlyingType == typeof(ushort)
+			   || underlyingType == typeof(int)
+			   || underlyingType == typeof(uint)
+			   || underlyingType == typeof(long)
+			   || underlyingType == typeof(ulong);
+		}
+
+		public static bool IsRealNumberType(this Type type)
+		{
+			if (!type.IsValueType) return false;
+			var underlyingType = Nullable.GetUnderlyingType(type) ?? type;
+			return underlyingType == typeof(float)
+			   || underlyingType == typeof(double)
+			   || underlyingType == typeof(decimal);
+		}
+
+		public static Type GetTypeWithGenericInterfaceOf(this Type type, Type genericInterfaceType)
+		{
+			foreach (var t in type.GetInterfaces())
+			{
+				if (t.IsGenericType && t.GetGenericTypeDefinition() == genericInterfaceType) return t;
+			}
+
+			if (!type.IsGenericType) return null;
+
+			var genericType = type.GetGenericType();
+			return genericType.GetGenericTypeDefinition() == genericInterfaceType
+					? genericType
+					: null;
+		}
+
+		public static bool HasAnyTypeDefinitionsOf(this Type genericType, params Type[] theseGenericTypes)
+		{
+			if (!genericType.IsGenericType) return false;
+			var genericTypeDefinition = genericType.GetGenericTypeDefinition();
+
+			foreach (var thisGenericType in theseGenericTypes)
+			{
+				if (genericTypeDefinition == thisGenericType)
+					return true;
+			}
+
+			return false;
+		}
+
+		public static Type[] GetGenericArgumentsIfBothHaveSameGenericDefinitionTypeAndArguments(
+			this Type assignableFromType, Type typeA, Type typeB)
+		{
+			var typeAInterface = typeA.GetTypeWithGenericInterfaceOf(assignableFromType);
+			if (typeAInterface == null) return null;
+
+			var typeBInterface = typeB.GetTypeWithGenericInterfaceOf(assignableFromType);
+			if (typeBInterface == null) return null;
+
+			var typeAGenericArgs = typeAInterface.GetGenericArguments();
+			var typeBGenericArgs = typeBInterface.GetGenericArguments();
+			if (typeAGenericArgs.Length != typeBGenericArgs.Length) return null;
+
+			for (var i = 0; i < typeBGenericArgs.Length; i++)
+			{
+				if (typeAGenericArgs[i] != typeBGenericArgs[i])
+				{
+					return null;
+				}
+			}
+
+			return typeAGenericArgs;
+		}
+
+		public static TypePair GetGenericArgumentsIfBothHaveConvertibleGenericDefinitionTypeAndArguments(
+			this Type assignableFromType, Type typeA, Type typeB)
+		{
+			var typeAInterface = typeA.GetTypeWithGenericInterfaceOf(assignableFromType);
+			if (typeAInterface == null) return null;
+
+			var typeBInterface = typeB.GetTypeWithGenericInterfaceOf(assignableFromType);
+			if (typeBInterface == null) return null;
+
+			var typeAGenericArgs = typeAInterface.GetGenericArguments();
+			var typeBGenericArgs = typeBInterface.GetGenericArguments();
+			if (typeAGenericArgs.Length != typeBGenericArgs.Length) return null;
+
+			for (var i = 0; i < typeBGenericArgs.Length; i++)
+			{
+				if (!AreAllStringOrValueTypes(typeAGenericArgs[i], typeBGenericArgs[i]))
+				{
+					return null;
+				}
+			}
+
+			return new TypePair(typeAGenericArgs, typeBGenericArgs);
+		}
+
+		public static bool AreAllStringOrValueTypes(params Type[] types)
+		{
+			foreach (var type in types)
+			{
+				if (!(type == typeof(string) || type.IsValueType)) return false;
+			}
+			return true;
+		}
+
+		static Dictionary<Type, EmptyCtorDelegate> ConstructorMethods = new Dictionary<Type, EmptyCtorDelegate>();
+		public static EmptyCtorDelegate GetConstructorMethod(Type type)
+		{
+			EmptyCtorDelegate emptyCtorFn;
+			if (ConstructorMethods.TryGetValue(type, out emptyCtorFn)) return emptyCtorFn;
+
+			emptyCtorFn = GetConstructorMethodToCache(type);
+
+			Dictionary<Type, EmptyCtorDelegate> snapshot, newCache;
+			do
+			{
+				snapshot = ConstructorMethods;
+				newCache = new Dictionary<Type, EmptyCtorDelegate>(ConstructorMethods);
+				newCache[type] = emptyCtorFn;
+
+			} while (!ReferenceEquals(
+				Interlocked.CompareExchange(ref ConstructorMethods, newCache, snapshot), snapshot));
+
+			return emptyCtorFn;
+		}
+
+		static Dictionary<string, EmptyCtorDelegate> TypeNamesMap = new Dictionary<string, EmptyCtorDelegate>();
+		public static EmptyCtorDelegate GetConstructorMethod(string typeName)
+		{
+			EmptyCtorDelegate emptyCtorFn;
+			if (TypeNamesMap.TryGetValue(typeName, out emptyCtorFn)) return emptyCtorFn;
+
+			var type = AssemblyUtils.FindType(typeName);
+			if (type == null) return null;
+			emptyCtorFn = GetConstructorMethodToCache(type);
+
+			Dictionary<string, EmptyCtorDelegate> snapshot, newCache;
+			do
+			{
+				snapshot = TypeNamesMap;
+				newCache = new Dictionary<string, EmptyCtorDelegate>(TypeNamesMap);
+				newCache[typeName] = emptyCtorFn;
+
+			} while (!ReferenceEquals(
+				Interlocked.CompareExchange(ref TypeNamesMap, newCache, snapshot), snapshot));
+
+			return emptyCtorFn;
+		}
+
+		public static EmptyCtorDelegate GetConstructorMethodToCache(Type type)
+		{
+			var emptyCtor = type.GetConstructor(Type.EmptyTypes);
+			if (emptyCtor != null)
+			{
+
+#if MONOTOUCH || SILVERLIGHT || XBOX
+				return () => Activator.CreateInstance(type);
+#else
+				var dm = new System.Reflection.Emit.DynamicMethod("MyCtor", type, Type.EmptyTypes, typeof(ReflectionExtensions).Module, true);
+				var ilgen = dm.GetILGenerator();
+				ilgen.Emit(System.Reflection.Emit.OpCodes.Nop);
+				ilgen.Emit(System.Reflection.Emit.OpCodes.Newobj, emptyCtor);
+				ilgen.Emit(System.Reflection.Emit.OpCodes.Ret);
+
+				return (EmptyCtorDelegate)dm.CreateDelegate(typeof(EmptyCtorDelegate));
+#endif
+			}
+
+#if SILVERLIGHT || XBOX
+			return () => Activator.CreateInstance(type);
+#else
+			//Anonymous types don't have empty constructors
+			return () => FormatterServices.GetUninitializedObject(type);
+#endif
+		}
+
+		private static class TypeMeta<T>
+		{
+			public static readonly EmptyCtorDelegate EmptyCtorFn;
+			static TypeMeta()
+			{
+				EmptyCtorFn = GetConstructorMethodToCache(typeof(T));
+			}
+		}
+
+		public static object CreateInstance<T>()
+		{
+			return TypeMeta<T>.EmptyCtorFn();
+		}
+
+		public static object CreateInstance(this Type type)
+		{
+			var ctorFn = GetConstructorMethod(type);
+			return ctorFn();
+		}
+
+		public static object CreateInstance(string typeName)
+		{
+			var ctorFn = GetConstructorMethod(typeName);
+			return ctorFn();
+		}
+
+		public static PropertyInfo[] GetPublicProperties(this Type type)
+		{
+			if (type.IsInterface)
+			{
+				var propertyInfos = new List<PropertyInfo>();
+
+				var considered = new List<Type>();
+				var queue = new Queue<Type>();
+				considered.Add(type);
+				queue.Enqueue(type);
+				while (queue.Count > 0)
+				{
+					var subType = queue.Dequeue();
+					foreach (var subInterface in subType.GetInterfaces())
+					{
+						if (considered.Contains(subInterface)) continue;
+
+						considered.Add(subInterface);
+						queue.Enqueue(subInterface);
+					}
+
+					var typeProperties = subType.GetProperties(
+						BindingFlags.FlattenHierarchy
+						| BindingFlags.Public
+						| BindingFlags.Instance);
+
+					var newPropertyInfos = typeProperties
+						.Where(x => !propertyInfos.Contains(x));
+
+					propertyInfos.InsertRange(0, newPropertyInfos);
+				}
+
+				return propertyInfos.ToArray();
+			}
+
+			return type.GetProperties(BindingFlags.FlattenHierarchy
+				| BindingFlags.Public | BindingFlags.Instance);
+		}
+
+		const string DataContract = "DataContractAttribute";
+		const string DataMember = "DataMemberAttribute";
+		const string IgnoreDataMember = "IgnoreDataMemberAttribute";
+
+		public static PropertyInfo[] GetSerializableProperties(this Type type)
+		{
+			var publicProperties = GetPublicProperties(type);
+			var publicReadableProperties = publicProperties.Where(x => x.GetGetMethod(false) != null);
+
+			//If it is a 'DataContract' only return 'DataMember' properties.
+			//checking for "DataContract" using strings to avoid dependency on System.Runtime.Serialization
+			if (type.IsDto())
+			{
+				return publicReadableProperties.Where(attr =>
+					attr.GetCustomAttributes(false).Any(x => x.GetType().Name == DataMember))
+					.ToArray();
+			}
+			// else return those properties that are not decorated with IgnoreDataMember
+			return publicReadableProperties.Where(prop => !prop.GetCustomAttributes(false).Any(attr => attr.GetType().Name == IgnoreDataMember)).ToArray();
+		}
+
+		public static bool IsDto(this Type type)
+		{
+			return type.GetCustomAttributes(true).Any(x => x.GetType().Name == DataContract);
+		}
+
+	}
+
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/ServiceStack.Text.csproj b/lib/ServiceStack.Text/src/ServiceStack.Text/ServiceStack.Text.csproj
new file mode 100644
index 0000000..5108c44
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/ServiceStack.Text.csproj
@@ -0,0 +1,299 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{579B3FDB-CDAD-44E1-8417-885C38E49A0E}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>ServiceStack.Text</RootNamespace>
+    <AssemblyName>ServiceStack.Text</AssemblyName>
+    <FileAlignment>512</FileAlignment>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation />
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+  </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>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <DocumentationFile>bin\Release\ServiceStack.Text.XML</DocumentationFile>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'MonoTouch|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\MonoTouch</OutputPath>
+    <DefineConstants>MONOTOUCH;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Data.Linq" />
+    <Reference Include="System.Runtime.Serialization" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="AssemblyUtils.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Common\DateTimeSerializer.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Common\DeserializeArray.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Common\DeserializeBuiltin.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Common\DeserializeCollection.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Common\DeserializeDictionary.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Common\DeserializeListWithElements.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Common\DeserializeSpecializedCollections.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Common\DeserializeType.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Common\DeserializeTypeRef.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Common\DeserializeTypeRefJson.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Common\DeserializeTypeRefJsv.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Common\DeserializeTypeUtils.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Common\ITypeSerializer.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Common\JsDelegates.cs" />
+    <Compile Include="Common\JsReader.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Common\JsState.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Common\JsWriter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Common\ParseUtils.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Common\StaticParseMethod.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Common\WriteDictionary.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Common\WriteLists.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Common\WriteType.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Controller\CommandProcessor.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Controller\PathInfo.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="CsvConfig.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="CsvSerializer.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="CsvStreamExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="CsvWriter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DateTimeExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Env.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ITracer.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ITypeSerializer.Generic.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="JsConfig.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="JsonObject.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="JsonSerializer.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="JsonSerializer.Generic.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Json\JsonReader.Generic.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Json\JsonTypeSerializer.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Json\JsonUtils.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Json\JsonWriter.Generic.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="JsvFormatter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Jsv\JsvDeserializeType.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Jsv\JsvReader.Generic.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Jsv\JsvSerializer.Generic.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Jsv\JsvTypeSerializer.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Jsv\JsvWriter.Generic.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ListExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="MapExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Marc\Link.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Marc\ObjectAccessor.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Marc\TypeAccessor.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="QueryStringSerializer.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ReflectionExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Reflection\StaticAccessors.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="StreamExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="StringExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Support\AssemblyTypeDefinition.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Support\DoubleConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Support\TypePair.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="TextExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Tracer.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="TranslateListWithElements.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="TypeConfig.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="TypeSerializer.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="TypeSerializer.Generic.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="XmlSerializer.cs">
+      <SubType>Code</SubType>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+      <Visible>False</Visible>
+      <ProductName>Windows Installer 3.1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+  </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>
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/StreamExtensions.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/StreamExtensions.cs
new file mode 100644
index 0000000..7595631
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/StreamExtensions.cs
@@ -0,0 +1,230 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+
+namespace ServiceStack.Text
+{
+	public static class StreamExtensions
+	{
+		public static void WriteTo(this Stream inStream, Stream outStream)
+		{
+			var memoryStream = inStream as MemoryStream;
+			if (memoryStream != null)
+			{
+				memoryStream.WriteTo(outStream);
+				return;
+			}
+
+			var data = new byte[4096];
+			int bytesRead;
+
+			while ((bytesRead = inStream.Read(data, 0, data.Length)) > 0)
+			{
+				outStream.Write(data, 0, bytesRead);
+			}
+		}
+
+		public static IEnumerable<string> ReadLines(this StreamReader reader)
+		{
+			if (reader == null)
+				throw new ArgumentNullException("reader");
+
+			string line;
+			while ((line = reader.ReadLine()) != null)
+			{
+				yield return line;
+			}
+		}
+
+		/// <summary>
+		/// @jonskeet: Collection of utility methods which operate on streams.
+		/// r285, February 26th 2009: http://www.yoda.arachsys.com/csharp/miscutil/
+		/// </summary>
+		const int DefaultBufferSize = 8 * 1024;
+
+		/// <summary>
+		/// Reads the given stream up to the end, returning the data as a byte
+		/// array.
+		/// </summary>
+		public static byte[] ReadFully(this Stream input)
+		{
+			return ReadFully(input, DefaultBufferSize);
+		}
+
+		/// <summary>
+		/// Reads the given stream up to the end, returning the data as a byte
+		/// array, using the given buffer size.
+		/// </summary>
+		public static byte[] ReadFully(this Stream input, int bufferSize)
+		{
+			if (bufferSize < 1)
+			{
+				throw new ArgumentOutOfRangeException("bufferSize");
+			}
+			return ReadFully(input, new byte[bufferSize]);
+		}
+
+		/// <summary>
+		/// Reads the given stream up to the end, returning the data as a byte
+		/// array, using the given buffer for transferring data. Note that the
+		/// current contents of the buffer is ignored, so the buffer needn't
+		/// be cleared beforehand.
+		/// </summary>
+		public static byte[] ReadFully(this Stream input, byte[] buffer)
+		{
+			if (buffer == null)
+			{
+				throw new ArgumentNullException("buffer");
+			}
+			if (input == null)
+			{
+				throw new ArgumentNullException("input");
+			}
+			if (buffer.Length == 0)
+			{
+				throw new ArgumentException("Buffer has length of 0");
+			}
+			// We could do all our own work here, but using MemoryStream is easier
+			// and likely to be just as efficient.
+			using (var tempStream = new MemoryStream())
+			{
+				CopyTo(input, tempStream, buffer);
+				// No need to copy the buffer if it's the right size
+				if (tempStream.Length == tempStream.GetBuffer().Length)
+				{
+					return tempStream.GetBuffer();
+				}
+				// Okay, make a copy that's the right size
+				return tempStream.ToArray();
+			}
+		}
+
+		/// <summary>
+		/// Copies all the data from one stream into another.
+		/// </summary>
+		public static void CopyTo(this Stream input, Stream output)
+		{
+			CopyTo(input, output, DefaultBufferSize);
+		}
+
+		/// <summary>
+		/// Copies all the data from one stream into another, using a buffer
+		/// of the given size.
+		/// </summary>
+		public static void CopyTo(this Stream input, Stream output, int bufferSize)
+		{
+			if (bufferSize < 1)
+			{
+				throw new ArgumentOutOfRangeException("bufferSize");
+			}
+			CopyTo(input, output, new byte[bufferSize]);
+		}
+
+		/// <summary>
+		/// Copies all the data from one stream into another, using the given 
+		/// buffer for transferring data. Note that the current contents of 
+		/// the buffer is ignored, so the buffer needn't be cleared beforehand.
+		/// </summary>
+		public static void CopyTo(this Stream input, Stream output, byte[] buffer)
+		{
+			if (buffer == null)
+			{
+				throw new ArgumentNullException("buffer");
+			}
+			if (input == null)
+			{
+				throw new ArgumentNullException("input");
+			}
+			if (output == null)
+			{
+				throw new ArgumentNullException("output");
+			}
+			if (buffer.Length == 0)
+			{
+				throw new ArgumentException("Buffer has length of 0");
+			}
+			int read;
+			while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
+			{
+				output.Write(buffer, 0, read);
+			}
+		}
+
+		/// <summary>
+		/// Reads exactly the given number of bytes from the specified stream.
+		/// If the end of the stream is reached before the specified amount
+		/// of data is read, an exception is thrown.
+		/// </summary>
+		public static byte[] ReadExactly(this Stream input, int bytesToRead)
+		{
+			return ReadExactly(input, new byte[bytesToRead]);
+		}
+
+		/// <summary>
+		/// Reads into a buffer, filling it completely.
+		/// </summary>
+		public static byte[] ReadExactly(this Stream input, byte[] buffer)
+		{
+			return ReadExactly(input, buffer, buffer.Length);
+		}
+
+		/// <summary>
+		/// Reads exactly the given number of bytes from the specified stream,
+		/// into the given buffer, starting at position 0 of the array.
+		/// </summary>
+		public static byte[] ReadExactly(this Stream input, byte[] buffer, int bytesToRead)
+		{
+			return ReadExactly(input, buffer, 0, bytesToRead);
+		}
+
+		/// <summary>
+		/// Reads exactly the given number of bytes from the specified stream,
+		/// into the given buffer, starting at position 0 of the array.
+		/// </summary>
+		public static byte[] ReadExactly(this Stream input, byte[] buffer, int startIndex, int bytesToRead)
+		{
+			if (input == null)
+			{
+				throw new ArgumentNullException("input");
+			}
+
+			if (buffer == null)
+			{
+				throw new ArgumentNullException("buffer");
+			}
+
+			if (startIndex < 0 || startIndex >= buffer.Length)
+			{
+				throw new ArgumentOutOfRangeException("startIndex");
+			}
+
+			if (bytesToRead < 1 || startIndex + bytesToRead > buffer.Length)
+			{
+				throw new ArgumentOutOfRangeException("bytesToRead");
+			}
+
+			return ReadExactlyFast(input, buffer, startIndex, bytesToRead);
+		}
+
+		/// <summary>
+		/// Same as ReadExactly, but without the argument checks.
+		/// </summary>
+		private static byte[] ReadExactlyFast(Stream fromStream, byte[] intoBuffer, int startAtIndex, int bytesToRead)
+		{
+			var index = 0;
+			while (index < bytesToRead)
+			{
+				var read = fromStream.Read(intoBuffer, startAtIndex + index, bytesToRead - index);
+				if (read == 0)
+				{
+					throw new EndOfStreamException
+						(String.Format("End of stream reached with {0} byte{1} left to read.",
+						               bytesToRead - index,
+						               bytesToRead - index == 1 ? "s" : ""));
+				}
+				index += read;
+			}
+			return intoBuffer;
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/StringExtensions.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/StringExtensions.cs
new file mode 100644
index 0000000..82ece3b
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/StringExtensions.cs
@@ -0,0 +1,539 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Globalization;
+using System.Text.RegularExpressions;
+using ServiceStack.Text.Support;
+
+namespace ServiceStack.Text
+{
+    public static class StringExtensions
+    {
+        public static T To<T>(this string value)
+        {
+            return TypeSerializer.DeserializeFromString<T>(value);
+        }
+
+        public static T To<T>(this string value, T defaultValue)
+        {
+            return string.IsNullOrEmpty(value) ? defaultValue : TypeSerializer.DeserializeFromString<T>(value);
+        }
+
+        public static T ToOrDefaultValue<T>(this string value)
+        {
+            return string.IsNullOrEmpty(value) ? default(T) : TypeSerializer.DeserializeFromString<T>(value);
+        }
+
+        public static object To(this string value, Type type)
+        {
+            return TypeSerializer.DeserializeFromString(value, type);
+        }
+
+
+        /// <summary>
+        /// Converts from base: 0 - 62
+        /// </summary>
+        /// <param name="source">The source.</param>
+        /// <param name="from">From.</param>
+        /// <param name="to">To.</param>
+        /// <returns></returns>
+        public static string BaseConvert(this string source, int from, int to)
+        {
+            const string chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+            var result = "";
+            var length = source.Length;
+            var number = new int[length];
+
+            for (var i = 0; i < length; i++)
+            {
+                number[i] = chars.IndexOf(source[i]);
+            }
+
+            int newlen;
+
+            do
+            {
+                var divide = 0;
+                newlen = 0;
+
+                for (var i = 0; i < length; i++)
+                {
+                    divide = divide * from + number[i];
+
+                    if (divide >= to)
+                    {
+                        number[newlen++] = divide / to;
+                        divide = divide % to;
+                    }
+                    else if (newlen > 0)
+                    {
+                        number[newlen++] = 0;
+                    }
+                }
+
+                length = newlen;
+                result = chars[divide] + result;
+            }
+            while (newlen != 0);
+
+            return result;
+        }
+
+        public static string EncodeXml(this string value)
+        {
+            return value.Replace("<", "<").Replace(">", ">").Replace("&", "&");
+        }
+
+        public static string EncodeJson(this string value)
+        {
+            return string.Concat
+            ("\"",
+                value.Replace("\\", "\\\\").Replace("\"", "\\\"").Replace("\r", "").Replace("\n", "\\n"),
+                "\""
+            );
+        }
+
+        public static string EncodeJsv(this string value)
+        {
+            return value.ToCsvField();
+        }
+
+        public static string UrlEncode(this string text)
+        {
+            if (string.IsNullOrEmpty(text)) return text;
+
+            var sb = new StringBuilder();
+
+            var textLength = text.Length;
+            for (var i = 0; i < textLength; i++)
+            {
+                var c = text.Substring(i, 1);
+                int charCode = text[i];
+
+                if (
+                    charCode >= 65 && charCode <= 90		// A-Z
+                    || charCode >= 97 && charCode <= 122    // a-z
+                    || charCode >= 48 && charCode <= 57		// 0-9
+                    || charCode >= 44 && charCode <= 46		// ,-.
+                    )
+                {
+                    sb.Append(c);
+                }
+                else
+                {
+                    sb.Append('%' + charCode.ToString("x"));
+                }
+            }
+            return sb.ToString();
+        }
+
+        public static string UrlDecode(this string text)
+        {
+            if (string.IsNullOrEmpty(text)) return null;
+
+            var sb = new StringBuilder();
+
+            var textLength = text.Length;
+            for (var i = 0; i < textLength; i++)
+            {
+                var c = text.Substring(i, 1);
+                if (c == "+")
+                {
+                    sb.Append(" ");
+                }
+                else if (c == "%")
+                {
+                    var hexNo = Convert.ToInt32(text.Substring(i + 1, 2), 16);
+                    sb.Append((char)hexNo);
+                    i += 2;
+                }
+                else
+                {
+                    sb.Append(c);
+                }
+            }
+
+            return sb.ToString();
+        }
+
+#if !XBOX
+        public static string HexEscape(this string text, params char[] anyCharOf)
+        {
+            if (string.IsNullOrEmpty(text)) return text;
+            if (anyCharOf == null || anyCharOf.Length == 0) return text;
+
+            var encodeCharMap = new HashSet<char>(anyCharOf);
+
+            var sb = new StringBuilder();
+            var textLength = text.Length;
+            for (var i = 0; i < textLength; i++)
+            {
+                var c = text[i];
+                if (encodeCharMap.Contains(c))
+                {
+                    sb.Append('%' + ((int)c).ToString("x"));
+                }
+                else
+                {
+                    sb.Append(c);
+                }
+            }
+            return sb.ToString();
+        }
+#endif
+        public static string HexUnescape(this string text, params char[] anyCharOf)
+        {
+            if (string.IsNullOrEmpty(text)) return null;
+            if (anyCharOf == null || anyCharOf.Length == 0) return text;
+
+            var sb = new StringBuilder();
+
+            var textLength = text.Length;
+            for (var i = 0; i < textLength; i++)
+            {
+                var c = text.Substring(i, 1);
+                if (c == "%")
+                {
+                    var hexNo = Convert.ToInt32(text.Substring(i + 1, 2), 16);
+                    sb.Append((char)hexNo);
+                    i += 2;
+                }
+                else
+                {
+                    sb.Append(c);
+                }
+            }
+
+            return sb.ToString();
+        }
+
+        public static string UrlFormat(this string url, params string[] urlComponents)
+        {
+            var encodedUrlComponents = new string[urlComponents.Length];
+            for (var i = 0; i < urlComponents.Length; i++)
+            {
+                var x = urlComponents[i];
+                encodedUrlComponents[i] = x.UrlEncode();
+            }
+
+            return string.Format(url, encodedUrlComponents);
+        }
+
+        public static string ToRot13(this string value)
+        {
+            var array = value.ToCharArray();
+            for (var i = 0; i < array.Length; i++)
+            {
+                var number = (int)array[i];
+
+                if (number >= 'a' && number <= 'z')
+                    number += (number > 'm') ? -13 : 13;
+
+                else if (number >= 'A' && number <= 'Z')
+                    number += (number > 'M') ? -13 : 13;
+
+                array[i] = (char)number;
+            }
+            return new string(array);
+        }
+
+        public static string WithTrailingSlash(this string path)
+        {
+            if (string.IsNullOrEmpty(path))
+                throw new ArgumentNullException("path");
+
+            if (path[path.Length - 1] != '/')
+            {
+                return path + "/";
+            }
+            return path;
+        }
+
+        public static string AppendUrlPaths(this string uri, params string[] uriComponents)
+        {
+            var sb = new StringBuilder(uri.WithTrailingSlash());
+            var i = 0;
+            foreach (var uriComponent in uriComponents)
+            {
+                if (i++ > 0) sb.Append('/');
+                sb.Append(uriComponent.UrlEncode());
+            }
+            return sb.ToString();
+        }
+
+        public static string FromUtf8Bytes(this byte[] bytes)
+        {
+            return bytes == null ? null
+                : Encoding.UTF8.GetString(bytes, 0, bytes.Length);
+        }
+
+        public static byte[] ToUtf8Bytes(this string value)
+        {
+            return Encoding.UTF8.GetBytes(value);
+        }
+
+        public static byte[] ToUtf8Bytes(this int intVal)
+        {
+            return FastToUtf8Bytes(intVal.ToString());
+        }
+
+        public static byte[] ToUtf8Bytes(this long longVal)
+        {
+            return FastToUtf8Bytes(longVal.ToString());
+        }
+
+        public static byte[] ToUtf8Bytes(this double doubleVal)
+        {
+            var doubleStr = doubleVal.ToString(CultureInfo.InvariantCulture.NumberFormat);
+
+            if (doubleStr.IndexOf('E') != -1 || doubleStr.IndexOf('e') != -1)
+                doubleStr = DoubleConverter.ToExactString(doubleVal);
+
+            return FastToUtf8Bytes(doubleStr);
+        }
+
+        /// <summary>
+        /// Skip the encoding process for 'safe strings' 
+        /// </summary>
+        /// <param name="strVal"></param>
+        /// <returns></returns>
+        private static byte[] FastToUtf8Bytes(string strVal)
+        {
+            var bytes = new byte[strVal.Length];
+            for (var i = 0; i < strVal.Length; i++)
+                bytes[i] = (byte)strVal[i];
+
+            return bytes;
+        }
+
+        public static string[] SplitOnFirst(this string strVal, char needle)
+        {
+            if (strVal == null) return new string[0];
+            var pos = strVal.IndexOf(needle);
+            return pos == -1
+                ? new[] { strVal }
+                : new[] { strVal.Substring(0, pos), strVal.Substring(pos + 1) };
+        }
+
+        public static string[] SplitOnFirst(this string strVal, string needle)
+        {
+            if (strVal == null) return new string[0];
+            var pos = strVal.IndexOf(needle);
+            return pos == -1
+                ? new[] { strVal }
+                : new[] { strVal.Substring(0, pos), strVal.Substring(pos + 1) };
+        }
+
+        public static string[] SplitOnLast(this string strVal, char needle)
+        {
+            if (strVal == null) return new string[0];
+            var pos = strVal.LastIndexOf(needle);
+            return pos == -1
+                ? new[] { strVal }
+                : new[] { strVal.Substring(0, pos), strVal.Substring(pos + 1) };
+        }
+
+        public static string[] SplitOnLast(this string strVal, string needle)
+        {
+            if (strVal == null) return new string[0];
+            var pos = strVal.LastIndexOf(needle);
+            return pos == -1
+                ? new[] { strVal }
+                : new[] { strVal.Substring(0, pos), strVal.Substring(pos + 1) };
+        }
+
+        public static string WithoutExtension(this string filePath)
+        {
+            if (string.IsNullOrEmpty(filePath)) return null;
+
+            var extPos = filePath.LastIndexOf('.');
+            if (extPos == -1) return filePath;
+
+            var dirPos = filePath.LastIndexOfAny(DirSeps);
+            return extPos > dirPos ? filePath.Substring(0, extPos) : filePath;
+        }
+
+        private static readonly char DirSep = Path.DirectorySeparatorChar;
+        private static readonly char AltDirSep = Path.DirectorySeparatorChar == '/' ? '\\' : '/';
+        static readonly char[] DirSeps = new[] { '\\', '/' };
+
+        public static string ParentDirectory(this string filePath)
+        {
+            if (string.IsNullOrEmpty(filePath)) return null;
+
+            var dirSep = filePath.IndexOf(DirSep) != -1
+                         ? DirSep
+                         : filePath.IndexOf(AltDirSep) != -1 ? AltDirSep : (char)0;
+
+            return dirSep == 0 ? null : filePath.TrimEnd(dirSep).SplitOnLast(dirSep)[0];
+        }
+
+        public static string ToJsv<T>(this T obj)
+        {
+            return TypeSerializer.SerializeToString<T>(obj);
+        }
+
+        public static T FromJsv<T>(this string jsv)
+        {
+            return TypeSerializer.DeserializeFromString<T>(jsv);
+        }
+
+        public static string ToJson<T>(this T obj)
+        {
+            return JsonSerializer.SerializeToString<T>(obj);
+        }
+
+        public static T FromJson<T>(this string json)
+        {
+            return JsonSerializer.DeserializeFromString<T>(json);
+        }
+
+#if !XBOX && !SILVERLIGHT
+		public static string ToXml<T>(this T obj)
+		{
+			return XmlSerializer.SerializeToString<T>(obj);
+		}
+#endif
+
+#if !XBOX && !SILVERLIGHT
+        public static T FromXml<T>(this string json)
+		{
+			return XmlSerializer.DeserializeFromString<T>(json);
+		}
+#endif
+        public static string FormatWith(this string text, params object[] args)
+        {
+            return string.Format(text, args);
+        }
+
+        public static string Fmt(this string text, params object[] args)
+        {
+            return string.Format(text, args);
+        }
+
+        public static bool StartsWithIgnoreCase(this string text, string startsWith)
+        {
+            return text != null
+                && text.StartsWith(startsWith, StringComparison.InvariantCultureIgnoreCase);
+        }
+
+        public static string ReadAllText(this string filePath)
+        {
+#if XBOX && !SILVERLIGHT
+			using( var fileStream = new FileStream( filePath, FileMode.Open, FileAccess.Read ) )
+			{
+				return new StreamReader( fileStream ).ReadToEnd( ) ;
+			}
+#else
+            return File.ReadAllText(filePath);
+#endif
+
+        }
+
+        public static int IndexOfAny(this string text, params string[] needles)
+        {
+            return IndexOfAny(text, 0, needles);
+        }
+
+        public static int IndexOfAny(this string text, int startIndex, params string[] needles)
+        {
+            if (text == null) return -1;
+
+            var firstPos = -1;
+            foreach (var needle in needles)
+            {
+                var pos = text.IndexOf(needle);
+                if (firstPos == -1 || pos < firstPos) firstPos = pos;
+            }
+            return firstPos;
+        }
+
+        public static string ExtractContents(this string fromText, string startAfter, string endAt)
+        {
+            return ExtractContents(fromText, startAfter, startAfter, endAt);
+        }
+
+        public static string ExtractContents(this string fromText, string uniqueMarker, string startAfter, string endAt)
+        {
+            if (string.IsNullOrEmpty(uniqueMarker))
+                throw new ArgumentNullException("uniqueMarker");
+            if (string.IsNullOrEmpty(startAfter))
+                throw new ArgumentNullException("startAfter");
+            if (string.IsNullOrEmpty(endAt))
+                throw new ArgumentNullException("endAt");
+
+            if (string.IsNullOrEmpty(fromText)) return null;
+
+            var markerPos = fromText.IndexOf(uniqueMarker);
+            if (markerPos == -1) return null;
+
+            var startPos = fromText.IndexOf(startAfter, markerPos);
+            if (startPos == -1) return null;
+            startPos += startAfter.Length;
+
+            var endPos = fromText.IndexOf(endAt, startPos);
+            if (endPos == -1) endPos = fromText.Length;
+
+            return fromText.Substring(startPos, endPos - startPos);
+        }
+
+#if XBOX && !SILVERLIGHT
+		static readonly Regex StripHtmlRegEx = new Regex(@"<(.|\n)*?>", RegexOptions.Compiled);
+#else
+        static readonly Regex StripHtmlRegEx = new Regex(@"<(.|\n)*?>");
+#endif
+        public static string StripHtml(this string html)
+        {
+            return string.IsNullOrEmpty(html) ? null : StripHtmlRegEx.Replace(html, "");
+        }
+
+#if XBOX && !SILVERLIGHT
+		static readonly Regex StripBracketsRegEx = new Regex(@"\[(.|\n)*?\]", RegexOptions.Compiled);
+		static readonly Regex StripBracesRegEx = new Regex(@"\((.|\n)*?\)", RegexOptions.Compiled);
+#else
+        static readonly Regex StripBracketsRegEx = new Regex(@"\[(.|\n)*?\]");
+        static readonly Regex StripBracesRegEx = new Regex(@"\((.|\n)*?\)");
+#endif
+        public static string StripMarkdownMarkup(this string markdown)
+        {
+            if (string.IsNullOrEmpty(markdown)) return null;
+            markdown = StripBracketsRegEx.Replace(markdown, "");
+            markdown = StripBracesRegEx.Replace(markdown, "");
+            markdown = markdown
+                .Replace("*", "")
+                .Replace("!", "")
+                .Replace("\r", "")
+                .Replace("\n", "")
+                .Replace("#", "");
+
+            return markdown;
+        }
+
+        private const int LowerCaseOffset = 'a' - 'A';
+        public static string ToCamelCase(this string value)
+        {
+            if (string.IsNullOrEmpty(value)) return value;
+
+            var firstChar = value[0];
+            if (firstChar < 'A' || firstChar > 'Z')
+                return value;
+
+            return (char)(firstChar + LowerCaseOffset) + value.Substring(1);
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Support/AssemblyTypeDefinition.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Support/AssemblyTypeDefinition.cs
new file mode 100644
index 0000000..7d7651d
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Support/AssemblyTypeDefinition.cs
@@ -0,0 +1,26 @@
+using System;
+
+namespace ServiceStack.Common.Support
+{
+	internal class AssemblyTypeDefinition
+	{
+		private const char TypeDefinitionSeperator = ',';
+		private const int TypeNameIndex = 0;
+		private const int AssemblyNameIndex = 1;
+
+		public AssemblyTypeDefinition(string typeDefinition)
+		{
+			if (string.IsNullOrEmpty(typeDefinition))
+			{
+				throw new ArgumentNullException();
+			}
+			var parts = typeDefinition.Split(TypeDefinitionSeperator);
+			TypeName = parts[TypeNameIndex].Trim();
+			AssemblyName = (parts.Length > AssemblyNameIndex) ? parts[AssemblyNameIndex].Trim() : null;
+		}
+
+		public string TypeName { get; set; }
+
+		public string AssemblyName { get; set; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Support/DoubleConverter.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Support/DoubleConverter.cs
new file mode 100644
index 0000000..3348747
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Support/DoubleConverter.cs
@@ -0,0 +1,226 @@
+namespace ServiceStack.Text.Support
+{
+	using System;
+	using System.Globalization;
+
+	/// <summary>
+	/// A class to allow the conversion of doubles to string representations of
+	/// their exact decimal values. The implementation aims for readability over
+	/// efficiency.
+	/// 
+	/// Courtesy of @JonSkeet
+	/// http://www.yoda.arachsys.com/csharp/DoubleConverter.cs
+	/// </summary>
+	public class DoubleConverter
+	{
+		/// <summary>
+		/// Converts the given double to a string representation of its
+		/// exact decimal value.
+		/// </summary>
+		/// <param name="d">The double to convert.</param>
+		/// <returns>A string representation of the double's exact decimal value.</return>
+		public static string ToExactString(double d)
+		{
+#if XBOX
+			return BitConverter.ToString( BitConverter.GetBytes( d ) ) ;
+#else
+			if (double.IsPositiveInfinity(d))
+				return "+Infinity";
+			if (double.IsNegativeInfinity(d))
+				return "-Infinity";
+			if (double.IsNaN(d))
+				return "NaN";
+
+			// Translate the double into sign, exponent and mantissa.
+			long bits = BitConverter.DoubleToInt64Bits(d);
+			// Note that the shift is sign-extended, hence the test against -1 not 1
+			bool negative = (bits < 0);
+			int exponent = (int)((bits >> 52) & 0x7ffL);
+			long mantissa = bits & 0xfffffffffffffL;
+
+			// Subnormal numbers; exponent is effectively one higher,
+			// but there's no extra normalisation bit in the mantissa
+			if (exponent == 0)
+			{
+				exponent++;
+			}
+			// Normal numbers; leave exponent as it is but add extra
+			// bit to the front of the mantissa
+			else
+			{
+				mantissa = mantissa | (1L << 52);
+			}
+
+			// Bias the exponent. It's actually biased by 1023, but we're
+			// treating the mantissa as m.0 rather than 0.m, so we need
+			// to subtract another 52 from it.
+			exponent -= 1075;
+
+			if (mantissa == 0)
+			{
+				return "0";
+			}
+
+			/* Normalize */
+			while ((mantissa & 1) == 0)
+			{    /*  i.e., Mantissa is even */
+				mantissa >>= 1;
+				exponent++;
+			}
+
+			/// Construct a new decimal expansion with the mantissa
+			ArbitraryDecimal ad = new ArbitraryDecimal(mantissa);
+
+			// If the exponent is less than 0, we need to repeatedly
+			// divide by 2 - which is the equivalent of multiplying
+			// by 5 and dividing by 10.
+			if (exponent < 0)
+			{
+				for (int i = 0; i < -exponent; i++)
+					ad.MultiplyBy(5);
+				ad.Shift(-exponent);
+			}
+			// Otherwise, we need to repeatedly multiply by 2
+			else
+			{
+				for (int i = 0; i < exponent; i++)
+					ad.MultiplyBy(2);
+			}
+
+			// Finally, return the string with an appropriate sign
+			if (negative)
+				return "-" + ad.ToString();
+			else
+				return ad.ToString();
+#endif
+		}
+
+		/// <summary>Private class used for manipulating
+		class ArbitraryDecimal
+		{
+			/// <summary>Digits in the decimal expansion, one byte per digit
+			byte[] digits;
+			/// <summary> 
+			/// How many digits are *after* the decimal point
+			/// </summary>
+			int decimalPoint = 0;
+
+			/// <summary> 
+			/// Constructs an arbitrary decimal expansion from the given long.
+			/// The long must not be negative.
+			/// </summary>
+			internal ArbitraryDecimal(long x)
+			{
+				string tmp = x.ToString(CultureInfo.InvariantCulture);
+				digits = new byte[tmp.Length];
+				for (int i = 0; i < tmp.Length; i++)
+					digits[i] = (byte)(tmp[i] - '0');
+				Normalize();
+			}
+
+			/// <summary>
+			/// Multiplies the current expansion by the given amount, which should
+			/// only be 2 or 5.
+			/// </summary>
+			internal void MultiplyBy(int amount)
+			{
+				byte[] result = new byte[digits.Length + 1];
+				for (int i = digits.Length - 1; i >= 0; i--)
+				{
+					int resultDigit = digits[i] * amount + result[i + 1];
+					result[i] = (byte)(resultDigit / 10);
+					result[i + 1] = (byte)(resultDigit % 10);
+				}
+				if (result[0] != 0)
+				{
+					digits = result;
+				}
+				else
+				{
+					Array.Copy(result, 1, digits, 0, digits.Length);
+				}
+				Normalize();
+			}
+
+			/// <summary>
+			/// Shifts the decimal point; a negative value makes
+			/// the decimal expansion bigger (as fewer digits come after the
+			/// decimal place) and a positive value makes the decimal
+			/// expansion smaller.
+			/// </summary>
+			internal void Shift(int amount)
+			{
+				decimalPoint += amount;
+			}
+
+			/// <summary>
+			/// Removes leading/trailing zeroes from the expansion.
+			/// </summary>
+			internal void Normalize()
+			{
+				int first;
+				for (first = 0; first < digits.Length; first++)
+					if (digits[first] != 0)
+						break;
+				int last;
+				for (last = digits.Length - 1; last >= 0; last--)
+					if (digits[last] != 0)
+						break;
+
+				if (first == 0 && last == digits.Length - 1)
+					return;
+
+				byte[] tmp = new byte[last - first + 1];
+				for (int i = 0; i < tmp.Length; i++)
+					tmp[i] = digits[i + first];
+
+				decimalPoint -= digits.Length - (last + 1);
+				digits = tmp;
+			}
+
+			/// <summary>
+			/// Converts the value to a proper decimal string representation.
+			/// </summary>
+			public override String ToString()
+			{
+				char[] digitString = new char[digits.Length];
+				for (int i = 0; i < digits.Length; i++)
+					digitString[i] = (char)(digits[i] + '0');
+
+				// Simplest case - nothing after the decimal point,
+				// and last real digit is non-zero, eg value=35
+				if (decimalPoint == 0)
+				{
+					return new string(digitString);
+				}
+
+				// Fairly simple case - nothing after the decimal
+				// point, but some 0s to add, eg value=350
+				if (decimalPoint < 0)
+				{
+					return new string(digitString) +
+						   new string('0', -decimalPoint);
+				}
+
+				// Nothing before the decimal point, eg 0.035
+				if (decimalPoint >= digitString.Length)
+				{
+					return "0." +
+						new string('0', (decimalPoint - digitString.Length)) +
+						new string(digitString);
+				}
+
+				// Most complicated case - part of the string comes
+				// before the decimal point, part comes after it,
+				// eg 3.5
+				return new string(digitString, 0,
+								   digitString.Length - decimalPoint) +
+					"." +
+					new string(digitString,
+								digitString.Length - decimalPoint,
+								decimalPoint);
+			}
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Support/TypePair.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Support/TypePair.cs
new file mode 100644
index 0000000..9d1f70f
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Support/TypePair.cs
@@ -0,0 +1,51 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+
+namespace ServiceStack.Text.Support
+{
+	public class TypePair
+	{
+		public Type[] Args1 { get; set; }
+		public Type[] Arg2 { get; set; }
+
+		public TypePair(Type[] arg1, Type[] arg2)
+		{
+			Args1 = arg1;
+			Arg2 = arg2;
+		}
+
+		public bool Equals(TypePair other)
+		{
+			if (ReferenceEquals(null, other)) return false;
+			if (ReferenceEquals(this, other)) return true;
+			return Equals(other.Args1, Args1) && Equals(other.Arg2, Arg2);
+		}
+
+		public override bool Equals(object obj)
+		{
+			if (ReferenceEquals(null, obj)) return false;
+			if (ReferenceEquals(this, obj)) return true;
+			if (obj.GetType() != typeof (TypePair)) return false;
+			return Equals((TypePair) obj);
+		}
+
+		public override int GetHashCode()
+		{
+			unchecked
+			{
+				return ((Args1 != null ? Args1.GetHashCode() : 0)*397) ^ (Arg2 != null ? Arg2.GetHashCode() : 0);
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/TextExtensions.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/TextExtensions.cs
new file mode 100644
index 0000000..041cce4
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/TextExtensions.cs
@@ -0,0 +1,70 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using ServiceStack.Text.Common;
+
+namespace ServiceStack.Text
+{
+	public static class TextExtensions
+	{
+		public static string ToCsvField(this string text)
+		{
+			return string.IsNullOrEmpty(text) || !JsWriter.HasAnyEscapeChars(text)
+		       	? text
+		       	: string.Concat
+		       	  	(
+						JsWriter.QuoteString,
+						text.Replace(JsWriter.QuoteString, TypeSerializer.DoubleQuoteString),
+						JsWriter.QuoteString
+		       	  	);
+		}
+
+		public static string FromCsvField(this string text)
+		{
+			const int startingQuotePos = 1;
+			const int endingQuotePos = 2;
+			return string.IsNullOrEmpty(text) || text[0] != JsWriter.QuoteChar
+			       	? text
+					: text.Substring(startingQuotePos, text.Length - endingQuotePos)
+						.Replace(TypeSerializer.DoubleQuoteString, JsWriter.QuoteString);
+		}
+
+		public static List<string> FromCsvFields(this IEnumerable<string> texts)
+		{
+			var safeTexts = new List<string>();
+			foreach (var text in texts)
+			{
+				safeTexts.Add(FromCsvField(text));
+			}
+			return safeTexts;
+		}
+
+		public static string[] FromCsvFields(params string[] texts)
+		{
+			var textsLen = texts.Length;
+			var safeTexts = new string[textsLen];
+			for (var i = 0; i < textsLen; i++)
+			{
+				safeTexts[i] = FromCsvField(texts[i]);
+			}
+			return safeTexts;
+		}
+
+		public static string SerializeToString<T>(this T value)
+		{
+			return JsonSerializer.SerializeToString(value);
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/Tracer.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/Tracer.cs
new file mode 100644
index 0000000..5cfc0c5
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/Tracer.cs
@@ -0,0 +1,65 @@
+using System;
+
+namespace ServiceStack.Text
+{
+	public class Tracer
+	{
+		public static ITracer Instance = new NullTracer();
+
+		public class NullTracer : ITracer
+		{
+			public void WriteDebug(string error) { }
+
+			public void WriteDebug(string format, params object[] args) { }
+		    
+            public void WriteWarning(string warning) { }
+
+		    public void WriteWarning(string format, params object[] args) { }
+
+		    public void WriteError(Exception ex) { }
+
+			public void WriteError(string error) { }
+
+			public void WriteError(string format, params object[] args) { }
+
+		}
+
+		public class ConsoleTracer : ITracer
+		{
+			public void WriteDebug(string error)
+			{
+				Console.WriteLine(error);
+			}
+
+			public void WriteDebug(string format, params object[] args)
+			{
+				Console.WriteLine(format, args);
+			}
+
+		    public void WriteWarning(string warning)
+		    {
+                Console.WriteLine(warning);                
+		    }
+
+		    public void WriteWarning(string format, params object[] args)
+		    {
+                Console.WriteLine(format, args);
+            }
+
+		    public void WriteError(Exception ex)
+			{
+				Console.WriteLine(ex);
+			}
+
+			public void WriteError(string error)
+			{
+				Console.WriteLine(error);
+			}
+
+			public void WriteError(string format, params object[] args)
+			{
+				Console.WriteLine(format, args);
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/TranslateListWithElements.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/TranslateListWithElements.cs
new file mode 100644
index 0000000..2d823d0
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/TranslateListWithElements.cs
@@ -0,0 +1,234 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Threading;
+using ServiceStack.Text.Common;
+
+namespace ServiceStack.Text
+{
+	public static class TranslateListWithElements
+	{
+        private static Dictionary<Type, ConvertInstanceDelegate> TranslateICollectionCache
+            = new Dictionary<Type, ConvertInstanceDelegate>();
+
+		public static object TranslateToGenericICollectionCache(object from, Type toInstanceOfType, Type elementType)
+		{
+            ConvertInstanceDelegate translateToFn;
+            if (TranslateICollectionCache.TryGetValue(toInstanceOfType, out translateToFn))
+                return translateToFn(from, toInstanceOfType);
+
+            var genericType = typeof(TranslateListWithElements<>).MakeGenericType(elementType);
+            var mi = genericType.GetMethod("LateBoundTranslateToGenericICollection", BindingFlags.Static | BindingFlags.Public);
+            translateToFn = (ConvertInstanceDelegate)Delegate.CreateDelegate(typeof(ConvertInstanceDelegate), mi);
+
+            Dictionary<Type, ConvertInstanceDelegate> snapshot, newCache;
+            do
+            {
+                snapshot = TranslateICollectionCache;
+                newCache = new Dictionary<Type, ConvertInstanceDelegate>(TranslateICollectionCache);
+                newCache[elementType] = translateToFn;
+
+            } while (!ReferenceEquals(
+                Interlocked.CompareExchange(ref TranslateICollectionCache, newCache, snapshot), snapshot));
+
+			return translateToFn(from, toInstanceOfType);
+		}
+
+        private static Dictionary<ConvertibleTypeKey, ConvertInstanceDelegate> TranslateConvertibleICollectionCache
+            = new Dictionary<ConvertibleTypeKey, ConvertInstanceDelegate>();
+
+		public static object TranslateToConvertibleGenericICollectionCache(
+			object from, Type toInstanceOfType, Type fromElementType)
+		{
+			var typeKey = new ConvertibleTypeKey(toInstanceOfType, fromElementType);
+            ConvertInstanceDelegate translateToFn;
+            if (TranslateConvertibleICollectionCache.TryGetValue(typeKey, out translateToFn)) return translateToFn(from, toInstanceOfType);
+
+            var toElementType = toInstanceOfType.GetGenericType().GetGenericArguments()[0];
+            var genericType = typeof(TranslateListWithConvertibleElements<,>).MakeGenericType(fromElementType, toElementType);
+            var mi = genericType.GetMethod("LateBoundTranslateToGenericICollection", BindingFlags.Static | BindingFlags.Public);
+            translateToFn = (ConvertInstanceDelegate)Delegate.CreateDelegate(typeof(ConvertInstanceDelegate), mi);
+
+            Dictionary<ConvertibleTypeKey, ConvertInstanceDelegate> snapshot, newCache;
+            do
+            {
+                snapshot = TranslateConvertibleICollectionCache;
+                newCache = new Dictionary<ConvertibleTypeKey, ConvertInstanceDelegate>(TranslateConvertibleICollectionCache);
+                newCache[typeKey] = translateToFn;
+
+            } while (!ReferenceEquals(
+                Interlocked.CompareExchange(ref TranslateConvertibleICollectionCache, newCache, snapshot), snapshot));
+            
+            return translateToFn(from, toInstanceOfType);
+		}
+
+		public static object TryTranslateToGenericICollection(Type fromPropertyType, Type toPropertyType, object fromValue)
+		{
+			var args = typeof(ICollection<>).GetGenericArgumentsIfBothHaveSameGenericDefinitionTypeAndArguments(
+				fromPropertyType, toPropertyType);
+
+			if (args != null)
+			{
+				return TranslateToGenericICollectionCache(
+					fromValue, toPropertyType, args[0]);
+			}
+
+			var varArgs = typeof(ICollection<>).GetGenericArgumentsIfBothHaveConvertibleGenericDefinitionTypeAndArguments(
+			fromPropertyType, toPropertyType);
+
+			if (varArgs != null)
+			{
+				return TranslateToConvertibleGenericICollectionCache(
+					fromValue, toPropertyType, varArgs.Args1[0]);
+			}
+
+			return null;
+		}
+
+	}
+
+	public class ConvertibleTypeKey
+	{
+		public Type ToInstanceType { get; set; }
+		public Type FromElemenetType { get; set; }
+
+		public ConvertibleTypeKey()
+		{
+		}
+
+		public ConvertibleTypeKey(Type toInstanceType, Type fromElemenetType)
+		{
+			ToInstanceType = toInstanceType;
+			FromElemenetType = fromElemenetType;
+		}
+
+		public bool Equals(ConvertibleTypeKey other)
+		{
+			if (ReferenceEquals(null, other)) return false;
+			if (ReferenceEquals(this, other)) return true;
+			return Equals(other.ToInstanceType, ToInstanceType) && Equals(other.FromElemenetType, FromElemenetType);
+		}
+
+		public override bool Equals(object obj)
+		{
+			if (ReferenceEquals(null, obj)) return false;
+			if (ReferenceEquals(this, obj)) return true;
+			if (obj.GetType() != typeof(ConvertibleTypeKey)) return false;
+			return Equals((ConvertibleTypeKey)obj);
+		}
+
+		public override int GetHashCode()
+		{
+			unchecked
+			{
+				return ((ToInstanceType != null ? ToInstanceType.GetHashCode() : 0) * 397)
+					^ (FromElemenetType != null ? FromElemenetType.GetHashCode() : 0);
+			}
+		}
+	}
+
+	public class TranslateListWithElements<T>
+	{
+		public static object CreateInstance(Type toInstanceOfType)
+		{
+			if (toInstanceOfType.IsGenericType)
+			{
+				if (toInstanceOfType.HasAnyTypeDefinitionsOf(
+					typeof(ICollection<>), typeof(IList<>)))
+				{
+					return ReflectionExtensions.CreateInstance(typeof(List<T>));
+				}
+			}
+
+			return ReflectionExtensions.CreateInstance(toInstanceOfType);
+		}
+
+		public static IList TranslateToIList(IList fromList, Type toInstanceOfType)
+		{
+			var to = (IList)ReflectionExtensions.CreateInstance(toInstanceOfType);
+			foreach (var item in fromList)
+			{
+				to.Add(item);
+			}
+			return to;
+		}
+
+		public static object LateBoundTranslateToGenericICollection(
+			object fromList, Type toInstanceOfType)
+		{
+			if (fromList == null) return null; //AOT
+
+			return TranslateToGenericICollection(
+				(ICollection<T>)fromList, toInstanceOfType);
+		}
+
+		public static ICollection<T> TranslateToGenericICollection(
+			ICollection<T> fromList, Type toInstanceOfType)
+		{
+			var to = (ICollection<T>)CreateInstance(toInstanceOfType);
+			foreach (var item in fromList)
+			{
+				to.Add(item);
+			}
+			return to;
+		}
+	}
+
+	public class TranslateListWithConvertibleElements<TFrom, TTo>
+	{
+		private static readonly Func<TFrom, TTo> ConvertFn;
+
+		static TranslateListWithConvertibleElements()
+		{
+			ConvertFn = GetConvertFn();
+		}
+
+		public static object LateBoundTranslateToGenericICollection(
+			object fromList, Type toInstanceOfType)
+		{
+			return TranslateToGenericICollection(
+				(ICollection<TFrom>)fromList, toInstanceOfType);
+		}
+
+		public static ICollection<TTo> TranslateToGenericICollection(
+			ICollection<TFrom> fromList, Type toInstanceOfType)
+		{
+			if (fromList == null) return null; //AOT
+
+			var to = (ICollection<TTo>)TranslateListWithElements<TTo>.CreateInstance(toInstanceOfType);
+
+			foreach (var item in fromList)
+			{
+				var toItem = ConvertFn(item);
+				to.Add(toItem);
+			}
+			return to;
+		}
+
+		private static Func<TFrom, TTo> GetConvertFn()
+		{
+			if (typeof(TTo) == typeof(string))
+			{
+				return x => (TTo)(object)TypeSerializer.SerializeToString(x);
+			}
+			if (typeof(TFrom) == typeof(string))
+			{
+				return x => TypeSerializer.DeserializeFromString<TTo>((string)(object)x);
+			}
+			return x => TypeSerializer.DeserializeFromString<TTo>(TypeSerializer.SerializeToString(x));
+		}
+	}
+}
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/TypeConfig.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/TypeConfig.cs
new file mode 100644
index 0000000..66db707
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/TypeConfig.cs
@@ -0,0 +1,53 @@
+using System;
+using System.Linq;
+using System.Reflection;
+
+namespace ServiceStack.Text
+{
+	internal class TypeConfig
+	{
+		internal readonly Type Type;
+		internal bool EnableAnonymousFieldSetterses;
+		internal PropertyInfo[] Properties;
+
+		internal TypeConfig(Type type)
+		{
+			Type = type;
+			EnableAnonymousFieldSetterses = false;
+			Properties = new PropertyInfo[0];
+		}
+	}
+
+	public static class TypeConfig<T>
+	{
+		private static readonly TypeConfig config;
+
+		public static PropertyInfo[] Properties
+		{
+			get { return config.Properties; }
+			set { config.Properties = value; }
+		}
+
+		public static bool EnableAnonymousFieldSetters
+		{
+			get { return config.EnableAnonymousFieldSetterses; }
+			set { config.EnableAnonymousFieldSetterses = value; }
+		}
+
+		static TypeConfig()
+		{
+			config = new TypeConfig(typeof(T));
+			
+			var excludedProperties = JsConfig<T>.ExcludePropertyNames ?? new string[0];
+			var properties = excludedProperties.Any() 
+				? config.Type.GetSerializableProperties().Where(x => !excludedProperties.Contains(x.Name))
+				: config.Type.GetSerializableProperties();
+			Properties = properties.Where(x => x.GetIndexParameters().Length == 0).ToArray();
+		}
+
+		internal static TypeConfig GetState()
+		{
+			return config;
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/TypeSerializer.Generic.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/TypeSerializer.Generic.cs
new file mode 100644
index 0000000..dbb3530
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/TypeSerializer.Generic.cs
@@ -0,0 +1,68 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.IO;
+using System.Text;
+using ServiceStack.Text.Jsv;
+
+namespace ServiceStack.Text
+{
+	public class TypeSerializer<T> : ITypeSerializer<T>
+	{
+		public bool CanCreateFromString(Type type)
+		{
+			return JsvReader.GetParseFn(type) != null;
+		}
+
+		/// <summary>
+		/// Parses the specified value.
+		/// </summary>
+		/// <param name="value">The value.</param>
+		/// <returns></returns>
+		public T DeserializeFromString(string value)
+		{
+			if (string.IsNullOrEmpty(value)) return default(T);
+			return (T)JsvReader<T>.Parse(value);
+		}
+
+		public T DeserializeFromReader(TextReader reader)
+		{
+			return DeserializeFromString(reader.ReadToEnd());
+		}
+
+		public string SerializeToString(T value)
+		{
+			if (value == null) return null;
+			if (typeof(T) == typeof(string)) return value as string;
+
+			var sb = new StringBuilder();
+			using (var writer = new StringWriter(sb))
+			{
+				JsvWriter<T>.WriteObject(writer, value);
+			}
+			return sb.ToString();
+		}
+
+		public void SerializeToWriter(T value, TextWriter writer)
+		{
+			if (value == null) return;
+			if (typeof(T) == typeof(string))
+			{
+				writer.Write(value);
+				return;
+			}
+
+			JsvWriter<T>.WriteObject(writer, value);
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/TypeSerializer.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/TypeSerializer.cs
new file mode 100644
index 0000000..13b4b01
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/TypeSerializer.cs
@@ -0,0 +1,216 @@
+//
+// http://code.google.com/p/servicestack/wiki/TypeSerializer
+// ServiceStack.Text: .NET C# POCO Type Text Serializer.
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2011 Liquidbit Ltd.
+//
+// Licensed under the same terms of ServiceStack: new BSD license.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Text;
+using ServiceStack.Text.Common;
+using ServiceStack.Text.Jsv;
+
+namespace ServiceStack.Text
+{
+	/// <summary>
+	/// Creates an instance of a Type from a string value
+	/// </summary>
+	public static class TypeSerializer
+	{
+		private static readonly UTF8Encoding UTF8EncodingWithoutBom = new UTF8Encoding(false);
+
+		public const string DoubleQuoteString = "\"\"";
+
+		/// <summary>
+		/// Determines whether the specified type is convertible from string.
+		/// </summary>
+		/// <param name="type">The type.</param>
+		/// <returns>
+		/// 	<c>true</c> if the specified type is convertible from string; otherwise, <c>false</c>.
+		/// </returns>
+		public static bool CanCreateFromString(Type type)
+		{
+			return JsvReader.GetParseFn(type) != null;
+		}
+
+		/// <summary>
+		/// Parses the specified value.
+		/// </summary>
+		/// <param name="value">The value.</param>
+		/// <returns></returns>
+		public static T DeserializeFromString<T>(string value)
+		{
+			if (string.IsNullOrEmpty(value)) return default(T);
+			return (T)JsvReader<T>.Parse(value);
+		}
+
+		public static T DeserializeFromReader<T>(TextReader reader)
+		{
+			return DeserializeFromString<T>(reader.ReadToEnd());
+		}
+
+		/// <summary>
+		/// Parses the specified type.
+		/// </summary>
+		/// <param name="type">The type.</param>
+		/// <param name="value">The value.</param>
+		/// <returns></returns>
+		public static object DeserializeFromString(string value, Type type)
+		{
+			return value == null 
+			       	? null 
+			       	: JsvReader.GetParseFn(type)(value);
+		}
+
+		public static object DeserializeFromReader(TextReader reader, Type type)
+		{
+			return DeserializeFromString(reader.ReadToEnd(), type);
+		}
+
+		public static string SerializeToString<T>(T value)
+		{
+			if (value == null) return null;
+			if (typeof(T) == typeof(string)) return value as string;
+            if (typeof(T) == typeof(object) || typeof(T).IsAbstract || typeof(T).IsInterface)
+            {
+                if (typeof(T).IsAbstract || typeof(T).IsInterface) JsState.IsWritingDynamic = true;
+                var result = SerializeToString(value, value.GetType());
+                if (typeof(T).IsAbstract || typeof(T).IsInterface) JsState.IsWritingDynamic = false;
+                return result;
+            }
+
+			var sb = new StringBuilder();
+			using (var writer = new StringWriter(sb, CultureInfo.InvariantCulture))
+			{
+				JsvWriter<T>.WriteObject(writer, value);
+			}
+			return sb.ToString();
+		}
+
+		public static string SerializeToString(object value, Type type)
+		{
+			if (value == null) return null;
+			if (type == typeof(string)) return value as string;
+
+			var sb = new StringBuilder();
+			using (var writer = new StringWriter(sb, CultureInfo.InvariantCulture))
+			{
+				JsvWriter.GetWriteFn(type)(writer, value);
+			}
+			return sb.ToString();
+		}
+
+		public static void SerializeToWriter<T>(T value, TextWriter writer)
+		{
+			if (value == null) return;
+			if (typeof(T) == typeof(string))
+			{
+				writer.Write(value);
+				return;
+			}
+			if (typeof(T) == typeof(object))
+			{
+                if (typeof(T).IsAbstract || typeof(T).IsInterface) JsState.IsWritingDynamic = true;
+                SerializeToWriter(value, value.GetType(), writer);
+                if (typeof(T).IsAbstract || typeof(T).IsInterface) JsState.IsWritingDynamic = false;
+                return;
+			}
+
+			JsvWriter<T>.WriteObject(writer, value);
+		}
+
+		public static void SerializeToWriter(object value, Type type, TextWriter writer)
+		{
+			if (value == null) return;
+			if (type == typeof(string))
+			{
+				writer.Write(value);
+				return;
+			}
+
+			JsvWriter.GetWriteFn(type)(writer, value);
+		}
+
+		public static void SerializeToStream<T>(T value, Stream stream)
+		{
+			if (value == null) return;
+			if (typeof(T) == typeof(object))
+			{
+                if (typeof(T).IsAbstract || typeof(T).IsInterface) JsState.IsWritingDynamic = true;
+                SerializeToStream(value, value.GetType(), stream);
+                if (typeof(T).IsAbstract || typeof(T).IsInterface) JsState.IsWritingDynamic = false;
+                return;
+			}
+
+			var writer = new StreamWriter(stream, UTF8EncodingWithoutBom);
+			JsvWriter<T>.WriteObject(writer, value);
+			writer.Flush();
+		}
+
+		public static void SerializeToStream(object value, Type type, Stream stream)
+		{
+			var writer = new StreamWriter(stream, UTF8EncodingWithoutBom);
+			JsvWriter.GetWriteFn(type)(writer, value);
+			writer.Flush();
+		}
+
+		public static T Clone<T>(T value)
+		{
+			var serializedValue = SerializeToString(value);
+			var cloneObj = DeserializeFromString<T>(serializedValue);
+			return cloneObj;
+		}
+
+		public static T DeserializeFromStream<T>(Stream stream)
+		{
+			using (var reader = new StreamReader(stream, UTF8EncodingWithoutBom))
+			{
+				return DeserializeFromString<T>(reader.ReadToEnd());
+			}
+		}
+
+		public static object DeserializeFromStream(Type type, Stream stream)
+		{
+			using (var reader = new StreamReader(stream, UTF8EncodingWithoutBom))
+			{
+				return DeserializeFromString(reader.ReadToEnd(), type);
+			}
+		}
+
+		/// <summary>
+		/// Useful extension method to get the Dictionary[string,string] representation of any POCO type.
+		/// </summary>
+		/// <returns></returns>
+		public static Dictionary<string, string> ToStringDictionary<T>(this T obj)
+			where T : class
+		{
+			var jsv = SerializeToString(obj);
+			var map = DeserializeFromString<Dictionary<string, string>>(jsv);
+			return map;
+		}
+		
+		/// <summary>
+		/// Recursively prints the contents of any POCO object in a human-friendly, readable format
+		/// </summary>
+		/// <returns></returns>
+		public static string Dump<T>(this T instance)
+		{
+			return SerializeAndFormat(instance);
+		}
+
+		public static string SerializeAndFormat<T>(this T instance)
+		{
+			var dtoStr = SerializeToString(instance);
+			var formatStr = JsvFormatter.Format(dtoStr);
+			return formatStr;
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack.Text/src/ServiceStack.Text/XmlSerializer.cs b/lib/ServiceStack.Text/src/ServiceStack.Text/XmlSerializer.cs
new file mode 100644
index 0000000..d6c6320
--- /dev/null
+++ b/lib/ServiceStack.Text/src/ServiceStack.Text/XmlSerializer.cs
@@ -0,0 +1,161 @@
+using System;
+using System.IO;
+#if !XBOX360 && !SILVERLIGHT
+using System.IO.Compression;
+#endif
+using System.Runtime.Serialization;
+using System.Text;
+using System.Xml;
+
+namespace ServiceStack.Text
+{
+#if !XBOX 
+    public class XmlSerializer
+    {
+        private readonly XmlDictionaryReaderQuotas quotas;
+        private static readonly XmlWriterSettings XSettings = new XmlWriterSettings();
+
+        public static XmlSerializer Instance
+            = new XmlSerializer(
+#if !SILVERLIGHT
+                new XmlDictionaryReaderQuotas { MaxStringContentLength = 1024 * 1024, }
+#endif
+        );
+
+        public XmlSerializer(XmlDictionaryReaderQuotas quotas=null, bool omitXmlDeclaration = false)
+        {
+            this.quotas = quotas;
+            XSettings.Encoding = Encoding.UTF8;
+            XSettings.OmitXmlDeclaration = omitXmlDeclaration;
+        }
+
+        private static object Deserialize(string xml, Type type, XmlDictionaryReaderQuotas quotas)
+        {
+            try
+            {
+                var bytes = Encoding.UTF8.GetBytes(xml);
+
+                using (var reader = XmlDictionaryReader.CreateTextReader(bytes, quotas))
+                {
+                    var serializer = new DataContractSerializer(type);
+                    return serializer.ReadObject(reader);
+                }
+            }
+            catch (Exception ex)
+            {
+                throw new SerializationException("DeserializeDataContract: Error converting type: " + ex.Message, ex);
+            }
+        }
+
+        public static object DeserializeFromString(string xml, Type type)
+        {
+            return Deserialize(xml, type, Instance.quotas);
+        }
+
+        public static T DeserializeFromString<T>(string xml)
+        {
+            var type = typeof(T);
+            return (T)Deserialize(xml, type, Instance.quotas);
+        }
+
+        public static T DeserializeFromReader<T>(TextReader reader)
+        {
+            return DeserializeFromString<T>(reader.ReadToEnd());
+        }
+
+        public static T DeserializeFromStream<T>(Stream stream)
+        {
+            var serializer = new DataContractSerializer(typeof(T));
+
+            return (T)serializer.ReadObject(stream);
+        }
+
+        public static object DeserializeFromStream(Type type, Stream stream)
+        {
+            var serializer = new DataContractSerializer(type);
+            return serializer.ReadObject(stream);
+        }
+
+        public static string SerializeToString<T>(T from)
+        {
+            try
+            {
+                using (var ms = new MemoryStream())
+                {
+                    using (var xw = XmlWriter.Create(ms, XSettings))
+                    {
+                        var serializer = new DataContractSerializer(from.GetType());
+                        serializer.WriteObject(xw, from);
+                        xw.Flush();
+                        ms.Seek(0, SeekOrigin.Begin);
+                    	var reader = new StreamReader(ms);
+						return reader.ReadToEnd();
+					}
+                }
+            }
+            catch (Exception ex)
+            {
+                throw new SerializationException(string.Format("Error serializing object of type {0}", from.GetType().FullName), ex);
+            }
+        }
+
+		public static void SerializeToWriter<T>(T value, TextWriter writer)
+		{
+			try
+			{
+#if !SILVERLIGHT
+				using (var xw = new XmlTextWriter(writer))
+#else
+                using (var xw = XmlWriter.Create(writer))
+#endif
+				{
+					var serializer = new DataContractSerializer(value.GetType());
+					serializer.WriteObject(xw, value);
+				}
+			}
+			catch (Exception ex)
+			{
+                throw new SerializationException(string.Format("Error serializing object of type {0}", value.GetType().FullName), ex);
+			}
+		}
+
+        public static void SerializeToStream(object obj, Stream stream)
+        {
+#if !SILVERLIGHT
+            using (var xw = new XmlTextWriter(stream, Encoding.UTF8))
+#else
+            using (var xw = XmlWriter.Create(stream))
+#endif
+            {
+                var serializer = new DataContractSerializer(obj.GetType());
+                serializer.WriteObject(xw, obj);
+            }
+        }
+
+
+#if !SILVERLIGHT
+        public static void CompressToStream<TXmlDto>(TXmlDto from, Stream stream)
+        {
+            using (var deflateStream = new DeflateStream(stream, CompressionMode.Compress))
+            using (var xw = new XmlTextWriter(deflateStream, Encoding.UTF8))
+            {
+                var serializer = new DataContractSerializer(from.GetType());
+                serializer.WriteObject(xw, from);
+                xw.Flush();
+            }
+        }
+
+        public static byte[] Compress<TXmlDto>(TXmlDto from)
+        {
+            using (var ms = new MemoryStream())
+            {
+                CompressToStream(from, ms);
+
+                return ms.ToArray();
+            }
+        }
+#endif
+
+    }
+#endif
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ActionExecExtensions.cs b/lib/ServiceStack/src/ServiceStack.Common/ActionExecExtensions.cs
new file mode 100644
index 0000000..acc0827
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ActionExecExtensions.cs
@@ -0,0 +1,88 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using ServiceStack.Common.Support;
+
+namespace ServiceStack.Common
+{
+    public static class ActionExecExtensions
+    {
+        public static void ExecAllAndWait(this ICollection<Action> actions, TimeSpan timeout)
+        {
+            var waitHandles = new WaitHandle[actions.Count];
+            var i = 0;
+            foreach (var action in actions)
+            {
+                waitHandles[i++] = action.BeginInvoke(null, null).AsyncWaitHandle;
+            }
+
+            WaitAll(waitHandles, timeout);
+        }
+
+        public static List<WaitHandle> ExecAsync(this IEnumerable<Action> actions)
+        {
+            var waitHandles = new List<WaitHandle>();
+            foreach (var action in actions)
+            {
+                var waitHandle = new AutoResetEvent(false);
+                waitHandles.Add(waitHandle);
+                var commandExecsHandler = new ActionExecHandler(action, waitHandle);
+                ThreadPool.QueueUserWorkItem(x => ((ActionExecHandler)x).Execute(), commandExecsHandler);
+            }
+            return waitHandles;
+        }
+
+        public static bool WaitAll(this List<WaitHandle> waitHandles, int timeoutMs)
+        {
+            return WaitAll(waitHandles.ToArray(), timeoutMs);
+        }
+
+        public static bool WaitAll(this ICollection<WaitHandle> waitHandles, int timeoutMs)
+        {
+            return WaitAll(waitHandles.ToArray(), timeoutMs);
+        }
+
+        public static bool WaitAll(this ICollection<WaitHandle> waitHandles, TimeSpan timeout)
+        {
+            return WaitAll(waitHandles.ToArray(), (int)timeout.TotalMilliseconds);
+        }
+
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+        public static bool WaitAll(this List<IAsyncResult> asyncResults, TimeSpan timeout)
+        {
+            var waitHandles = asyncResults.ConvertAll(x => x.AsyncWaitHandle);
+            return WaitAll(waitHandles.ToArray(), (int)timeout.TotalMilliseconds);
+        }
+        
+        public static bool WaitAll(WaitHandle[] waitHandles, TimeSpan timeout)
+        {
+            return WaitAll(waitHandles, (int)timeout.TotalMilliseconds);
+        }
+
+        public static bool WaitAll(WaitHandle[] waitHandles, int timeOutMs)
+        {
+            // throws an exception if there are no wait handles
+            if (waitHandles == null) throw new ArgumentNullException("waitHandles");
+            if (waitHandles.Length == 0) return true;
+
+            if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA)
+            {
+                // WaitAll for multiple handles on an STA thread is not supported.
+                // CurrentThread is ApartmentState.STA when run under unit tests
+                var successfullyComplete = true;
+                foreach (var waitHandle in waitHandles)
+                {
+                    successfullyComplete = successfullyComplete 
+                        && waitHandle.WaitOne(timeOutMs, false);
+                }
+                return successfullyComplete;
+            }
+
+            return WaitHandle.WaitAll(waitHandles, timeOutMs, false);
+        }
+#endif
+
+    }
+
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/AssertExtensions.cs b/lib/ServiceStack/src/ServiceStack.Common/AssertExtensions.cs
new file mode 100644
index 0000000..7edbe46
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/AssertExtensions.cs
@@ -0,0 +1,73 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace ServiceStack.Common
+{
+    public static class AssertExtensions
+    {
+        public static void ThrowOnFirstNull(params object[] objs)
+        {
+            foreach (var obj in objs)
+            {
+                ThrowIfNull(obj);
+            }
+        }
+
+        public static void ThrowIfNull(this object obj)
+        {
+            ThrowIfNull(obj, null);
+        }
+
+        public static void ThrowIfNull(this object obj, string varName)
+        {
+            if (obj == null)
+                throw new ArgumentNullException(varName ?? "object");
+        }
+
+        public static void ThrowIfNullOrEmpty(this string strValue)
+        {
+            ThrowIfNullOrEmpty(strValue, null);
+        }
+
+        public static void ThrowIfNullOrEmpty(this string strValue, string varName)
+        {
+            if (string.IsNullOrEmpty(strValue))
+                throw new ArgumentNullException(varName ?? "string");
+        }
+
+        public static void ThrowIfNullOrEmpty(this ICollection collection)
+        {
+            ThrowIfNullOrEmpty(collection, null);
+        }
+
+        public static void ThrowIfNullOrEmpty(this ICollection collection, string varName)
+        {
+            var fieldName = varName ?? "collection";
+
+            if (collection == null)
+                throw new ArgumentNullException(fieldName);
+
+            if (collection.Count == 0)
+                throw new ArgumentException(fieldName + " is empty");
+        }
+
+        public static void ThrowIfNullOrEmpty<T>(this ICollection<T> collection)
+        {
+            ThrowIfNullOrEmpty(collection, null);
+        }
+
+        public static void ThrowIfNullOrEmpty<T>(this ICollection<T> collection, string varName)
+        {
+            var fieldName = varName ?? "collection";
+
+            if (collection == null)
+                throw new ArgumentNullException(fieldName);
+
+            if (collection.Count == 0)
+                throw new ArgumentException(fieldName + " is empty");
+        }
+
+    }
+
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ByteArrayExtensions.cs b/lib/ServiceStack/src/ServiceStack.Common/ByteArrayExtensions.cs
new file mode 100644
index 0000000..6cef70d
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ByteArrayExtensions.cs
@@ -0,0 +1,20 @@
+namespace ServiceStack.Common
+{
+    public static class ByteArrayExtensions
+    {
+        public static bool AreEqual(this byte[] b1, byte[] b2)
+        {
+            if (b1 == b2) return true;
+            if (b1 == null || b2 == null) return false;
+            if (b1.Length != b2.Length) return false;
+
+            for (var i = 0; i < b1.Length; i++)
+            {
+                if (b1[i] != b2[i]) return false;
+            }
+
+            return true;
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/DictionaryExtensions.cs b/lib/ServiceStack/src/ServiceStack.Common/DictionaryExtensions.cs
new file mode 100644
index 0000000..acf7005
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/DictionaryExtensions.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Collections.Generic;
+using ServiceStack.Common.Extensions;
+
+namespace ServiceStack.Common
+{
+    public static class DictionaryExtensions
+    {
+        public static TValue GetValueOrDefault<TValue, TKey>(this Dictionary<TKey, TValue> dictionary, TKey key)
+        {
+            return dictionary.ContainsKey(key) ? dictionary[key] : default(TValue);
+        }
+
+        public static void ForEach<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, Action<TKey, TValue> onEachFn)
+        {
+            foreach (var entry in dictionary)
+            {
+                onEachFn(entry.Key, entry.Value);
+            }
+        }
+
+        public static bool EquivalentTo<K, V>(this IDictionary<K, V> thisMap, IDictionary<K, V> otherMap)
+        {
+            if (thisMap == null || otherMap == null) return thisMap == otherMap;
+            if (thisMap.Count != otherMap.Count) return false;
+
+            foreach (var entry in thisMap)
+            {
+                V otherValue;
+                if (!otherMap.TryGetValue(entry.Key, out otherValue)) return false;
+                if (!Equals(entry.Value, otherValue)) return false;
+            }
+
+            return true;
+        }
+
+        public static List<T> ConvertAll<T, K, V>(IDictionary<K, V> map, Func<K, V, T> createFn)
+        {
+            var list = new List<T>();
+            map.ForEach((kvp) => list.Add(createFn(kvp.Key, kvp.Value)));
+            return list;
+        }
+        
+        public static V GetOrAdd<K, V>(this Dictionary<K, V> map, K key, Func<K,V> createFn)
+        {
+            //simulate ConcurrentDictionary.GetOrAdd
+            lock (map)
+            {
+                V val;
+                if (!map.TryGetValue(key, out val))
+                    map[key] = val = createFn(key);
+
+                return val;
+            }
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/DirectoryInfoExtensions.cs b/lib/ServiceStack/src/ServiceStack.Common/DirectoryInfoExtensions.cs
new file mode 100644
index 0000000..8821d73
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/DirectoryInfoExtensions.cs
@@ -0,0 +1,44 @@
+#if !SILVERLIGHT 
+using System.Collections.Generic;
+using System.IO;
+
+namespace ServiceStack.Common
+{
+    public static class DirectoryInfoExtensions
+    {
+        public static IEnumerable<string> GetMatchingFiles(this DirectoryInfo rootDirPath, string fileSearchPattern)
+        {
+            return GetMatchingFiles(rootDirPath.FullName, fileSearchPattern);
+        }
+
+        public static IEnumerable<string> GetMatchingFiles(string rootDirPath, string fileSearchPattern)
+        {
+            var pending = new Queue<string>();
+            pending.Enqueue(rootDirPath);
+            string[] paths; 
+
+            while (pending.Count > 0)
+            {
+                rootDirPath = pending.Dequeue();
+                paths = Directory.GetFiles(rootDirPath, fileSearchPattern);
+                foreach (var filePath in paths) {
+                    yield return filePath;
+                }
+                paths = Directory.GetDirectories(rootDirPath);
+                foreach (var dirPath in paths)
+                {
+                    var dirAttrs = File.GetAttributes(dirPath);
+                    var isRecurseSymLink = (dirAttrs & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint;
+
+                    if (!isRecurseSymLink)
+                    {
+                        pending.Enqueue(dirPath);
+                    }
+                }
+            }
+        }		 
+
+    }
+
+}
+#endif
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/DisposableExtensions.cs b/lib/ServiceStack/src/ServiceStack.Common/DisposableExtensions.cs
new file mode 100644
index 0000000..920819e
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/DisposableExtensions.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using ServiceStack.Logging;
+
+namespace ServiceStack.Common
+{
+    public static class DisposableExtensions
+    {
+        public static void Dispose(this IEnumerable<IDisposable> resources, ILog log)
+        {
+            foreach (var disposable in resources)
+            {
+                try
+                {
+                    disposable.Dispose();
+                }
+                catch (Exception ex)
+                {
+                    if (log != null)
+                    {
+                        log.Error(string.Format("Error disposing of '{0}'", disposable.GetType().FullName), ex);
+                    }
+                }
+            }
+        }
+
+        public static void Dispose(this IEnumerable<IDisposable> resources)
+        {
+            Dispose(resources, null);
+        }
+
+        public static void Dispose(params IDisposable[] disposables)
+        {
+            Dispose(disposables, null);
+        }
+
+        public static void Run<T>(this T disposable, Action<T> runActionThenDispose)
+            where T : IDisposable
+        {
+            using (disposable)
+            {
+                runActionThenDispose(disposable);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/EnumExtensions.cs b/lib/ServiceStack/src/ServiceStack.Common/EnumExtensions.cs
new file mode 100644
index 0000000..482ef88
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/EnumExtensions.cs
@@ -0,0 +1,110 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Reflection;
+
+namespace ServiceStack.Common
+{
+    public static class EnumExtensions
+    {
+        /// <summary>
+        /// Gets the textual description of the enum if it has one. e.g.
+        /// 
+        /// <code>
+        /// enum UserColors
+        /// {
+        ///     [Description("Bright Red")]
+        ///     BrightRed
+        /// }
+        /// UserColors.BrightRed.ToDescription();
+        /// </code>
+        /// </summary>
+        /// <param name="enum"></param>
+        /// <returns></returns>
+        public static string ToDescription(this Enum @enum) 
+        {
+            var type = @enum.GetType();
+            var memInfo = type.GetMember(@enum.ToString());
+            if (memInfo != null && memInfo.Length > 0)
+            {
+                var attrs = memInfo[0].GetCustomAttributes(
+                    typeof(DescriptionAttribute),
+                    false);
+
+                if (attrs != null && attrs.Length > 0)
+                    return ((DescriptionAttribute)attrs[0]).Description;
+            }
+
+            return @enum.ToString();
+        }
+
+        public static List<string> ToList(this Enum @enum)
+        {
+#if !SILVERLIGHT4
+            return new List<string>(Enum.GetNames(@enum.GetType()));
+#else
+            return @enum.GetType().GetFields(BindingFlags.Static | BindingFlags.Public).Select(fi => fi.Name).ToList();
+#endif
+        }
+
+        public static bool Has<T>(this Enum type, T value)
+        {
+            try
+            {
+                return (((int)(object)type & (int)(object)value) == (int)(object)value);
+            }
+            catch
+            {
+                return false;
+            }
+        }
+
+        public static bool Is<T>(this Enum type, T value)
+        {
+            try
+            {
+                return (int)(object)type == (int)(object)value;
+            }
+            catch
+            {
+                return false;
+            }
+        }
+
+
+        public static T Add<T>(this Enum type, T value)
+        {
+            try
+            {
+                return (T)(object)(((int)(object)type | (int)(object)value));
+            }
+            catch (Exception ex)
+            {
+                throw new ArgumentException(
+                    string.Format(
+                        "Could not append value from enumerated type '{0}'.",
+                        typeof(T).Name
+                        ), ex);
+            }
+        }
+
+        public static T Remove<T>(this Enum type, T value)
+        {
+            try
+            {
+                return (T)(object)(((int)(object)type & ~(int)(object)value));
+            }
+            catch (Exception ex)
+            {
+                throw new ArgumentException(
+                    string.Format(
+                        "Could not remove value from enumerated type '{0}'.",
+                        typeof(T).Name
+                        ), ex);
+            }
+        }
+
+    }
+
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/EnumerableExtensions.cs b/lib/ServiceStack/src/ServiceStack.Common/EnumerableExtensions.cs
new file mode 100644
index 0000000..cf98f59
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/EnumerableExtensions.cs
@@ -0,0 +1,107 @@
+using System;
+using System.Collections.Generic;
+
+namespace ServiceStack.Common
+{
+    public static class EnumerableExtensions
+    {
+        public static bool IsEmpty<T>(this ICollection<T> collection)
+        {
+            return collection == null || collection.Count == 0;
+        }
+
+        public static HashSet<T> ToHashSet<T>(this IEnumerable<T> items)
+        {
+            return new HashSet<T>(items);
+        }
+
+        public static List<To> SafeConvertAll<To, From>(this IEnumerable<From> items, Func<From, To> converter)
+        {
+            return items == null ? new List<To>() : Extensions.EnumerableExtensions.ConvertAll(items, converter);
+        }
+
+        public static List<object> ToObjects<T>(this IEnumerable<T> items)
+        {
+            var to = new List<object>();
+            foreach (var item in items)
+            {
+                to.Add(item);
+            }
+            return to;
+        }
+
+        public static string FirstNonDefaultOrEmpty(this IEnumerable<string> values)
+        {
+            foreach (var value in values)
+            {
+                if (!string.IsNullOrEmpty(value)) return value;
+            }
+            return null;
+        }
+
+        public static T FirstNonDefault<T>(this IEnumerable<T> values)
+        {
+            foreach (var value in values)
+            {
+                if (!Equals(value, default(T))) return value;
+            }
+            return default(T);
+        }
+
+        public static bool EquivalentTo<T>(this IEnumerable<T> thisList, IEnumerable<T> otherList)
+        {
+            if (thisList == null || otherList == null) return thisList == otherList;
+
+            var otherEnum = otherList.GetEnumerator();
+            foreach (var item in thisList)
+            {
+                if (!otherEnum.MoveNext()) return false;
+
+                var thisIsDefault = Equals(item, default(T));
+                var otherIsDefault = Equals(otherEnum.Current, default(T));
+                if (thisIsDefault || otherIsDefault)
+                {
+                    return thisIsDefault && otherIsDefault;
+                }
+
+                if (!item.Equals(otherEnum.Current)) return false;
+            }
+            var hasNoMoreLeftAsWell = !otherEnum.MoveNext();
+            return hasNoMoreLeftAsWell;
+        }
+
+        public static IEnumerable<T[]> BatchesOf<T>(this IEnumerable<T> sequence, int batchSize)
+        {
+            var batch = new List<T>(batchSize);
+            foreach (var item in sequence)
+            {
+                batch.Add(item);
+                if (batch.Count >= batchSize)
+                {
+                    yield return batch.ToArray();
+                    batch.Clear();
+                }
+            }
+
+            if (batch.Count > 0)
+            {
+                yield return batch.ToArray();
+                batch.Clear();
+            }
+        }
+
+        public static Dictionary<TKey, T> ToSafeDictionary<T, TKey>(this IEnumerable<T> list, Func<T, TKey> expr)
+        {
+            var map = new Dictionary<TKey, T>();
+            if (list != null)
+            {
+                foreach (var item in list)
+                {
+                    map[expr(item)] = item;
+                }
+            }
+            return map;
+        }
+        
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ExecExtensions.cs b/lib/ServiceStack/src/ServiceStack.Common/ExecExtensions.cs
new file mode 100644
index 0000000..9b81c38
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ExecExtensions.cs
@@ -0,0 +1,144 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using ServiceStack.Logging;
+
+namespace ServiceStack.Common
+{
+    public static class ExecExtensions
+    {
+        public static void LogError(Type declaringType, string clientMethodName, Exception ex)
+        {
+            var log = LogManager.GetLogger(declaringType);
+            log.Error(string.Format("'{0}' threw an error on {1}: {2}", declaringType.FullName, clientMethodName, ex.Message), ex);
+        }
+
+        public static void ExecAll<T>(this IEnumerable<T> instances, Action<T> action)
+        {
+            foreach (var instance in instances)
+            {
+                try
+                {
+                    action(instance);
+                }
+                catch (Exception ex)
+                {
+                    LogError(instance.GetType(), action.GetType().Name, ex);
+                }
+            }
+        }
+
+        public static void ExecAllWithFirstOut<T, TReturn>(this IEnumerable<T> instances, Func<T, TReturn> action, ref TReturn firstResult)
+        {
+            foreach (var instance in instances)
+            {
+                try
+                {
+                    var result = action(instance);
+                    if (!Equals(firstResult, default(TReturn)))
+                    {
+                        firstResult = result;
+                    }
+                }
+                catch (Exception ex)
+                {
+                    LogError(instance.GetType(), action.GetType().Name, ex);
+                }
+            }
+        }
+
+        public static TReturn ExecReturnFirstWithResult<T, TReturn>(this IEnumerable<T> instances, Func<T, TReturn> action)
+        {
+            foreach (var instance in instances)
+            {
+                try
+                {
+                    var result = action(instance);
+                    if (!Equals(result, default(TReturn)))
+                    {
+                        return result;
+                    }
+                }
+                catch (Exception ex)
+                {
+                    LogError(instance.GetType(), action.GetType().Name, ex);
+                }
+            }
+
+            return default(TReturn);
+        }
+
+        public static void RetryUntilTrue(Func<bool> action, TimeSpan? timeOut)
+        {
+            var i = 0;
+            var firstAttempt = DateTime.Now;
+
+            while (timeOut == null || DateTime.Now - firstAttempt < timeOut.Value)
+            {
+                i++;
+                if (action())
+                {
+                    return;
+                }
+                SleepBackOffMultiplier(i);
+            }
+
+            throw new TimeoutException(string.Format("Exceeded timeout of {0}", timeOut.Value));
+        }
+
+        public static void RetryOnException(Action action, TimeSpan? timeOut)
+        {
+            var i = 0;
+            Exception lastEx = null;
+            var firstAttempt = DateTime.Now;
+
+            while (timeOut == null || DateTime.Now - firstAttempt < timeOut.Value)
+            {
+                i++;
+                try
+                {
+                    action();
+                    return;
+                }
+                catch (Exception ex)
+                {
+                    lastEx = ex;
+
+                    SleepBackOffMultiplier(i);
+                }
+            }
+
+            throw new TimeoutException(string.Format("Exceeded timeout of {0}", timeOut.Value), lastEx);
+        }
+
+        public static void RetryOnException(Action action, int maxRetries)
+        {
+            for (var i = 0; i < maxRetries; i++)
+            {
+                try
+                {
+                    action();
+                    break;
+                }
+                catch
+                {
+                    if (i == maxRetries - 1) throw;
+
+                    SleepBackOffMultiplier(i);
+                }
+            }
+        }
+
+        private static void SleepBackOffMultiplier(int i)
+        {
+            //exponential/random retry back-off.
+            var rand = new Random(Guid.NewGuid().GetHashCode());
+            var nextTry = rand.Next(
+                (int)Math.Pow(i, 2), (int)Math.Pow(i + 1, 2) + 1);
+
+            Thread.Sleep(nextTry);
+        }
+    }
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Expressions/DelegateFactory.cs b/lib/ServiceStack/src/ServiceStack.Common/Expressions/DelegateFactory.cs
new file mode 100644
index 0000000..48ff380
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Expressions/DelegateFactory.cs
@@ -0,0 +1,72 @@
+using System;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Reflection;
+
+namespace ServiceStack.Common.Expressions
+{
+    public static class DelegateFactory
+    {
+
+        /*
+         *	MethodInfo method = typeof(String).GetMethod("StartsWith", new[] { typeof(string) });  
+            LateBoundMethod callback = DelegateFactory.Create(method);  
+  
+            string foo = "this is a test";  
+            bool result = (bool) callback(foo, new[] { "this" });  
+  
+            result.ShouldBeTrue();  
+         */
+        public delegate object LateBoundMethod(object target, object[] arguments);
+
+        public static LateBoundMethod Create(MethodInfo method)
+        {
+            ParameterExpression instanceParameter = Expression.Parameter(typeof(object), "target");
+            ParameterExpression argumentsParameter = Expression.Parameter(typeof(object[]), "arguments");
+
+            MethodCallExpression call = Expression.Call(
+                Expression.Convert(instanceParameter, method.DeclaringType),
+                method,
+                CreateParameterExpressions(method, argumentsParameter));
+
+            Expression<LateBoundMethod> lambda = Expression.Lambda<LateBoundMethod>(
+                Expression.Convert(call, typeof(object)),
+                instanceParameter,
+                argumentsParameter);
+
+            return lambda.Compile();
+        }
+
+        private static Expression[] CreateParameterExpressions(MethodInfo method, Expression argumentsParameter)
+        {
+            return method.GetParameters().Select((parameter, index) =>
+                Expression.Convert(
+                    Expression.ArrayIndex(argumentsParameter, Expression.Constant(index)),
+                    parameter.ParameterType)).ToArray();
+        }
+
+
+        public delegate void LateBoundVoid(object target, object[] arguments);
+
+        public static LateBoundVoid CreateVoid(MethodInfo method)
+        {
+            ParameterExpression instanceParameter = Expression.Parameter(typeof(object), "target");
+            ParameterExpression argumentsParameter = Expression.Parameter(typeof(object[]), "arguments");
+
+            MethodCallExpression call = Expression.Call(
+                Expression.Convert(instanceParameter, method.DeclaringType),
+                method,
+                CreateParameterExpressions(method, argumentsParameter));
+
+            var lambda = Expression.Lambda<LateBoundVoid>(
+                Expression.Convert(call, method.ReturnParameter.ParameterType),
+                instanceParameter,
+                argumentsParameter);
+
+            return lambda.Compile();
+        }
+
+
+    }
+
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Extensions/ActionExecExtensions.cs b/lib/ServiceStack/src/ServiceStack.Common/Extensions/ActionExecExtensions.cs
new file mode 100644
index 0000000..7d6650b
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Extensions/ActionExecExtensions.cs
@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+using System.Threading;
+
+using Proxy = ServiceStack.Common.ActionExecExtensions;
+
+namespace ServiceStack.Common.Extensions
+{
+    public static class ExtensionsProxy
+    {
+        public static void ExecAllAndWait(this ICollection<Action> actions, TimeSpan timeout)
+        {
+            Proxy.ExecAllAndWait(actions, timeout);
+        }
+
+        public static List<WaitHandle> ExecAsync(this IEnumerable<Action> actions)
+        {
+            return Proxy.ExecAsync(actions);
+        }
+
+        public static bool WaitAll(this List<WaitHandle> waitHandles, int timeoutMs)
+        {
+            return Proxy.WaitAll(waitHandles, timeoutMs);
+        }
+
+        public static bool WaitAll(this ICollection<WaitHandle> waitHandles, int timeoutMs)
+        {
+            return Proxy.WaitAll(waitHandles, timeoutMs);
+        }
+
+        public static bool WaitAll(this ICollection<WaitHandle> waitHandles, TimeSpan timeout)
+        {
+            return Proxy.WaitAll(waitHandles, timeout);
+        }
+
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+        public static bool WaitAll(this List<IAsyncResult> asyncResults, TimeSpan timeout)
+        {
+            return Proxy.WaitAll(asyncResults, timeout);
+        }
+#endif
+
+        public static bool WaitAll(WaitHandle[] waitHandles, TimeSpan timeout)
+        {
+            return Proxy.WaitAll(waitHandles, timeout);
+        }
+
+        public static bool WaitAll(WaitHandle[] waitHandles, int timeOutMs)
+        {
+            return Proxy.WaitAll(waitHandles, timeOutMs);
+        }	
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Extensions/AssertExtensions.cs b/lib/ServiceStack/src/ServiceStack.Common/Extensions/AssertExtensions.cs
new file mode 100644
index 0000000..a5c0c62
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Extensions/AssertExtensions.cs
@@ -0,0 +1,57 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+using Proxy = ServiceStack.Common.AssertExtensions;
+
+namespace ServiceStack.Common.Extensions
+{
+    public static class AssertExtensions
+    {
+        public static void ThrowOnFirstNull(params object[] objs)
+        {
+            Proxy.ThrowOnFirstNull(objs);
+        }
+
+        public static void ThrowIfNull(this object obj)
+        {
+            Proxy.ThrowIfNull(obj);
+        }
+
+        public static void ThrowIfNull(this object obj, string varName)
+        {
+            Proxy.ThrowIfNull(obj, varName);
+        }
+
+        public static void ThrowIfNullOrEmpty(this string strValue)
+        {
+            Proxy.ThrowIfNullOrEmpty(strValue);
+        }
+
+        public static void ThrowIfNullOrEmpty(this string strValue, string varName)
+        {
+            Proxy.ThrowIfNullOrEmpty(strValue, varName);
+        }
+
+        public static void ThrowIfNullOrEmpty(this ICollection collection)
+        {
+            Proxy.ThrowIfNullOrEmpty(collection);
+        }
+
+        public static void ThrowIfNullOrEmpty(this ICollection collection, string varName)
+        {
+            Proxy.ThrowIfNullOrEmpty(collection, varName);
+        }
+
+        public static void ThrowIfNullOrEmpty<T>(this ICollection<T> collection)
+        {
+            Proxy.ThrowIfNullOrEmpty(collection);
+        }
+
+        public static void ThrowIfNullOrEmpty<T>(this ICollection<T> collection, string varName)
+        {
+            Proxy.ThrowIfNullOrEmpty(collection, varName);
+        }
+         
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Extensions/ByteArrayExtensions.cs b/lib/ServiceStack/src/ServiceStack.Common/Extensions/ByteArrayExtensions.cs
new file mode 100644
index 0000000..ce9a9e8
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Extensions/ByteArrayExtensions.cs
@@ -0,0 +1,12 @@
+using Proxy = ServiceStack.Common.ByteArrayExtensions;
+
+namespace ServiceStack.Common.Extensions
+{
+    public static class ByteArrayExtensions
+    {
+        public static bool AreEqual(this byte[] b1, byte[] b2)
+        {
+            return Proxy.AreEqual(b1, b2);
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Extensions/CollectionExtensions.cs b/lib/ServiceStack/src/ServiceStack.Common/Extensions/CollectionExtensions.cs
new file mode 100644
index 0000000..7060042
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Extensions/CollectionExtensions.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using Proxy = ServiceStack.Common;
+
+namespace ServiceStack.Common.Extensions
+{
+    public static class CollectionExtensions
+    {
+        public static bool IsEmpty<T>(this ICollection<T> collection)
+        {
+            return collection == null || collection.Count == 0;
+        }
+        
+        public static List<To> ConvertAll<To>(this ICollection items, Func<object, To> converter)
+        {
+            var list = new List<To>();
+            foreach (var item in items)
+            {
+                list.Add(converter(item));
+            }
+            return list;
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Extensions/DictionaryExtensions.cs b/lib/ServiceStack/src/ServiceStack.Common/Extensions/DictionaryExtensions.cs
new file mode 100644
index 0000000..d1d9488
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Extensions/DictionaryExtensions.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+
+using Proxy = ServiceStack.Common.DictionaryExtensions;
+
+namespace ServiceStack.Common.Extensions
+{
+    public static class DictionaryExtensions
+    {
+        public static TValue GetValueOrDefault<TValue, TKey>(this Dictionary<TKey, TValue> dictionary, TKey key)
+        {
+            return Proxy.GetValueOrDefault(dictionary, key);
+        }
+
+        public static void ForEach<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, Action<TKey, TValue> onEachFn)
+        {
+            Proxy.ForEach(dictionary, onEachFn);
+        }
+
+        public static bool EquivalentTo<K, V>(this IDictionary<K, V> thisMap, IDictionary<K, V> otherMap)
+        {
+            return Proxy.EquivalentTo(thisMap, otherMap);
+        }
+         
+        public static List<T> ConvertAll<T, K, V>(IDictionary<K, V> map, Func<K, V, T> createFn)
+        {
+            return Proxy.ConvertAll(map, createFn);
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Extensions/EnumerableExtensions.cs b/lib/ServiceStack/src/ServiceStack.Common/Extensions/EnumerableExtensions.cs
new file mode 100644
index 0000000..87b9d16
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Extensions/EnumerableExtensions.cs
@@ -0,0 +1,123 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+using Proxy = ServiceStack.Common.EnumerableExtensions;
+
+namespace ServiceStack.Common.Extensions
+{
+    /// <summary>
+    /// These extensions have a potential to conflict with the LINQ extensions methods so
+    /// leaving the implmentation in the 'Extensions' sub-namespace to force explicit opt-in
+    /// </summary>
+    public static class EnumerableExtensions
+    {
+        public static void ForEach<T>(this IEnumerable<T> values, Action<T> action)
+        {
+            foreach (var value in values)
+            {
+                action(value);
+            }
+        }
+
+        public static List<To> ConvertAll<To>(this IEnumerable items, Func<object, To> converter)
+        {
+            var list = new List<To>();
+            foreach (var item in items)
+            {
+                list.Add(converter(item));
+            }
+            return list;
+        }
+
+        public static object First(this IEnumerable items)
+        {
+            foreach (var item in items)
+            {
+                return item;
+            }
+            return null;
+        }
+
+        public static List<To> ToList<To>(this IEnumerable items)
+        {
+            var list = new List<To>();
+            foreach (var item in items)
+            {
+                list.Add((To)item);
+            }
+            return list;
+        }
+
+        public static List<To> ConvertAll<To, From>(this IEnumerable<From> items, Func<From, To> converter)
+        {
+            var list = new List<To>();
+            foreach (var item in items)
+            {
+                list.Add(converter(item));
+            }
+            return list;
+        }
+
+        public static HashSet<T> ToHashSet<T>(this IEnumerable<T> items)
+        {
+            return Proxy.ToHashSet(items);
+        }
+
+        public static List<To> SafeConvertAll<To, From>(this IEnumerable<From> items, Func<From, To> converter)
+        {
+            return Proxy.SafeConvertAll(items, converter);
+        }
+
+        public static List<object> ToObjects<T>(this IEnumerable<T> items)
+        {
+            var to = new List<object>();
+            foreach (var item in items)
+            {
+                to.Add(item);
+            }
+            return to;
+        }
+
+        public static string FirstNonDefaultOrEmpty(this IEnumerable<string> values)
+        {
+            foreach (var value in values)
+            {
+                if (!string.IsNullOrEmpty(value)) return value;
+            }
+            return null;
+        }
+
+        public static T FirstNonDefault<T>(this IEnumerable<T> values)
+        {
+            foreach (var value in values)
+            {
+                if (!Equals(value, default(T))) return value;
+            }
+            return default(T);
+        }
+
+        public static bool EquivalentTo<T>(this IEnumerable<T> thisList, IEnumerable<T> otherList)
+        {
+            if (thisList == null || otherList == null) return thisList == otherList;
+
+            var otherEnum = otherList.GetEnumerator();
+            foreach (var item in thisList)
+            {
+                if (!otherEnum.MoveNext()) return false;
+                
+                var thisIsDefault = Equals(item, default(T));
+                var otherIsDefault = Equals(otherEnum.Current, default(T));
+                if (thisIsDefault || otherIsDefault)
+                {
+                    return thisIsDefault && otherIsDefault;
+                }
+                
+                if (!item.Equals(otherEnum.Current)) return false;
+            }
+            var hasNoMoreLeftAsWell = !otherEnum.MoveNext();
+            return hasNoMoreLeftAsWell;
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Extensions/ITranslatorExtensions.cs b/lib/ServiceStack/src/ServiceStack.Common/Extensions/ITranslatorExtensions.cs
new file mode 100644
index 0000000..d7de38b
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Extensions/ITranslatorExtensions.cs
@@ -0,0 +1,24 @@
+using System.Collections.Generic;
+using ServiceStack.DesignPatterns.Translator;
+
+namespace ServiceStack.Common.Extensions
+{
+    public static class TranslatorExtensions
+    {
+        // Methods
+        public static List<To> ParseAll<To, From>(this ITranslator<To, From> translator, IEnumerable<From> from)
+        {
+            var list = new List<To>();
+            if (from != null)
+            {
+                foreach (var local in from)
+                {
+                    list.Add(translator.Parse(local));
+                }
+            }
+            return list;
+        }
+    }
+
+
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Extensions/IntExtensions.cs b/lib/ServiceStack/src/ServiceStack.Common/Extensions/IntExtensions.cs
new file mode 100644
index 0000000..6a6baa3
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Extensions/IntExtensions.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+
+using Proxy = ServiceStack.Common.IntExtensions;
+
+namespace ServiceStack.Common.Extensions
+{
+    public static class IntExtensions
+    {
+        public static IEnumerable<int> Times(this int times)
+        {
+            return Proxy.Times(times);
+        }
+
+        public static void Times(this int times, Action<int> actionFn)
+        {
+            Proxy.Times(times, actionFn);
+        }
+
+        public static void Times(this int times, Action actionFn)
+        {
+            Proxy.Times(times, actionFn);
+        }
+
+        public static List<IAsyncResult> TimesAsync(this int times, Action<int> actionFn)
+        {
+            return Proxy.TimesAsync(times, actionFn);
+        }
+
+        public static List<IAsyncResult> TimesAsync(this int times, Action actionFn)
+        {
+            return Proxy.TimesAsync(times, actionFn);
+        }
+
+        public static List<T> Times<T>(this int times, Func<T> actionFn)
+        {
+            return Proxy.Times(times, actionFn);
+        }
+
+        public static List<T> Times<T>(this int times, Func<int, T> actionFn)
+        {
+            return Proxy.Times(times, actionFn);
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Extensions/ReflectionExtensions.cs b/lib/ServiceStack/src/ServiceStack.Common/Extensions/ReflectionExtensions.cs
new file mode 100644
index 0000000..2ba133c
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Extensions/ReflectionExtensions.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Reflection;
+
+using Proxy = ServiceStack.Common.ReflectionExtensions;
+
+namespace ServiceStack.Common.Extensions
+{
+    public static class ReflectionExtensions
+    {
+        public static To PopulateWith<To, From>(this To to, From from)
+        {
+            return Proxy.PopulateWith(to, from);
+        }
+
+        public static To PopulateWithNonDefaultValues<To, From>(this To to, From from)
+        {
+            return Proxy.PopulateWithNonDefaultValues(to, from);
+        }
+
+        public static To PopulateFromPropertiesWithAttribute<To, From, TAttr>(this To to, From from)
+        {
+            return Proxy.PopulateFromPropertiesWithAttribute<To, From, TAttr>(to, from);
+        }
+
+        public static T TranslateTo<T>(this object from)
+            where T : new()
+        {
+            return Proxy.TranslateTo<T>(from);
+        }
+
+        public static TAttribute FirstAttribute<TAttribute>(this Type type)
+        {
+            return Proxy.FirstAttribute<TAttribute>(type);
+        }
+
+        public static TAttribute FirstAttribute<TAttribute>(this Type type, bool inherit)
+        {
+            return Proxy.FirstAttribute<TAttribute>(type, inherit);
+        }
+
+        public static TAttribute FirstAttribute<TAttribute>(this PropertyInfo propertyInfo)
+        {
+            return Proxy.FirstAttribute<TAttribute>(propertyInfo);
+        }
+
+        public static TAttribute FirstAttribute<TAttribute>(this PropertyInfo propertyInfo, bool inherit)
+        {
+            return Proxy.FirstAttribute<TAttribute>(propertyInfo, inherit);
+        }
+
+        public static bool IsGenericType(this Type type)
+        {
+            return Proxy.IsGenericType(type);
+        }
+
+        public static Type FirstGenericTypeDefinition(this Type type)
+        {
+            return Proxy.FirstGenericTypeDefinition(type);
+        }
+    }
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Extensions/StringExtensions.cs b/lib/ServiceStack/src/ServiceStack.Common/Extensions/StringExtensions.cs
new file mode 100644
index 0000000..120accd
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Extensions/StringExtensions.cs
@@ -0,0 +1,104 @@
+using System.Collections.Generic;
+using Proxy = ServiceStack.Common.StringExtensions;
+
+namespace ServiceStack.Common.Extensions
+{
+    public static class StringExtensions
+    {
+        public static T ToEnum<T>(this string value)
+        {
+            return Proxy.ToEnum<T>(value);
+        }
+
+        public static T ToEnumOrDefault<T>(this string value, T defaultValue)
+        {
+            return Proxy.ToEnumOrDefault<T>(value, defaultValue);
+        }
+
+        public static string SplitCamelCase(this string value)
+        {
+            return Proxy.SplitCamelCase(value);
+        }
+
+        public static string ToEnglish(this string camelCase)
+        {
+            return Proxy.ToEnglish(camelCase);
+        }
+
+        public static bool IsEmpty(this string value)
+        {
+            return Proxy.IsEmpty(value);
+        }
+
+        public static bool IsNullOrEmpty(this string value)
+        {
+            return Proxy.IsNullOrEmpty(value);
+        }
+
+        public static bool EqualsIgnoreCase(this string value, string other)
+        {
+            return Proxy.EqualsIgnoreCase(value, other);
+        }
+
+        public static string ReplaceFirst(this string haystack, string needle, string replacement)
+        {
+            return Proxy.ReplaceFirst(haystack, needle, replacement);
+        }
+
+        public static string ReplaceAll(this string haystack, string needle, string replacement)
+        {
+            return Proxy.ReplaceAll(haystack, needle, replacement);
+        }
+
+        public static bool ContainsAny(this string text, params string[] testMatches)
+        {
+            return Proxy.ContainsAny(text, testMatches);
+        }
+
+        public static string SafeVarName(this string text)
+        {
+            return Proxy.SafeVarName(text);
+        }
+
+        public static string Join(this List<string> items)
+        {
+            return Proxy.Join(items);
+        }
+
+        public static string Join(this List<string> items, string delimeter)
+        {
+            return Proxy.Join(items, delimeter);
+        }
+
+        public static bool Glob(this string value, string pattern)
+        {
+            int pos;
+            for (pos = 0; pattern.Length != pos; pos++)
+            {
+                switch (pattern[pos])
+                {
+                    case '?':
+                        break;
+
+                    case '*':
+                        for (int i = value.Length; i >= pos; i--)
+                        {
+                            if (Glob(value.Substring(i), pattern.Substring(pos + 1)))
+                                return true;
+                        }
+                        return false;
+
+                    default:
+                        if (value.Length == pos || char.ToUpper(pattern[pos]) != char.ToUpper(value[pos]))
+                        {
+                            return false;
+                        }
+                        break;
+                }
+            }
+
+            return value.Length == pos;
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/HostContext.cs b/lib/ServiceStack/src/ServiceStack.Common/HostContext.cs
new file mode 100644
index 0000000..e2268dd
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/HostContext.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web;
+
+namespace ServiceStack.Common
+{
+    public class HostContext
+    {
+        public static HostContext Instance = new HostContext();
+
+        [ThreadStatic] public static IDictionary items;
+        public virtual IDictionary Items
+        {
+            get
+            {
+                return items ?? (HttpContext.Current != null
+                    ? HttpContext.Current.Items
+                    : items = new Dictionary<object, object>());
+            }
+            set { items = value; }
+        }
+
+        public T GetOrCreate<T>(Func<T> createFn)
+        {
+            if (Items.Contains(typeof(T).Name))
+                return (T)Items[typeof(T).Name];
+
+            return (T) (Items[typeof(T).Name] = createFn());
+        }
+
+        public void EndRequest()
+        {
+            items = null;
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/IPAddressExtensions.cs b/lib/ServiceStack/src/ServiceStack.Common/IPAddressExtensions.cs
new file mode 100644
index 0000000..6a4ac7e
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/IPAddressExtensions.cs
@@ -0,0 +1,166 @@
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Net.NetworkInformation;
+using System.Net.Sockets;
+using ServiceStack.Logging;
+
+namespace ServiceStack.Common.Extensions
+{
+    /// <summary>
+    /// Useful IPAddressExtensions from: 
+    /// http://blogs.msdn.com/knom/archive/2008/12/31/ip-address-calculations-with-c-subnetmasks-networks.aspx
+    /// 
+    /// </summary>
+    public static class IPAddressExtensions
+    {
+        public static IPAddress GetBroadcastAddress(this IPAddress address, IPAddress subnetMask)
+        {
+            var ipAdressBytes = address.GetAddressBytes();
+            var subnetMaskBytes = subnetMask.GetAddressBytes();
+
+            if (ipAdressBytes.Length != subnetMaskBytes.Length)
+                throw new ArgumentException("Lengths of IP address and subnet mask do not match.");
+
+            var broadcastAddress = new byte[ipAdressBytes.Length];
+            for (var i = 0; i < broadcastAddress.Length; i++)
+            {
+                broadcastAddress[i] = (byte)(ipAdressBytes[i] | (subnetMaskBytes[i] ^ 255));
+            }
+            return new IPAddress(broadcastAddress);
+        }
+        
+        public static IPAddress GetNetworkAddress(this IPAddress address, IPAddress subnetMask)
+        {
+            var ipAdressBytes = address.GetAddressBytes();
+            var subnetMaskBytes = subnetMask.GetAddressBytes();
+
+            return new IPAddress(GetNetworkAddressBytes(ipAdressBytes, subnetMaskBytes));
+        }
+
+        public static byte[] GetNetworkAddressBytes(byte[] ipAdressBytes, byte[] subnetMaskBytes) 
+        {
+            if (ipAdressBytes.Length != subnetMaskBytes.Length)
+                throw new ArgumentException("Lengths of IP address and subnet mask do not match.");
+
+            var broadcastAddress = new byte[ipAdressBytes.Length];
+            for (var i = 0; i < broadcastAddress.Length; i++)
+            {
+                broadcastAddress[i] = (byte)(ipAdressBytes[i] & (subnetMaskBytes[i]));
+            }
+            return broadcastAddress;
+        }
+
+        public static bool IsInSameIpv6Subnet(this IPAddress address2, IPAddress address)
+        {
+            if (address2.AddressFamily != AddressFamily.InterNetworkV6 || address.AddressFamily != AddressFamily.InterNetworkV6)
+            {
+                throw new ArgumentException("Both IPAddress must be IPV6 addresses");
+            }
+            var address1Bytes = address.GetAddressBytes();
+            var address2Bytes = address2.GetAddressBytes();
+
+            return IsInSameIpv6Subnet(address1Bytes, address2Bytes);
+        }
+
+        public static bool IsInSameIpv6Subnet(this byte[] address1Bytes, byte[] address2Bytes) 
+        {
+            if (address1Bytes.Length != address2Bytes.Length)
+                throw new ArgumentException("Lengths of IP addresses do not match.");
+
+            for (var i = 0; i < 8; i++)
+            {
+                if (address1Bytes[i] != address2Bytes[i])
+                {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        public static bool IsInSameIpv4Subnet(this IPAddress address2, IPAddress address, IPAddress subnetMask)
+        {
+            if (address2.AddressFamily != AddressFamily.InterNetwork || address.AddressFamily != AddressFamily.InterNetwork)
+            {
+                throw new ArgumentException("Both IPAddress must be IPV4 addresses");
+            }
+            var network1 = address.GetNetworkAddress(subnetMask);
+            var network2 = address2.GetNetworkAddress(subnetMask);
+
+            return network1.Equals(network2);
+        }
+
+        public static bool IsInSameIpv4Subnet(this byte[] address1Bytes, byte[] address2Bytes, byte[] subnetMaskBytes)
+        {
+            if (address1Bytes.Length != address2Bytes.Length)
+                throw new ArgumentException("Lengths of IP addresses do not match.");
+
+            var network1Bytes = GetNetworkAddressBytes(address1Bytes, subnetMaskBytes);
+            var network2Bytes = GetNetworkAddressBytes(address2Bytes, subnetMaskBytes);
+
+            return network1Bytes.AreEqual(network2Bytes);
+        }
+
+
+        /// <summary>
+        /// Gets the ipv4 addresses from all Network Interfaces that have Subnet masks.
+        /// </summary>
+        /// <returns></returns>
+        public static Dictionary<IPAddress, IPAddress> GetAllNetworkInterfaceIpv4Addresses()
+        {
+            var map = new Dictionary<IPAddress, IPAddress>();
+
+            try
+            {
+#if !SILVERLIGHT 
+                foreach (var ni in NetworkInterface.GetAllNetworkInterfaces())
+                {
+                    foreach (var uipi in ni.GetIPProperties().UnicastAddresses)
+                    {
+                        if (uipi.Address.AddressFamily != AddressFamily.InterNetwork) continue;
+
+                        if (uipi.IPv4Mask == null) continue; //ignore 127.0.0.1
+                        map[uipi.Address] = uipi.IPv4Mask;
+                    }
+                }
+#endif
+            }
+            catch /*(NotImplementedException ex)*/
+            {
+                //log.Warn("MONO does not support NetworkInterface.GetAllNetworkInterfaces(). Could not detect local ip subnets.", ex);
+            } 
+            return map;
+        }
+
+        /// <summary>
+        /// Gets the ipv6 addresses from all Network Interfaces.
+        /// </summary>
+        /// <returns></returns>
+        public static List<IPAddress> GetAllNetworkInterfaceIpv6Addresses()
+        {
+            var list = new List<IPAddress>();
+
+            try
+            {
+#if !SILVERLIGHT 
+                foreach (var ni in NetworkInterface.GetAllNetworkInterfaces())
+                {
+                    foreach (var uipi in ni.GetIPProperties().UnicastAddresses)
+                    {
+                        if (uipi.Address.AddressFamily != AddressFamily.InterNetworkV6) continue;
+                        list.Add(uipi.Address);
+                    }
+                }
+#endif
+            }
+            catch /*(NotImplementedException ex)*/
+            {
+                //log.Warn("MONO does not support NetworkInterface.GetAllNetworkInterfaces(). Could not detect local ip subnets.", ex);
+            }
+            
+            return list;
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/IntExtensions.cs b/lib/ServiceStack/src/ServiceStack.Common/IntExtensions.cs
new file mode 100644
index 0000000..b2577ed
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/IntExtensions.cs
@@ -0,0 +1,72 @@
+using System;
+using System.Collections.Generic;
+
+namespace ServiceStack.Common
+{
+    public static class IntExtensions
+    {
+        public static IEnumerable<int> Times(this int times)
+        {
+            for (var i=0; i < times; i++)
+            {
+                yield return i;
+            }
+        }
+
+        public static void Times(this int times, Action<int> actionFn)
+        {
+            for (var i = 0; i < times; i++)
+            {
+                actionFn(i);
+            }
+        }
+
+        public static void Times(this int times, Action actionFn)
+        {
+            for (var i = 0; i < times; i++)
+            {
+                actionFn();
+            }
+        }
+
+        public static List<IAsyncResult> TimesAsync(this int times, Action<int> actionFn)
+        {
+            var asyncResults = new List<IAsyncResult>(times);
+            for (var i = 0; i < times; i++)
+            {
+                asyncResults.Add(actionFn.BeginInvoke(i, null, null));				
+            }
+            return asyncResults;
+        }
+
+        public static List<IAsyncResult> TimesAsync(this int times, Action actionFn)
+        {
+            var asyncResults = new List<IAsyncResult>(times);
+            for (var i = 0; i < times; i++)
+            {
+                asyncResults.Add(actionFn.BeginInvoke(null, null));
+            }
+            return asyncResults;
+        }
+
+        public static List<T> Times<T>(this int times, Func<T> actionFn)
+        {
+            var list = new List<T>();
+            for (var i=0; i < times; i++)
+            {
+                list.Add(actionFn());
+            }
+            return list;
+        }
+
+        public static List<T> Times<T>(this int times, Func<int, T> actionFn)
+        {
+            var list = new List<T>();
+            for (var i=0; i < times; i++)
+            {
+                list.Add(actionFn(i));
+            }
+            return list;
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Messaging/ClientFactory.cs b/lib/ServiceStack/src/ServiceStack.Common/Messaging/ClientFactory.cs
new file mode 100644
index 0000000..3202078
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Messaging/ClientFactory.cs
@@ -0,0 +1,33 @@
+using System;
+using ServiceStack.Common;
+using ServiceStack.Service;
+using ServiceStack.ServiceClient.Web;
+
+namespace ServiceStack.Messaging
+{
+    public static class ClientFactory
+    {
+         public static IOneWayClient Create(string endpointUrl)
+        {
+             if (endpointUrl.IsNullOrEmpty() || !endpointUrl.StartsWith("http"))
+                return null;
+
+             if (endpointUrl.IndexOf("format=") == -1 || endpointUrl.IndexOf("format=json") >= 0)
+                 return new JsonServiceClient(endpointUrl);
+
+             if (endpointUrl.IndexOf("format=xml") >= 0)
+                 return new XmlServiceClient(endpointUrl);
+
+             if (endpointUrl.IndexOf("format=jsv") >= 0)
+                 return new JsvServiceClient(endpointUrl);
+
+             if (endpointUrl.IndexOf("format=soap11") >= 0)
+                 return new Soap11ServiceClient(endpointUrl);
+
+             if (endpointUrl.IndexOf("format=soap12") >= 0)
+                 return new Soap12ServiceClient(endpointUrl);
+
+             throw new NotImplementedException("could not find service client for " + endpointUrl);
+         }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Messaging/IMessageHandler.cs b/lib/ServiceStack/src/ServiceStack.Common/Messaging/IMessageHandler.cs
new file mode 100644
index 0000000..4d389a3
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Messaging/IMessageHandler.cs
@@ -0,0 +1,37 @@
+using System;
+
+namespace ServiceStack.Messaging
+{
+    /// <summary>
+    /// Single threaded message handler that can process all messages
+    /// of a particular message type.
+    /// </summary>
+    public interface IMessageHandler
+    {
+        /// <summary>
+        /// The type of the message this handler processes
+        /// </summary>
+        Type MessageType { get; }
+
+        /// <summary>
+        /// Process all messages pending
+        /// </summary>
+        /// <param name="mqClient"></param>
+        void Process(IMessageQueueClient mqClient);
+
+        /// <summary>
+        /// Process messages from a single queue.
+        /// </summary>
+        /// <param name="mqClient"></param>
+        /// <param name="queueName">The queue to process</param>
+        /// <param name="doNext">A predicate on whether to continue processing the next message if any</param>
+        /// <returns></returns>
+        int ProcessQueue(IMessageQueueClient mqClient, string queueName, Func<bool> doNext = null);
+
+        /// <summary>
+        /// Get Current Stats for this Message Handler
+        /// </summary>
+        /// <returns></returns>
+        IMessageHandlerStats GetStats();
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Messaging/IMessageHandlerDisposer.cs b/lib/ServiceStack/src/ServiceStack.Common/Messaging/IMessageHandlerDisposer.cs
new file mode 100644
index 0000000..f9ae532
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Messaging/IMessageHandlerDisposer.cs
@@ -0,0 +1,7 @@
+namespace ServiceStack.Messaging
+{
+    public interface IMessageHandlerDisposer
+    {
+        void DisposeMessageHandler(IMessageHandler messageHandler);
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Messaging/IMessageHandlerFactory.cs b/lib/ServiceStack/src/ServiceStack.Common/Messaging/IMessageHandlerFactory.cs
new file mode 100644
index 0000000..feb6037
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Messaging/IMessageHandlerFactory.cs
@@ -0,0 +1,10 @@
+namespace ServiceStack.Messaging
+{
+    /// <summary>
+    /// Encapsulates creating a new message handler
+    /// </summary>
+    public interface IMessageHandlerFactory
+    {
+        IMessageHandler CreateMessageHandler();
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Messaging/InMemoryMessageQueueClient.cs b/lib/ServiceStack/src/ServiceStack.Common/Messaging/InMemoryMessageQueueClient.cs
new file mode 100644
index 0000000..986d2ff
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Messaging/InMemoryMessageQueueClient.cs
@@ -0,0 +1,54 @@
+using System;
+
+namespace ServiceStack.Messaging
+{
+    public class InMemoryMessageQueueClient
+        : IMessageQueueClient
+    {
+        private readonly MessageQueueClientFactory factory;
+
+        public InMemoryMessageQueueClient(MessageQueueClientFactory factory)
+        {
+            this.factory = factory;
+        }
+
+        public void Publish<T>(T messageBody)
+        {
+            factory.PublishMessage(QueueNames<T>.In, new Message<T>(messageBody));
+        }
+
+        public void Publish<T>(IMessage<T> message)
+        {
+            factory.PublishMessage(QueueNames<T>.In, message);
+        }
+
+        public void Publish(string queueName, byte[] messageBytes)
+        {
+            factory.PublishMessage(queueName, messageBytes);
+        }
+
+        public void Notify(string queueName, byte[] messageBytes)
+        {
+            factory.PublishMessage(queueName, messageBytes);
+        }
+
+        public byte[] GetAsync(string queueName)
+        {
+            return factory.GetMessageAsync(queueName);
+        }
+
+        public string WaitForNotifyOnAny(params string[] channelNames)
+        {
+            throw new NotImplementedException();
+        }
+
+        public byte[] Get(string queueName, TimeSpan? timeOut)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void Dispose()
+        {
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Messaging/InMemoryTransientMessageFactory.cs b/lib/ServiceStack/src/ServiceStack.Common/Messaging/InMemoryTransientMessageFactory.cs
new file mode 100644
index 0000000..beef254
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Messaging/InMemoryTransientMessageFactory.cs
@@ -0,0 +1,74 @@
+#if !SILVERLIGHT 
+using System;
+using ServiceStack.Logging;
+
+namespace ServiceStack.Messaging
+{
+    public class InMemoryTransientMessageFactory
+        : IMessageFactory
+    {
+        private static readonly ILog Log = LogManager.GetLogger(typeof(InMemoryTransientMessageFactory));
+        private readonly InMemoryTransientMessageService  transientMessageService;
+        internal MessageQueueClientFactory MqFactory { get; set; }
+
+        public InMemoryTransientMessageFactory()
+            : this(null)
+        {
+        }
+
+        public InMemoryTransientMessageFactory(InMemoryTransientMessageService transientMessageService)
+        {
+            this.transientMessageService = transientMessageService ?? new InMemoryTransientMessageService();
+            this.MqFactory = new MessageQueueClientFactory();
+        }
+
+        public IMessageProducer CreateMessageProducer()
+        {
+            return new InMemoryMessageProducer(this);
+        }
+
+        public IMessageQueueClient CreateMessageQueueClient()
+        {
+            return new InMemoryMessageQueueClient(MqFactory);
+        }
+
+        public IMessageService CreateMessageService()
+        {
+            return transientMessageService;
+        }
+
+        public void Dispose()
+        {
+            Log.DebugFormat("Disposing InMemoryTransientMessageFactory...");
+        }
+
+
+        internal class InMemoryMessageProducer
+            : IMessageProducer
+        {
+            private readonly InMemoryTransientMessageFactory parent;
+
+            public InMemoryMessageProducer(InMemoryTransientMessageFactory parent)
+            {
+                this.parent = parent;
+            }
+
+            public void Publish<T>(T messageBody)
+            {
+                Publish((IMessage<T>)new Message<T>(messageBody));
+            }
+
+            public void Publish<T>(IMessage<T> message)
+            {
+                this.parent.transientMessageService.MessageQueueFactory.PublishMessage(QueueNames<T>.In, message);
+            }
+
+            public void Dispose()
+            {
+                Log.DebugFormat("Disposing InMemoryMessageProducer...");
+            }
+        }
+
+    }
+}
+#endif
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Messaging/InMemoryTransientMessageService.cs b/lib/ServiceStack/src/ServiceStack.Common/Messaging/InMemoryTransientMessageService.cs
new file mode 100644
index 0000000..9712b8a
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Messaging/InMemoryTransientMessageService.cs
@@ -0,0 +1,40 @@
+#if !SILVERLIGHT 
+using System;
+using System.Collections;
+
+namespace ServiceStack.Messaging
+{
+    public class InMemoryTransientMessageService
+        : TransientMessageServiceBase
+    {
+        internal InMemoryTransientMessageFactory Factory { get; set; }
+
+        public InMemoryTransientMessageService()
+            : this(null)
+        {
+        }
+
+        public InMemoryTransientMessageService(InMemoryTransientMessageFactory factory)
+        {
+            this.Factory = factory ?? new InMemoryTransientMessageFactory(this);
+            this.Factory.MqFactory.MessageReceived += factory_MessageReceived;
+        }
+
+        void factory_MessageReceived(object sender, EventArgs e)
+        {
+            //var Factory = (MessageQueueClientFactory) sender;
+            this.Start();
+        }
+
+        public override IMessageFactory MessageFactory
+        {
+            get { return Factory; }
+        }
+
+        public MessageQueueClientFactory MessageQueueFactory
+        {
+            get { return Factory.MqFactory; }
+        }
+    }
+}
+#endif
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Messaging/MessageExtensions.cs b/lib/ServiceStack/src/ServiceStack.Common/Messaging/MessageExtensions.cs
new file mode 100644
index 0000000..ca5ba0d
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Messaging/MessageExtensions.cs
@@ -0,0 +1,88 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Threading;
+using ServiceStack.Text;
+
+namespace ServiceStack.Messaging
+{
+    public static class MessageExtensions
+    {
+        public static string ToString(byte[] bytes)
+        {
+#if !SILVERLIGHT 
+            return System.Text.Encoding.UTF8.GetString(bytes);
+#else
+            return System.Text.Encoding.UTF8.GetString(bytes, 0, bytes.Length);
+#endif
+        }
+
+        private static Dictionary<Type, ToMessageDelegate> ToMessageFnCache = new Dictionary<Type, ToMessageDelegate>();
+        internal static ToMessageDelegate GetToMessageFn(Type type)
+        {
+            ToMessageDelegate toMessageFn;
+            ToMessageFnCache.TryGetValue(type, out toMessageFn);
+
+            if (toMessageFn != null) return toMessageFn;
+
+            var genericType = typeof(MessageExtensions<>).MakeGenericType(type);
+            var mi = genericType.GetMethod("ConvertToMessage", BindingFlags.Public | BindingFlags.Static);
+            toMessageFn = (ToMessageDelegate)Delegate.CreateDelegate(typeof(ToMessageDelegate), mi);
+
+            Dictionary<Type, ToMessageDelegate> snapshot, newCache;
+            do
+            {
+                snapshot = ToMessageFnCache;
+                newCache = new Dictionary<Type, ToMessageDelegate>(ToMessageFnCache);
+                newCache[type] = toMessageFn;
+
+            } while (!ReferenceEquals(
+                Interlocked.CompareExchange(ref ToMessageFnCache, newCache, snapshot), snapshot));
+
+            return toMessageFn;
+        }
+
+        public static IMessage ToMessage(this byte[] bytes, Type ofType)
+        {
+            var msgFn = GetToMessageFn(ofType);
+            var msg = msgFn(bytes);
+            return msg;
+        }
+
+        public static Message<T> ToMessage<T>(this byte[] bytes)
+        {
+            var messageText = ToString(bytes);
+            return JsonSerializer.DeserializeFromString<Message<T>>(messageText);
+        }
+
+        public static byte[] ToBytes(this IMessage message)
+        {
+            var serializedMessage = JsonSerializer.SerializeToString((object)message);
+            return System.Text.Encoding.UTF8.GetBytes(serializedMessage);
+        }
+
+        public static byte[] ToBytes<T>(this IMessage<T> message)
+        {
+            var serializedMessage = JsonSerializer.SerializeToString(message);
+            return System.Text.Encoding.UTF8.GetBytes(serializedMessage);
+        }
+
+        public static string ToInQueueName<T>(this IMessage<T> message)
+        {
+            return message.Priority > 0
+                ? QueueNames<T>.Priority
+                : QueueNames<T>.In;
+        }
+    }
+
+    internal delegate IMessage ToMessageDelegate(object param);
+
+    internal static class MessageExtensions<T>
+    {
+        public static IMessage ConvertToMessage(object oBytes)
+        {
+            var bytes = (byte[]) oBytes;
+            return bytes.ToMessage<T>();
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Messaging/MessageHandler.cs b/lib/ServiceStack/src/ServiceStack.Common/Messaging/MessageHandler.cs
new file mode 100644
index 0000000..b7a7fbb
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Messaging/MessageHandler.cs
@@ -0,0 +1,220 @@
+using System;
+using System.Text;
+using ServiceStack.Common;
+using ServiceStack.Logging;
+using ServiceStack.Service;
+using ServiceStack.ServiceClient.Web;
+using ServiceStack.Text;
+using StringExtensions = ServiceStack.Common.StringExtensions;
+
+namespace ServiceStack.Messaging
+{
+    /// <summary>
+    /// Processes all messages in a Normal and Priority Queue.
+    /// Expects to be called in 1 thread. i.e. Non Thread-Safe.
+    /// </summary>
+    /// <typeparam name="T"></typeparam>
+    public class MessageHandler<T>
+        : IMessageHandler, IDisposable
+    {
+        private static readonly ILog Log = LogManager.GetLogger(typeof(MessageHandler<T>));
+
+        public const int DefaultRetryCount = 2; //Will be a total of 3 attempts
+        private readonly IMessageService messageService;
+        private readonly Func<IMessage<T>, object> processMessageFn;
+        private readonly Action<IMessage<T>, Exception> processInExceptionFn;
+        public Func<string, IOneWayClient> ReplyClientFactory { get; set; }
+        private readonly int retryCount;
+
+        public int TotalMessagesProcessed { get; private set; }
+        public int TotalMessagesFailed { get; private set; }
+        public int TotalRetries { get; private set; }
+        public int TotalNormalMessagesReceived { get; private set; }
+        public int TotalPriorityMessagesReceived { get; private set; }
+        public int TotalOutMessagesReceived { get; private set; }
+
+        public string[] ProcessQueueNames { get; set; }
+
+        public MessageHandler(IMessageService messageService,
+            Func<IMessage<T>, object> processMessageFn)
+            : this(messageService, processMessageFn, null, DefaultRetryCount) {}
+
+        private IMessageQueueClient MqClient { get; set; }
+
+        public MessageHandler(IMessageService messageService,
+            Func<IMessage<T>, object> processMessageFn,
+            Action<IMessage<T>, Exception> processInExceptionFn,
+            int retryCount)
+        {
+            if (messageService == null)
+                throw new ArgumentNullException("messageService");
+
+            if (processMessageFn == null)
+                throw new ArgumentNullException("processMessageFn");
+
+            this.messageService = messageService;
+            this.processMessageFn = processMessageFn;
+            this.processInExceptionFn = processInExceptionFn ?? DefaultInExceptionHandler;
+            this.retryCount = retryCount;
+            this.ReplyClientFactory = ClientFactory.Create;
+            this.ProcessQueueNames = new[] { QueueNames<T>.Priority, QueueNames<T>.In };
+        }
+
+        public Type MessageType
+        {
+            get { return typeof(T); }
+        }
+
+        public void Process(IMessageQueueClient mqClient)
+        {
+            foreach (var processQueueName in ProcessQueueNames)
+            {
+                ProcessQueue(mqClient, processQueueName);
+            }
+        }
+
+        public int ProcessQueue(IMessageQueueClient mqClient, string queueName, Func<bool> doNext = null)
+        {
+            var msgsProcessed = 0;
+            try
+            {
+                byte[] messageBytes;
+                while ((messageBytes = mqClient.GetAsync(queueName)) != null)
+                {
+                    var message = messageBytes.ToMessage<T>();
+                    ProcessMessage(mqClient, message);
+
+                    this.TotalNormalMessagesReceived++;
+                    msgsProcessed++;
+                    if (doNext != null && !doNext()) return msgsProcessed;
+                }
+            }
+            catch (Exception ex)
+            {
+                var lastEx = ex;
+                Log.Error("Error serializing message from mq server: " + lastEx.Message, ex);
+            }
+
+            return msgsProcessed;
+        }
+
+        public IMessageHandlerStats GetStats()
+        {
+            return new MessageHandlerStats(typeof(T).Name,
+                TotalMessagesProcessed, TotalMessagesFailed, TotalRetries, 
+                TotalNormalMessagesReceived, TotalPriorityMessagesReceived);
+        }
+
+        private void DefaultInExceptionHandler(IMessage<T> message, Exception ex)
+        {
+            Log.Error("Message exception handler threw an error", ex);
+
+            if (!(ex is UnRetryableMessagingException))
+            {
+                if (message.RetryAttempts < retryCount)
+                {
+                    message.RetryAttempts++;
+                    this.TotalRetries++;
+
+                    message.Error = new MessagingException(ex.Message, ex).ToMessageError();
+                    MqClient.Publish(QueueNames<T>.In, message.ToBytes());
+                    return;
+                }
+            }
+
+            MqClient.Publish(QueueNames<T>.Dlq, message.ToBytes());
+        }
+
+        public void ProcessMessage(IMessageQueueClient mqClient, Message<T> message)
+        {
+            this.MqClient = mqClient;
+
+            try
+            {
+                var response = processMessageFn(message);
+                var responseEx = response as Exception;
+                if (responseEx != null)
+                    throw responseEx;
+
+                this.TotalMessagesProcessed++;
+
+                //If there's no response publish the request message to its OutQ
+                if (response == null)
+                {
+                    var messageOptions = (MessageOption)message.Options;
+                    if (messageOptions.Has(MessageOption.NotifyOneWay))
+                    {
+                        mqClient.Notify(QueueNames<T>.Out, message.ToBytes());
+                    }
+                }
+                else
+                {
+                    //If there is a response send it to the typed response OutQ
+                    var mqReplyTo = message.ReplyTo;
+
+                    if (mqReplyTo == null)
+                    {
+                        var responseType = response.GetType();
+#if __MonoCS__
+                        // work around Mono 2.6.7 compiler bug:
+                        // System.Type.IsUserType' is inaccessible due to its protection level
+                        if (!StringExtensions.IsUserType(responseType)) return;
+#else
+                        if (!responseType.IsUserType()) return;
+#endif
+                        mqReplyTo = new QueueNames(responseType).In;
+                    }
+                    
+                    var replyClient = ReplyClientFactory(mqReplyTo);
+                    if (replyClient != null)
+                    {
+                        try
+                        {
+                            replyClient.SendOneWay(mqReplyTo, response);
+                            return;
+                        }
+                        catch (Exception ex)
+                        {
+                            Log.Error("Could not send response to '{0}' with client '{1}'"
+                                .Fmt(mqReplyTo, replyClient.GetType().Name), ex);
+
+                            var responseType = response.GetType();
+#if __MonoCS__
+                            if (!StringExtensions.IsUserType(responseType)) return;
+#else
+                            if (!responseType.IsUserType()) return;
+#endif
+
+                            mqReplyTo = new QueueNames(responseType).In;
+                        }
+                    }
+
+                    //Otherwise send to our trusty response Queue (inc if replyClient fails)
+                    var responseMessage = MessageFactory.Create(response);
+                    responseMessage.ReplyId = message.Id;
+                    mqClient.Publish(mqReplyTo, responseMessage.ToBytes());
+                }
+            }
+            catch (Exception ex)
+            {
+                try
+                {
+                    TotalMessagesFailed++;
+                    processInExceptionFn(message, ex);
+                }
+                catch (Exception exHandlerEx)
+                {
+                    Log.Error("Message exception handler threw an error", exHandlerEx);
+                }
+            }
+        }
+
+        public void Dispose()
+        {
+            var shouldDispose = messageService as IMessageHandlerDisposer;
+            if (shouldDispose != null)
+                shouldDispose.DisposeMessageHandler(this);
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Messaging/MessageHandlerFactory.cs b/lib/ServiceStack/src/ServiceStack.Common/Messaging/MessageHandlerFactory.cs
new file mode 100644
index 0000000..42345f8
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Messaging/MessageHandlerFactory.cs
@@ -0,0 +1,62 @@
+using System;
+
+namespace ServiceStack.Messaging
+{
+    public class MessageHandlerFactory<T>
+        : IMessageHandlerFactory
+    {
+        public const int DefaultRetryCount = 2; //Will be a total of 3 attempts
+        private readonly IMessageService messageService;
+
+        public Func<IMessage, IMessage> RequestFilter { get; set; }
+        public Func<object, object> ResponseFilter { get; set; }
+
+        private readonly Func<IMessage<T>, object> processMessageFn;
+        private readonly Action<IMessage<T>, Exception> processExceptionFn;
+        public int RetryCount { get; set; }
+
+        public MessageHandlerFactory(IMessageService messageService, Func<IMessage<T>, object> processMessageFn)
+            : this(messageService, processMessageFn, null)
+        {
+        }
+
+        public MessageHandlerFactory(IMessageService messageService, 
+            Func<IMessage<T>, object> processMessageFn,
+            Action<IMessage<T>, Exception> processExceptionEx)
+        {
+            if (messageService == null)
+                throw new ArgumentNullException("messageService");
+
+            if (processMessageFn == null)
+                throw new ArgumentNullException("processMessageFn");
+
+            this.messageService = messageService;
+            this.processMessageFn = processMessageFn;
+            this.processExceptionFn = processExceptionEx;
+            this.RetryCount = DefaultRetryCount;
+        }
+
+        public IMessageHandler CreateMessageHandler()
+        {
+            if (this.RequestFilter == null && this.ResponseFilter == null)
+            {
+                return new MessageHandler<T>(messageService, processMessageFn, 
+                    processExceptionFn, this.RetryCount);
+            }
+
+            return new MessageHandler<T>(messageService, msg => 
+                {
+                    if (this.RequestFilter != null)
+                        msg = (IMessage<T>) this.RequestFilter(msg);
+
+                    var result = this.processMessageFn(msg);
+
+                    if (this.ResponseFilter != null)
+                        result = this.ResponseFilter(result);
+
+                    return result;
+                },
+                processExceptionFn, this.RetryCount);
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Messaging/MessageQueueClientFactory.cs b/lib/ServiceStack/src/ServiceStack.Common/Messaging/MessageQueueClientFactory.cs
new file mode 100644
index 0000000..617960c
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Messaging/MessageQueueClientFactory.cs
@@ -0,0 +1,68 @@
+using System;
+using System.Collections.Generic;
+
+namespace ServiceStack.Messaging
+{
+    public class MessageQueueClientFactory
+        : IMessageQueueClientFactory
+    {
+        public IMessageQueueClient CreateMessageQueueClient()
+        {
+            return new InMemoryMessageQueueClient(this);
+        }
+
+        readonly object syncLock = new object();
+
+        public event EventHandler<EventArgs> MessageReceived;
+
+        void InvokeMessageReceived(EventArgs e)
+        {
+            var received = MessageReceived;
+            if (received != null) received(this, e);
+        }
+
+        private readonly Dictionary<string, Queue<byte[]>> queueMessageBytesMap
+            = new Dictionary<string, Queue<byte[]>>();
+
+        public void PublishMessage<T>(string queueName, IMessage<T> message)
+        {
+            PublishMessage(queueName, message.ToBytes());
+        }
+
+        public void PublishMessage(string queueName, byte[] messageBytes)
+        {
+            lock (syncLock)
+            {
+                Queue<byte[]> bytesQueue;
+                if (!queueMessageBytesMap.TryGetValue(queueName, out bytesQueue))
+                {
+                    bytesQueue = new Queue<byte[]>();
+                    queueMessageBytesMap[queueName] = bytesQueue;
+                }
+
+                bytesQueue.Enqueue(messageBytes);
+            }
+
+            InvokeMessageReceived(new EventArgs());
+        }
+
+        public byte[] GetMessageAsync(string queueName)
+        {
+            lock (syncLock)
+            {
+                Queue<byte[]> bytesQueue;
+                if (!queueMessageBytesMap.TryGetValue(queueName, out bytesQueue))
+                {
+                    return null;
+                }
+
+                var messageBytes = bytesQueue.Dequeue();
+                return messageBytes;
+            }
+        }
+
+        public void Dispose()
+        {
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Messaging/Rcon/Client.cs b/lib/ServiceStack/src/ServiceStack.Common/Messaging/Rcon/Client.cs
new file mode 100644
index 0000000..e6adb15
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Messaging/Rcon/Client.cs
@@ -0,0 +1,315 @@
+#if !SILVERLIGHT 
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Net;
+using System.Net.Sockets;
+using System.Threading;
+
+namespace ServiceStack.Messaging.Rcon
+{
+    /// <summary>
+    /// Base rcon class.
+    /// </summary>
+    public class Client
+    {
+        #region Delegates
+
+        /// <summary>
+        /// Event delegate when disconnected from the server.
+        /// </summary>
+        /// <param name="rcon"></param>
+        public delegate void OnDisconnectedHandler(Client rcon);
+
+        /// <summary>
+        /// Delegate for async callbacks.
+        /// </summary>
+        /// <param name="rcon"></param>
+        /// <param name="packet"></param>
+        public delegate void AsyncCallback(Client rcon, byte[] response);
+
+        #endregion
+
+        #region Events
+
+        /// <summary>
+        /// Disconnected event.
+        /// </summary>
+        public event OnDisconnectedHandler OnDisconnected;
+
+        #endregion
+
+        #region Fields
+
+        /// <summary>
+        /// Rcon connection socket. Always set to null when not connected.
+        /// </summary>
+        Socket _sock = null;
+
+        /// <summary>
+        /// Unique ID for each message.
+        /// </summary>
+        uint _sequenceID = 1;
+
+        /// <summary>
+        /// Registered callbacks.
+        /// </summary>
+        Dictionary<uint, AsyncCallback> _registeredCallbacks = new Dictionary<uint, AsyncCallback>();
+
+        #endregion
+
+        #region Methods
+
+        /// <summary>
+        /// Create a new instance of rcon.
+        /// </summary>
+        /// <param name="rconEndpoint">Endpoint to connect to, usually the game server with query port.</param>
+        public Client(IPEndPoint rconEndpoint)
+        {
+            Endpoint = rconEndpoint;
+            Connected = false;
+        }
+
+        /// <summary>
+        /// Attempts to connect to the game server for rcon operations.
+        /// </summary>
+        /// <returns>True if connection established, false otherwise.</returns>
+        public virtual bool Connect()
+        {
+            if (Connected)
+                Disconnect();
+
+            Connected = false;
+            _sequenceID = 1;
+
+            try
+            {
+                _sock = new Socket(Endpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
+                _sock.Connect(Endpoint);
+
+                var readEventArgs = new SocketAsyncEventArgs();
+                var state = new ClientSocketState();
+                readEventArgs.UserToken = state;
+                readEventArgs.SetBuffer(state.Header, 0, state.Header.Length);
+                readEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(readEventArgs_Completed);
+
+                if (!_sock.ReceiveAsync(readEventArgs))
+                {
+                    ProcessReceive(_sock, readEventArgs);
+                }
+
+                Connected = true;
+                return true;
+            }
+            catch (Exception ex)
+            {
+                LastException = ex;
+            }
+            Disconnect();
+            return false;
+        }
+
+        void readEventArgs_Completed(object sender, SocketAsyncEventArgs e)
+        {
+            ProcessReceive((Socket)sender, e);
+        }
+
+        void ProcessReceive(Socket readingSock, SocketAsyncEventArgs e)
+        {
+            var userToken = (ClientSocketState)e.UserToken;
+            if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
+            {
+                if (!userToken.ReadHeader)
+                {
+                    //  if we've filled the buffer we can decode the header
+                    if (e.Offset + e.BytesTransferred == userToken.Header.Length)
+                    {
+                        userToken.ReadHeader = true;
+                        userToken.MessageLength = BitConverter.ToUInt32(userToken.Header, 4);
+                        userToken.CompleteMessage = new byte[userToken.MessageLength];
+                        for (int i = 0; i < userToken.Header.Length; i++)
+                        {
+                            userToken.CompleteMessage[i] = userToken.Header[i];
+                        }
+                        e.SetBuffer(userToken.CompleteMessage, userToken.Header.Length, userToken.CompleteMessage.Length - userToken.Header.Length);
+
+                        if (!readingSock.ReceiveAsync(e))
+                        {
+                            ProcessReceive(readingSock, e);
+                        }
+                    }
+                    else
+                    {
+                        if (!readingSock.ReceiveAsync(e))
+                        {
+                            ProcessReceive(readingSock, e);
+                        }
+                    }
+                }
+                else
+                {
+                    if (e.Offset + e.BytesTransferred == userToken.MessageLength)
+                    {
+                        //  copy buffer
+                        var fullPacket = userToken.CompleteMessage;
+
+                        //  reset state
+                        userToken.ReadHeader = false;
+                        userToken.MessageLength = 0;
+
+                        //  process the message
+                        ProcessPacket(fullPacket, userToken);
+
+                        //  start listening for more packets
+                        e.SetBuffer(userToken.Header, 0, userToken.Header.Length);
+                        if (!readingSock.ReceiveAsync(e))
+                        {
+                            ProcessReceive(readingSock, e);
+                        }
+                    }
+                    else
+                    {
+                        if (!readingSock.ReceiveAsync(e))
+                        {
+                            ProcessReceive(readingSock, e);
+                        }
+                    }
+                }
+            }
+            else
+            {
+                //  socket disconnected
+                Disconnect();
+            }
+        }
+
+        /// <summary>
+        /// Processes a received packet.
+        /// </summary>
+        /// <param name="packet">The packet.</param>
+        void ProcessPacket(byte[] packet, ClientSocketState userToken)
+        {
+            var packetObj = PacketCodec.DecodePacket(packet);
+            if (_registeredCallbacks.ContainsKey(packetObj.Sequence))
+            {
+                var callback = _registeredCallbacks[packetObj.Sequence];
+                _registeredCallbacks.Remove(packetObj.Sequence);
+                if (packetObj.Words.Length < 3)
+                {
+                    callback(this, null);
+                }
+                else
+                {
+                    callback(this, packetObj.Words[2]);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Disconnects from rcon.
+        /// </summary>
+        public virtual void Disconnect()
+        {
+            Connected = false;
+            _sequenceID = 1;
+
+            if (_sock != null)
+            {
+                if (OnDisconnected != null)
+                    OnDisconnected(this);
+
+                //  these exceptions aren't really anything to worry about
+                try
+                {
+                    _sock.Close();
+                }
+                catch (Exception) { }
+
+                _sock = null;
+            }
+        }
+
+        public void Call<T>(T request, AsyncCallback callback)
+        {
+            _registeredCallbacks[_sequenceID] = callback;
+            IMessage<T> message = new Message<T>(request);
+            InternalSend(new byte[][]{ Encoding.UTF8.GetBytes(request.GetType().AssemblyQualifiedName), message.ToBytes() });
+        }
+
+        /// <summary>
+        /// Sends message to the server.
+        /// </summary>
+        /// <param name="words">Words to send.</param>
+        protected virtual void InternalSend(byte[][] words)
+        {
+            if (!Connected)
+            {
+                LastException = new NotConnectedException();
+                throw LastException;
+            }
+
+            var packet = PacketCodec.EncodePacket(false, false, _sequenceID++, words);
+            try
+            {
+                var sendEventArgs = new SocketAsyncEventArgs();
+                sendEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(sendEventArgs_Completed);
+                sendEventArgs.SetBuffer(packet, 0, packet.Length);
+                _sock.SendAsync(sendEventArgs);
+            }
+            catch (Exception ex)
+            {
+                Disconnect();
+                LastException = ex;
+                throw LastException;
+            }
+        }
+
+        void sendEventArgs_Completed(object sender, SocketAsyncEventArgs e)
+        {
+            ProcessSend((Socket)sender, e);
+        }
+
+        void ProcessSend(Socket sock, SocketAsyncEventArgs e)
+        {
+            if (e.SocketError != SocketError.Success)
+            {
+                Disconnect();
+            }
+        }
+
+        #endregion
+
+        #region Properties
+
+        /// <summary>
+        /// Game server endpoint.
+        /// </summary>
+        public IPEndPoint Endpoint { get; protected set; }
+
+        /// <summary>
+        /// Last exception that occured during operation.
+        /// </summary>
+        public Exception LastException { get; protected set; }
+
+        /// <summary>
+        /// Connected?
+        /// </summary>
+        public bool Connected { get; protected set; }
+
+        /// <summary>
+        /// Gets the next unique ID to be used for transmisson. Read this before sending to pair responses to sent messages.
+        /// </summary>
+        public uint SequenceID { get { return _sequenceID; } }
+
+        #endregion
+    }
+
+    /// <summary>
+    /// Exception thrown when attempting to send on a non-connected service client.
+    /// </summary>
+    public class NotConnectedException : Exception
+    {
+    }
+}
+#endif
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Messaging/Rcon/Packet.cs b/lib/ServiceStack/src/ServiceStack.Common/Messaging/Rcon/Packet.cs
new file mode 100644
index 0000000..3220f01
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Messaging/Rcon/Packet.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace ServiceStack.Messaging.Rcon
+{
+    internal class Packet
+    {
+        /// <summary>
+        /// True if the packet originated on the server.
+        /// </summary>
+        public bool FromServer { get; internal set; }
+
+        /// <summary>
+        /// True if the packet is a response from a sent packet.
+        /// </summary>
+        public bool IsResponse { get; internal set; }
+
+        /// <summary>
+        /// Sequence identifier. Unique to the connection.
+        /// </summary>
+        public uint Sequence { get; internal set; }
+
+        /// <summary>
+        /// Words.
+        /// </summary>
+        public byte[][] Words { get; internal set; }
+    }
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Messaging/Rcon/PacketCodec.cs b/lib/ServiceStack/src/ServiceStack.Common/Messaging/Rcon/PacketCodec.cs
new file mode 100644
index 0000000..9ee52e2
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Messaging/Rcon/PacketCodec.cs
@@ -0,0 +1,152 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace ServiceStack.Messaging.Rcon
+{
+    /// <summary>
+    /// Contains methods required for encoding and decoding rcon packets.
+    /// </summary>
+    internal class PacketCodec
+    {
+        /// <summary>
+        /// Decodes a packet.
+        /// </summary>
+        /// <param name="packet">The packet.</param>
+        /// <returns>A packet object.</returns>
+        internal static Packet DecodePacket(byte[] packet)
+        {
+            var header = DecodeHeader(packet);
+            var words = DecodeWords(packet);
+
+            bool fromServer = false;
+            if (header[0] > 0)
+                fromServer = true;
+            bool isResponse = false;
+            if (header[1] > 0)
+                isResponse = true;
+            uint idNumber = 0;
+            if (header[2] > 0)
+                idNumber = header[2];
+
+            return new Packet()
+            {
+                FromServer = fromServer,
+                IsResponse = isResponse,
+                Sequence = idNumber,
+                Words = words
+            };
+        }
+
+        /// <summary>
+        /// Decodes the packet header.
+        /// </summary>
+        /// <param name="packet"></param>
+        /// <returns></returns>
+        private static uint[] DecodeHeader(byte[] packet)
+        {
+            var x = BitConverter.ToUInt32(packet, 0);
+            return new uint[] { x & 0x80000000, x & 0x40000000, x & 0x3FFFFFFF };
+        }
+
+        /// <summary>
+        /// Decodes words in a packet.
+        /// </summary>
+        /// <param name="packet"></param>
+        /// <returns></returns>
+        private static byte[][] DecodeWords(byte[] packet)
+        {
+            var wordCount = BitConverter.ToUInt32(packet, 8);
+            var words = new byte[wordCount][];
+            var wordIndex = 0;
+            int offset = 12;
+            for (int i = 0; i < wordCount; i++)
+            {
+                var wordLen = BitConverter.ToInt32(packet, offset);
+                var word = new byte[wordLen];
+                for (int j = 0; j < wordLen; j++)
+                {
+                    word[j] = packet[offset + 4 + j];
+                }
+                words[wordIndex++] = word;
+                offset += 5 + wordLen;
+            }
+            return words;
+        }
+
+        /// <summary>
+        /// Encodes a packet for transmission to the server.
+        /// </summary>
+        /// <param name="fromServer"></param>
+        /// <param name="isResponse"></param>
+        /// <param name="id"></param>
+        /// <param name="words"></param>
+        /// <returns></returns>
+        internal static byte[] EncodePacket(bool fromServer, bool isResponse, uint id, byte[][] words)
+        {
+            /*
+             * Packet format:
+             * 0 - 3 = header
+             * 4 - 7 = size of packet
+             * 8 -11 = number of words
+             * 12+   = words
+             * 
+             * Word format:
+             * 0 - 3 = word length
+             * 4 - n = word
+             * n+1   = null (0x0)
+             */
+            var encodedHeader = EncodeHeader(fromServer, isResponse, id);
+            var encodedWordCount = BitConverter.GetBytes((uint)words.Length);
+            var encodedWords = EncodeWords(words);
+            var encodedPacketSize = BitConverter.GetBytes((uint)(encodedHeader.Length + encodedWordCount.Length + encodedWords.Length + 4));  //  +4 for the packet size indicator
+
+            var packet = new List<byte>();
+            packet.AddRange(encodedHeader);
+            packet.AddRange(encodedPacketSize);
+            packet.AddRange(encodedWordCount);
+            packet.AddRange(encodedWords);
+            return packet.ToArray();
+        }
+
+        /// <summary>
+        /// Encodes a packet header.
+        /// </summary>
+        /// <param name="fromServer"></param>
+        /// <param name="isResponse"></param>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        private static byte[] EncodeHeader(bool fromServer, bool isResponse, uint id)
+        {
+            uint header = id & 0x3FFFFFFF;
+            if (fromServer)
+                header += 0x80000000;
+            if (isResponse)
+                header += 0x40000000;
+            return BitConverter.GetBytes(header);
+        }
+
+        /// <summary>
+        /// Encodes words.
+        /// </summary>
+        /// <param name="words"></param>
+        /// <returns></returns>
+        private static byte[] EncodeWords(byte[][] words)
+        {
+            var wordPacket = new List<byte>();
+            foreach (var word in words)
+            {
+                var encodedWord = new List<byte>();
+                encodedWord.AddRange(word);
+                encodedWord.Add(0);
+
+                var encodedLength = BitConverter.GetBytes((uint)word.Length);
+
+                wordPacket.AddRange(encodedLength);
+                wordPacket.AddRange(encodedWord);
+            }
+            return wordPacket.ToArray();
+        }
+    }
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Messaging/Rcon/PacketProcessingClient.cs b/lib/ServiceStack/src/ServiceStack.Common/Messaging/Rcon/PacketProcessingClient.cs
new file mode 100644
index 0000000..5b59434
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Messaging/Rcon/PacketProcessingClient.cs
@@ -0,0 +1,108 @@
+#if !SILVERLIGHT 
+using System;
+using System.Collections.Generic;
+using ServiceStack.Messaging;
+using System.Net.Sockets;
+using System.Text;
+
+namespace ServiceStack.Messaging.Rcon
+{
+    /// <summary>
+    /// Processing client used to interface with ServiceStack and allow a message to be processed.
+    /// Not an actual client.
+    /// </summary>
+    internal class ProcessingClient : IMessageQueueClient
+    {
+        Packet thePacket;
+        Socket theClient;
+        Server theServer;
+        bool givenPacket = false;
+
+        public ProcessingClient(Packet packet, Socket client, Server server)
+        {
+            thePacket = packet;
+            theClient = client;
+            theServer = server;
+        }
+
+        public void Publish<T>(T messageBody)
+        {
+            if (typeof(IMessage).IsAssignableFrom(typeof(T)))
+                Publish((IMessage)messageBody);
+            else
+                Publish<T>(new Message<T>(messageBody));
+        }
+
+        public void Publish(IMessage message)
+        {
+            var messageBytes = message.ToBytes();
+            Publish(new QueueNames(message.Body.GetType()).In, messageBytes);
+        }
+
+        public void Publish<T>(IMessage<T> message)
+        {
+            var messageBytes = message.ToBytes();
+            Publish(message.ToInQueueName(), messageBytes);
+        }
+
+        /// <summary>
+        /// Publish the specified message into the durable queue @queueName
+        /// </summary>
+        /// <param name="queueName"></param>
+        /// <param name="messageBytes"></param>
+        public void Publish(string queueName, byte[] messageBytes)
+        {
+            theServer.Publish(queueName, messageBytes, theClient, thePacket.Sequence);
+        }
+        
+        /// <summary>
+        /// Publish the specified message into the transient queue @queueName
+        /// </summary>
+        /// <param name="queueName"></param>
+        /// <param name="messageBytes"></param>
+        public void Notify(string queueName, byte[] messageBytes)
+        {
+            theServer.Notify(queueName, messageBytes, theClient, thePacket.Sequence);
+        }
+
+        /// <summary>
+        /// Synchronous blocking get.
+        /// </summary>
+        /// <param name="queueName"></param>
+        /// <param name="timeOut"></param>
+        /// <returns></returns>
+        public byte[] Get(string queueName, TimeSpan? timeOut)
+        {
+            if (givenPacket)
+                return null;
+            var ret = thePacket.Words[1];
+            givenPacket = true;
+            return ret;
+        }
+        
+        /// <summary>
+        /// Non blocking get message
+        /// </summary>
+        /// <param name="queueName"></param>
+        /// <returns></returns>
+        public byte[] GetAsync(string queueName)
+        {
+            return Get(queueName, TimeSpan.MinValue);
+        }
+
+        /// <summary>
+        /// Blocking wait for notifications on any of the supplied channels
+        /// </summary>
+        /// <param name="channelNames"></param>
+        /// <returns></returns>
+        public string WaitForNotifyOnAny(params string[] channelNames)
+        {
+            return null;
+        }
+
+        public void Dispose()
+        {
+        }
+    }
+}
+#endif
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Messaging/Rcon/Server.cs b/lib/ServiceStack/src/ServiceStack.Common/Messaging/Rcon/Server.cs
new file mode 100644
index 0000000..b2c024a
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Messaging/Rcon/Server.cs
@@ -0,0 +1,321 @@
+#if !SILVERLIGHT
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Net.Sockets;
+using System.Linq;
+using System.Threading;
+using System.Text;
+using ServiceStack.Messaging;
+
+namespace ServiceStack.Messaging.Rcon
+{
+    /// <summary>
+    /// Hosting services via a binary-safe TCP-based protocol.
+    /// </summary>
+    public class Server : IMessageService
+    {
+        private readonly Dictionary<Type, IMessageHandlerFactory> handlerMap
+            = new Dictionary<Type, IMessageHandlerFactory>();
+        private Dictionary<Type, IMessageHandler> messageHandlers = new Dictionary<Type,IMessageHandler>();
+
+        Socket _listener = null;
+        IPEndPoint _localEndpoint = null;
+
+        public Server(IPEndPoint localEndpoint)
+        {
+            _localEndpoint = localEndpoint;
+        }
+
+        #region IMessageService Members
+
+        /// <summary>
+        /// Factory to create consumers and producers that work with this service
+        /// </summary>
+        public IMessageFactory MessageFactory { get; private set; }
+
+        /// <summary>
+        /// Register DTOs and hanlders the MQ Host will process
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="processMessageFn"></param>
+        public void RegisterHandler<T>(Func<IMessage<T>, object> processMessageFn)
+        {
+            RegisterHandler(processMessageFn, null);
+        }
+
+        public void RegisterHandler<T>(Func<IMessage<T>, object> processMessageFn, Action<IMessage<T>, Exception> processExceptionEx)
+        {
+            if (handlerMap.ContainsKey(typeof(T)))
+            {
+                throw new ArgumentException("Message handler has already been registered for type: " + typeof(T).Name);
+            }
+
+            handlerMap[typeof(T)] = CreateMessageHandlerFactory(processMessageFn, processExceptionEx);
+        }
+
+        protected IMessageHandlerFactory CreateMessageHandlerFactory<T>(Func<IMessage<T>, object> processMessageFn, Action<IMessage<T>, Exception> processExceptionEx)
+        {
+            return new MessageHandlerFactory<T>(this, processMessageFn, processExceptionEx);
+        }
+
+        public IMessageHandlerStats GetStats()
+        {
+            return null;
+        }
+
+        /// <summary>
+        /// Get Total Current Stats for all Message Handlers
+        /// </summary>
+        /// <returns></returns>
+        public string GetStatus()
+        {
+            return null;
+        }
+
+        /// <summary>
+        /// Get a Stats dump
+        /// </summary>
+        /// <returns></returns>
+        public string GetStatsDescription()
+        {
+            return null;
+        }
+
+        /// <summary>
+        /// Start the MQ Host. Stops the server and restarts if already started.
+        /// </summary>
+        public void Start()
+        {
+            if (this.messageHandlers.Count == 0)
+            {
+                foreach (var kvp in this.handlerMap)
+                {
+                    this.messageHandlers[kvp.Key] = kvp.Value.CreateMessageHandler();
+                }
+            }
+
+            Stop();
+
+            _listener = new Socket(_localEndpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
+            _listener.Bind(_localEndpoint);
+            _listener.Listen(60);
+            var acceptArgs = new SocketAsyncEventArgs();
+            acceptArgs.Completed += new EventHandler<SocketAsyncEventArgs>(acceptArgs_Completed);
+            if (!_listener.AcceptAsync(acceptArgs))
+            {
+                ProcessAccept(_listener, acceptArgs);
+            }
+        }
+
+        /// <summary>
+        /// Stop the MQ Host if not already stopped. 
+        /// </summary>
+        public void Stop()
+        {
+            if (_listener != null)
+            {
+                _listener.Close();
+                _listener = null;
+            }
+        }
+
+        #endregion
+
+        public void Dispose()
+        {
+            if (_listener != null)
+            {
+                try
+                {
+                    _listener.Shutdown(SocketShutdown.Send);
+                    _listener.Close();
+                }
+                catch (Exception) { }
+            }
+        }
+
+        public void Notify(string queueName, byte[] message, Socket client, uint sequenceID)
+        {
+            var words = new byte[][] { Encoding.UTF8.GetBytes("notify"), Encoding.UTF8.GetBytes(queueName), message };
+            var sendToClient = PacketCodec.EncodePacket(false, true, sequenceID, words);
+            Send(sendToClient, client);
+        }
+
+        public void Publish(string queueName, byte[] message, Socket client, uint sequenceID)
+        {
+            var words = new byte[][] { Encoding.UTF8.GetBytes("publish"), Encoding.UTF8.GetBytes(queueName), message };
+            var sendToClient = PacketCodec.EncodePacket(false, true, sequenceID, words);
+            Send(sendToClient, client);
+        }
+
+        void acceptArgs_Completed(object sender, SocketAsyncEventArgs e)
+        {
+            ProcessAccept((Socket)sender, e);
+        }
+
+        void ProcessAccept(Socket serverSock, SocketAsyncEventArgs e)
+        {
+            var newSocket = e.AcceptSocket;
+            var readEventArgs = new SocketAsyncEventArgs();
+            var state = new ClientSocketState();
+            readEventArgs.UserToken = state;
+            readEventArgs.SetBuffer(state.Header, 0, state.Header.Length);
+            readEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(readEventArgs_Completed);
+
+            if (!newSocket.ReceiveAsync(readEventArgs))
+            {
+                ProcessReceive(newSocket, readEventArgs);
+            }
+
+            e.AcceptSocket = null;
+            serverSock.AcceptAsync(e);
+        }
+
+        void readEventArgs_Completed(object sender, SocketAsyncEventArgs e)
+        {
+            ProcessReceive((Socket)sender, e);
+        }
+
+        void ProcessReceive(Socket readingSock, SocketAsyncEventArgs e)
+        {
+            var userToken = (ClientSocketState)e.UserToken;
+            if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
+            {
+                if (!userToken.ReadHeader)
+                {
+                    //  if we've filled the buffer we can decode the header
+                    if (e.Offset + e.BytesTransferred == userToken.Header.Length)
+                    {
+                        userToken.ReadHeader = true;
+                        userToken.MessageLength = BitConverter.ToUInt32(userToken.Header, 4);
+                        userToken.CompleteMessage = new byte[userToken.MessageLength];
+                        for (int i = 0; i < userToken.Header.Length; i++)
+                        {
+                            userToken.CompleteMessage[i] = userToken.Header[i];
+                        }
+                        e.SetBuffer(userToken.CompleteMessage, userToken.Header.Length, userToken.CompleteMessage.Length - userToken.Header.Length);
+
+                        if (!readingSock.ReceiveAsync(e))
+                        {
+                            ProcessReceive(readingSock, e);
+                        }
+                    }
+                    else
+                    {
+                        if (!readingSock.ReceiveAsync(e))
+                        {
+                            ProcessReceive(readingSock, e);
+                        }
+                    }
+                }
+                else
+                {
+                    if (e.Offset + e.BytesTransferred == userToken.MessageLength)
+                    {
+                        //  copy buffer
+                        var fullPacket = userToken.CompleteMessage;
+
+                        //  reset state
+                        userToken.ReadHeader = false;
+                        userToken.MessageLength = 0;
+
+                        //  process the message
+                        ThreadPool.QueueUserWorkItem(delegate
+                        {
+                            ProcessPacket(fullPacket, readingSock, userToken);
+                        });
+
+                        //  start listening for more packets
+                        e.SetBuffer(userToken.Header, 0, userToken.Header.Length);
+                        if (!readingSock.ReceiveAsync(e))
+                        {
+                            ProcessReceive(readingSock, e);
+                        }
+                    }
+                    else
+                    {
+                        if (!readingSock.ReceiveAsync(e))
+                        {
+                            ProcessReceive(readingSock, e);
+                        }
+                    }
+                }
+            }
+            else
+            {
+                //  socket disconnected
+                ClientDisconnected(readingSock);
+            }
+        }
+
+        /// <summary>
+        /// Processes a received packet.
+        /// </summary>
+        /// <param name="packet">The packet.</param>
+        void ProcessPacket(byte[] packet, Socket client, ClientSocketState userToken)
+        {
+            var packetObj = PacketCodec.DecodePacket(packet);
+#if !SILVERLIGHT 
+            var type = Type.GetType(Encoding.UTF8.GetString(packetObj.Words[0]));
+#else
+            var bytes = packetObj.Words[0];
+            var type = Type.GetType(Encoding.UTF8.GetString(bytes, 0, bytes.Length));
+#endif
+
+            if (messageHandlers.ContainsKey(type))
+            {
+                messageHandlers[type].Process(new ProcessingClient(packetObj, client, this));
+            }
+        }
+
+        void Send(byte[] data, Socket client)
+        {
+            var sendEventArgs = new SocketAsyncEventArgs();
+            sendEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(sendEventArgs_Completed);
+            sendEventArgs.SetBuffer(data, 0, data.Length);
+            client.SendAsync(sendEventArgs);
+        }
+
+        void sendEventArgs_Completed(object sender, SocketAsyncEventArgs e)
+        {
+            ProcessSend((Socket)sender, e);
+        }
+
+        void ProcessSend(Socket sock, SocketAsyncEventArgs e)
+        {
+            if (e.SocketError != SocketError.Success)
+            {
+                ClientDisconnected(sock);
+            }
+        }
+
+        void ClientDisconnected(Socket sock)
+        {
+            if (sock != null)
+            {
+                try
+                {
+                    sock.Shutdown(SocketShutdown.Send);
+                }
+                catch (Exception) { }
+
+                try
+                {
+                    sock.Close();
+                }
+                catch (Exception) { }
+            }
+        }
+    }
+
+    public class ClientSocketState
+    {
+        public byte[] Header = new byte[8];
+        public byte[] CompleteMessage = new byte[0];
+        public bool ReadHeader = false;
+        public uint MessageLength = 0;
+    }
+}
+
+#endif
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Messaging/TransientMessageServiceBase.cs b/lib/ServiceStack/src/ServiceStack.Common/Messaging/TransientMessageServiceBase.cs
new file mode 100644
index 0000000..63e8b2b
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Messaging/TransientMessageServiceBase.cs
@@ -0,0 +1,142 @@
+#if !SILVERLIGHT 
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace ServiceStack.Messaging
+{
+    public abstract class TransientMessageServiceBase
+        : IMessageService, IMessageHandlerDisposer
+    {
+        private bool isRunning;
+        public const int DefaultRetryCount = 2; //Will be a total of 3 attempts
+
+        public int RetryCount { get; protected set; }
+        public TimeSpan? RequestTimeOut { get; protected set; }
+
+        public int PoolSize { get; protected set; } //use later
+
+        public abstract IMessageFactory MessageFactory { get; }
+
+        protected TransientMessageServiceBase()
+            : this(DefaultRetryCount, null)
+        {
+        }
+
+        protected TransientMessageServiceBase(int retryAttempts, TimeSpan? requestTimeOut)
+        {
+            this.RetryCount = retryAttempts;
+            this.RequestTimeOut = requestTimeOut;
+        }
+
+        private readonly Dictionary<Type, IMessageHandlerFactory> handlerMap
+            = new Dictionary<Type, IMessageHandlerFactory>();
+
+        private IMessageHandler[] messageHandlers;
+
+        public void RegisterHandler<T>(Func<IMessage<T>, object> processMessageFn)
+        {
+            RegisterHandler(processMessageFn, null);
+        }
+
+        public void RegisterHandler<T>(Func<IMessage<T>, object> processMessageFn,
+            Action<IMessage<T>, Exception> processExceptionEx)
+        {
+            if (handlerMap.ContainsKey(typeof(T)))
+            {
+                throw new ArgumentException("Message handler has already been registered for type: " + typeof(T).Name);
+            }
+
+            handlerMap[typeof(T)] = CreateMessageHandlerFactory(processMessageFn, processExceptionEx);
+        }
+
+        public IMessageHandlerStats GetStats()
+        {
+            var total = new MessageHandlerStats("All Handlers");
+            messageHandlers.ToList().ForEach(x => total.Add(x.GetStats()));
+            return total;
+        }
+
+        public string GetStatus()
+        {
+            return isRunning ? "Started" : "Stopped";
+        }
+
+        public string GetStatsDescription()
+        {
+            var sb = new StringBuilder("#MQ HOST STATS:\n");
+            sb.AppendLine("===============");
+            foreach (var messageHandler in messageHandlers)
+            {
+                sb.AppendLine(messageHandler.GetStats().ToString());
+                sb.AppendLine("---------------");
+            }
+            return sb.ToString();
+        }
+
+        protected IMessageHandlerFactory CreateMessageHandlerFactory<T>(
+            Func<IMessage<T>, object> processMessageFn, 
+            Action<IMessage<T>, Exception> processExceptionEx)
+        {
+            return new MessageHandlerFactory<T>(this, processMessageFn, processExceptionEx) {
+                RetryCount = RetryCount,
+            };
+        }
+
+        public virtual void Start()
+        {
+            if (isRunning) return;
+            isRunning = true;
+
+            this.messageHandlers = this.handlerMap.Values.ToList().ConvertAll(
+                x => x.CreateMessageHandler()).ToArray();
+
+            using (var mqClient = MessageFactory.CreateMessageQueueClient())
+            {
+                foreach (var handler in messageHandlers)
+                {
+                    handler.Process(mqClient);
+                }
+            }
+
+            this.Stop();
+        }
+
+        public virtual void Stop()
+        {
+            isRunning = false;
+            messageHandlers = null;
+        }
+
+        public virtual void Dispose()
+        {
+            Stop();
+        }
+
+        public virtual void DisposeMessageHandler(IMessageHandler messageHandler)
+        {
+            lock (messageHandlers)
+            {
+                if (!isRunning) return;
+
+                var allHandlersAreDisposed = true;
+                for (var i = 0; i < messageHandlers.Length; i++)
+                {
+                    if (messageHandlers[i] == messageHandler)
+                    {
+                        messageHandlers[i] = null;
+                    }
+                    allHandlersAreDisposed = allHandlersAreDisposed
+                        && messageHandlers[i] == null;
+                }
+
+                if (allHandlersAreDisposed)
+                {
+                    Stop();
+                }
+            }
+        }
+    }
+}
+#endif
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Model.cs b/lib/ServiceStack/src/ServiceStack.Common/Model.cs
new file mode 100644
index 0000000..fffd7d9
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Model.cs
@@ -0,0 +1,27 @@
+using ServiceStack.Common.Utils;
+
+namespace ServiceStack
+{
+    public static class Model
+    {
+        public static object ToId<T>(this T entity)
+        {
+            return entity.GetId();
+        }
+
+        public static string ToUrn<T>(object id)
+        {
+            return IdUtils.CreateUrn<T>(id);
+        }
+
+        public static string ToUrn<T>(this T entity)
+        {
+            return entity.CreateUrn();
+        }
+
+        public static string ToSafePathCacheKey<T>(string idValue)
+        {
+            return IdUtils.CreateCacheKeyPath<T>(idValue);
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ModelConfig.cs b/lib/ServiceStack/src/ServiceStack.Common/ModelConfig.cs
new file mode 100644
index 0000000..99b6c39
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ModelConfig.cs
@@ -0,0 +1,13 @@
+using System;
+using ServiceStack.Common.Utils;
+
+namespace ServiceStack
+{
+    public class ModelConfig<T>
+    {
+        public static void Id(Func<T, object> getIdFn)
+        {
+            IdUtils<T>.CanGetId = getIdFn;
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Net30/ConcurrentDictionary.cs b/lib/ServiceStack/src/ServiceStack.Common/Net30/ConcurrentDictionary.cs
new file mode 100644
index 0000000..e314d88
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Net30/ConcurrentDictionary.cs
@@ -0,0 +1,440 @@
+// ConcurrentDictionary.cs
+//
+// Copyright (c) 2009 Jérémie "Garuma" Laval
+//
+// 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.
+//
+//
+
+#if !NET_4_0 
+
+using System;
+using System.Threading;
+using System.Collections;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Diagnostics;
+
+namespace ServiceStack.Net30.Collections.Concurrent
+{
+    public class ConcurrentDictionary<TKey, TValue> : IDictionary<TKey, TValue>,
+      ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>,
+      IDictionary, ICollection, IEnumerable
+    {
+        IEqualityComparer<TKey> comparer;
+
+        SplitOrderedList<TKey, KeyValuePair<TKey, TValue>> internalDictionary;
+
+        public ConcurrentDictionary () : this (EqualityComparer<TKey>.Default)
+        {
+        }
+
+        public ConcurrentDictionary (IEnumerable<KeyValuePair<TKey, TValue>> collection)
+            : this (collection, EqualityComparer<TKey>.Default)
+        {
+        }
+
+        public ConcurrentDictionary (IEqualityComparer<TKey> comparer)
+        {
+            this.comparer = comparer;
+            this.internalDictionary = new SplitOrderedList<TKey, KeyValuePair<TKey, TValue>> (comparer);
+        }
+
+        public ConcurrentDictionary (IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey> comparer)
+            : this (comparer)
+        {
+            foreach (KeyValuePair<TKey, TValue> pair in collection)
+                Add (pair.Key, pair.Value);
+        }
+
+        // Parameters unused
+        public ConcurrentDictionary (int concurrencyLevel, int capacity)
+            : this (EqualityComparer<TKey>.Default)
+        {
+
+        }
+
+        public ConcurrentDictionary (int concurrencyLevel,
+                                     IEnumerable<KeyValuePair<TKey, TValue>> collection,
+                                     IEqualityComparer<TKey> comparer)
+            : this (collection, comparer)
+        {
+
+        }
+
+        // Parameters unused
+        public ConcurrentDictionary (int concurrencyLevel, int capacity, IEqualityComparer<TKey> comparer)
+            : this (comparer)
+        {
+
+        }
+
+        void Add (TKey key, TValue value)
+        {
+            while (!TryAdd (key, value));
+        }
+
+        void IDictionary<TKey, TValue>.Add (TKey key, TValue value)
+        {
+            Add (key, value);
+        }
+
+        public bool TryAdd (TKey key, TValue value)
+        {
+            return internalDictionary.Insert (Hash (key), key, Make (key, value));
+        }
+
+        void ICollection<KeyValuePair<TKey,TValue>>.Add (KeyValuePair<TKey, TValue> pair)
+        {
+            Add (pair.Key, pair.Value);
+        }
+
+        public TValue AddOrUpdate (TKey key, Func<TKey, TValue> addValueFactory, Func<TKey, TValue, TValue> updateValueFactory)
+        {
+            return internalDictionary.InsertOrUpdate (Hash (key),
+                                                      key,
+                                                      () => Make (key, addValueFactory (key)),
+                                                      (e) => Make (key, updateValueFactory (key, e.Value))).Value;
+        }
+
+        public TValue AddOrUpdate (TKey key, TValue addValue, Func<TKey, TValue, TValue> updateValueFactory)
+        {
+            return AddOrUpdate (key, (_) => addValue, updateValueFactory);
+        }
+
+        TValue AddOrUpdate (TKey key, TValue addValue, TValue updateValue)
+        {
+            return internalDictionary.InsertOrUpdate (Hash (key),
+                                                      key,
+                                                      Make (key, addValue),
+                                                      Make (key, updateValue)).Value;
+        }
+
+        TValue GetValue (TKey key)
+        {
+            TValue temp;
+            if (!TryGetValue (key, out temp))
+                throw new KeyNotFoundException (key.ToString ());
+            return temp;
+        }
+
+        public bool TryGetValue (TKey key, out TValue value)
+        {
+            KeyValuePair<TKey, TValue> pair;
+            bool result = internalDictionary.Find (Hash (key), key, out pair);
+            value = pair.Value;
+
+            return result;
+        }
+
+        public bool TryUpdate (TKey key, TValue newValue, TValue comparisonValue)
+        {
+            return internalDictionary.CompareExchange (Hash (key), key, Make (key, newValue), (e) => e.Value.Equals (comparisonValue));
+        }
+
+        public TValue this[TKey key] {
+            get {
+                return GetValue (key);
+            }
+            set {
+                AddOrUpdate (key, value, value);
+            }
+        }
+
+        public TValue GetOrAdd (TKey key, Func<TKey, TValue> valueFactory)
+        {
+            return internalDictionary.InsertOrGet (Hash (key), key, Make (key, default(TValue)), () => Make (key, valueFactory (key))).Value;
+        }
+
+        public TValue GetOrAdd (TKey key, TValue value)
+        {
+            return internalDictionary.InsertOrGet (Hash (key), key, Make (key, value), null).Value;
+        }
+
+        public bool TryRemove (TKey key, out TValue value)
+        {
+            KeyValuePair<TKey, TValue> data;
+            bool result = internalDictionary.Delete (Hash (key), key, out data);
+            value = data.Value;
+            return result;
+        }
+
+        bool Remove (TKey key)
+        {
+            TValue dummy;
+
+            return TryRemove (key, out dummy);
+        }
+
+        bool IDictionary<TKey, TValue>.Remove (TKey key)
+        {
+            return Remove (key);
+        }
+
+        bool ICollection<KeyValuePair<TKey,TValue>>.Remove (KeyValuePair<TKey,TValue> pair)
+        {
+            return Remove (pair.Key);
+        }
+
+        public bool ContainsKey (TKey key)
+        {
+            KeyValuePair<TKey, TValue> dummy;
+            return internalDictionary.Find (Hash (key), key, out dummy);
+        }
+
+        bool IDictionary.Contains (object key)
+        {
+            if (!(key is TKey))
+                return false;
+
+            return ContainsKey ((TKey)key);
+        }
+
+        void IDictionary.Remove (object key)
+        {
+            if (!(key is TKey))
+                return;
+
+            Remove ((TKey)key);
+        }
+
+        object IDictionary.this [object key]
+        {
+            get {
+                if (!(key is TKey))
+                    throw new ArgumentException ("key isn't of correct type", "key");
+
+                return this[(TKey)key];
+            }
+            set {
+                if (!(key is TKey) || !(value is TValue))
+                    throw new ArgumentException ("key or value aren't of correct type");
+
+                this[(TKey)key] = (TValue)value;
+            }
+        }
+
+        void IDictionary.Add (object key, object value)
+        {
+            if (!(key is TKey) || !(value is TValue))
+                throw new ArgumentException ("key or value aren't of correct type");
+
+            Add ((TKey)key, (TValue)value);
+        }
+
+        bool ICollection<KeyValuePair<TKey,TValue>>.Contains (KeyValuePair<TKey, TValue> pair)
+        {
+            return ContainsKey (pair.Key);
+        }
+
+        public KeyValuePair<TKey,TValue>[] ToArray ()
+        {
+            // This is most certainly not optimum but there is
+            // not a lot of possibilities
+
+            return new List<KeyValuePair<TKey,TValue>> (this).ToArray ();
+        }
+
+        public void Clear()
+        {
+            // Pronk
+            internalDictionary = new SplitOrderedList<TKey, KeyValuePair<TKey, TValue>> (comparer);
+        }
+
+        public int Count {
+            get {
+                return internalDictionary.Count;
+            }
+        }
+
+        public bool IsEmpty {
+            get {
+                return Count == 0;
+            }
+        }
+
+        bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly {
+            get {
+                return false;
+            }
+        }
+
+        bool IDictionary.IsReadOnly {
+            get {
+                return false;
+            }
+        }
+
+        public ICollection<TKey> Keys {
+            get {
+                return GetPart<TKey> ((kvp) => kvp.Key);
+            }
+        }
+
+        public ICollection<TValue> Values {
+            get {
+                return GetPart<TValue> ((kvp) => kvp.Value);
+            }
+        }
+
+        ICollection IDictionary.Keys {
+            get {
+                return (ICollection)Keys;
+            }
+        }
+
+        ICollection IDictionary.Values {
+            get {
+                return (ICollection)Values;
+            }
+        }
+
+        ICollection<T> GetPart<T> (Func<KeyValuePair<TKey, TValue>, T> extractor)
+        {
+            List<T> temp = new List<T> ();
+
+            foreach (KeyValuePair<TKey, TValue> kvp in this)
+                temp.Add (extractor (kvp));
+
+            return temp.AsReadOnly ();
+        }
+
+        void ICollection.CopyTo (Array array, int startIndex)
+        {
+            KeyValuePair<TKey, TValue>[] arr = array as KeyValuePair<TKey, TValue>[];
+            if (arr == null)
+                return;
+
+            CopyTo (arr, startIndex, Count);
+        }
+
+        void CopyTo (KeyValuePair<TKey, TValue>[] array, int startIndex)
+        {
+            CopyTo (array, startIndex, Count);
+        }
+
+        void ICollection<KeyValuePair<TKey, TValue>>.CopyTo (KeyValuePair<TKey, TValue>[] array, int startIndex)
+        {
+            CopyTo (array, startIndex);
+        }
+
+        void CopyTo (KeyValuePair<TKey, TValue>[] array, int startIndex, int num)
+        {
+            foreach (var kvp in this) {
+                array [startIndex++] = kvp;
+
+                if (--num <= 0)
+                    return;
+            }
+        }
+
+        public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator ()
+        {
+            return GetEnumeratorInternal ();
+        }
+
+        IEnumerator IEnumerable.GetEnumerator ()
+        {
+            return (IEnumerator)GetEnumeratorInternal ();
+        }
+
+        IEnumerator<KeyValuePair<TKey, TValue>> GetEnumeratorInternal ()
+        {
+            return internalDictionary.GetEnumerator ();
+        }
+
+        IDictionaryEnumerator IDictionary.GetEnumerator ()
+        {
+            return new ConcurrentDictionaryEnumerator (GetEnumeratorInternal ());
+        }
+
+        class ConcurrentDictionaryEnumerator : IDictionaryEnumerator
+        {
+            IEnumerator<KeyValuePair<TKey, TValue>> internalEnum;
+
+            public ConcurrentDictionaryEnumerator (IEnumerator<KeyValuePair<TKey, TValue>> internalEnum)
+            {
+                this.internalEnum = internalEnum;
+            }
+
+            public bool MoveNext ()
+            {
+                return internalEnum.MoveNext ();
+            }
+
+            public void Reset ()
+            {
+                internalEnum.Reset ();
+            }
+
+            public object Current {
+                get {
+                    return Entry;
+                }
+            }
+
+            public DictionaryEntry Entry {
+                get {
+                    KeyValuePair<TKey, TValue> current = internalEnum.Current;
+                    return new DictionaryEntry (current.Key, current.Value);
+                }
+            }
+
+            public object Key {
+                get {
+                    return internalEnum.Current.Key;
+                }
+            }
+
+            public object Value {
+                get {
+                    return internalEnum.Current.Value;
+                }
+            }
+        }
+
+        object ICollection.SyncRoot {
+            get {
+                return this;
+            }
+        }
+
+        bool IDictionary.IsFixedSize {
+            get {
+                return false;
+            }
+        }
+
+        bool ICollection.IsSynchronized {
+            get { return true; }
+        }
+
+        static KeyValuePair<U, V> Make<U, V> (U key, V value)
+        {
+            return new KeyValuePair<U, V> (key, value);
+        }
+
+        uint Hash (TKey key)
+        {
+            return (uint)comparer.GetHashCode (key);
+        }
+    }
+}
+
+#endif
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Net30/ConcurrentQueue.cs b/lib/ServiceStack/src/ServiceStack.Common/Net30/ConcurrentQueue.cs
new file mode 100644
index 0000000..94e33ab
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Net30/ConcurrentQueue.cs
@@ -0,0 +1,237 @@
+// IConcurrentCollection.cs
+//
+// Copyright (c) 2008 Jérémie "Garuma" Laval
+//
+// 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.
+//
+//
+
+using System;
+using System.Threading;
+using System.Collections;
+using System.Collections.Generic;
+using ServiceStack.Net30.Collections.Concurrent;
+
+namespace ServiceStack.Common.Net30
+{
+    public interface IProducerConsumerCollection<T> : IEnumerable<T>, ICollection, IEnumerable
+    {
+        bool TryAdd(T item);
+        bool TryTake(out T item);
+        T[] ToArray();
+        void CopyTo(T[] array, int index);
+    }
+
+    [System.Diagnostics.DebuggerDisplay ("Count={Count}")]
+    public class ConcurrentQueue<T> : IProducerConsumerCollection<T>, IEnumerable<T>, ICollection, IEnumerable
+    {
+        class Node
+        {
+            public T Value;
+            public Node Next;
+        }
+
+        Node head = new Node ();
+        Node tail;
+        int count;
+
+        class NodeObjectPool : ObjectPool<Node> {
+            protected override Node Creator ()
+            {
+                return new Node ();
+            }
+        }
+        static readonly NodeObjectPool pool = new NodeObjectPool ();
+
+        static Node ZeroOut (Node node)
+        {
+            node.Value = default(T);
+            node.Next = null;
+            return node;
+        }
+
+        public ConcurrentQueue ()
+        {
+            tail = head;
+        }
+
+        public ConcurrentQueue (IEnumerable<T> collection): this()
+        {
+            foreach (T item in collection)
+                Enqueue (item);
+        }
+
+        public void Enqueue (T item)
+        {
+            Node node = pool.Take ();
+            node.Value = item;
+
+            Node oldTail = null;
+            Node oldNext = null;
+
+            bool update = false;
+            while (!update) {
+                oldTail = tail;
+                oldNext = oldTail.Next;
+
+                // Did tail was already updated ?
+                if (tail == oldTail) {
+                    if (oldNext == null) {
+                        // The place is for us
+                        update = Interlocked.CompareExchange (ref tail.Next, node, null) == null;
+                    } else {
+                        // another Thread already used the place so give him a hand by putting tail where it should be
+                        Interlocked.CompareExchange (ref tail, oldNext, oldTail);
+                    }
+                }
+            }
+            // At this point we added correctly our node, now we have to update tail. If it fails then it will be done by another thread
+            Interlocked.CompareExchange (ref tail, node, oldTail);
+
+            Interlocked.Increment (ref count);
+        }
+
+        bool IProducerConsumerCollection<T>.TryAdd (T item)
+        {
+            Enqueue (item);
+            return true;
+        }
+
+        public bool TryDequeue (out T result)
+        {
+            result = default (T);
+            bool advanced = false;
+
+            while (!advanced) {
+                Node oldHead = head;
+                Node oldTail = tail;
+                Node oldNext = oldHead.Next;
+
+                if (oldHead == head) {
+                    // Empty case ?
+                    if (oldHead == oldTail) {	
+                        // This should be false then
+                        if (oldNext != null) {
+                            // If not then the linked list is mal formed, update tail
+                            Interlocked.CompareExchange (ref tail, oldNext, oldTail);
+                        }
+                        result = default (T);
+                        return false;
+                    } else {
+                        result = oldNext.Value;
+                        advanced = Interlocked.CompareExchange (ref head, oldNext, oldHead) == oldHead;
+                        if (advanced)
+                            pool.Release (ZeroOut (oldHead));
+                    }
+                }
+            }
+
+            Interlocked.Decrement (ref count);
+
+            return true;
+        }
+
+        public bool TryPeek (out T result)
+        {
+            if (IsEmpty) {
+                result = default (T);
+                return false;
+            }
+
+            Node first = head.Next;
+            result = first.Value;
+            return true;
+        }
+
+        internal void Clear ()
+        {
+            count = 0;
+            tail = head = new Node ();
+        }
+
+        IEnumerator IEnumerable.GetEnumerator ()
+        {
+            return (IEnumerator)InternalGetEnumerator ();
+        }
+
+        public IEnumerator<T> GetEnumerator ()
+        {
+            return InternalGetEnumerator ();
+        }
+
+        IEnumerator<T> InternalGetEnumerator ()
+        {
+            Node my_head = head;
+            while ((my_head = my_head.Next) != null) {
+                yield return my_head.Value;
+            }
+        }
+
+        void ICollection.CopyTo (Array array, int index)
+        {
+            T[] dest = array as T[];
+            if (dest == null)
+                return;
+            CopyTo (dest, index);
+        }
+
+        public void CopyTo (T[] array, int index)
+        {
+            IEnumerator<T> e = InternalGetEnumerator ();
+            int i = index;
+            while (e.MoveNext ()) {
+                array [i++] = e.Current;
+            }
+        }
+
+        public T[] ToArray ()
+        {
+            T[] dest = new T [count];
+            CopyTo (dest, 0);
+            return dest;
+        }
+
+        bool ICollection.IsSynchronized {
+            get { return true; }
+        }
+
+        bool IProducerConsumerCollection<T>.TryTake (out T item)
+        {
+            return TryDequeue (out item);
+        }
+
+        object syncRoot = new object();
+        object ICollection.SyncRoot {
+            get { return syncRoot; }
+        }
+
+        public int Count {
+            get {
+                return count;
+            }
+        }
+
+        public bool IsEmpty {
+            get {
+                return count == 0;
+            }
+        }
+    }
+}
+
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Net30/ObjectPool.cs b/lib/ServiceStack/src/ServiceStack.Common/Net30/ObjectPool.cs
new file mode 100644
index 0000000..d228ab6
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Net30/ObjectPool.cs
@@ -0,0 +1,97 @@
+// ObjectPool.cs
+//
+// Copyright (c) 2011 Novell
+//
+// Authors: 
+//      Jérémie "garuma" Laval
+//
+// 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.
+//
+//
+
+#if !NET_4_0 
+
+using System;
+using System.Threading;
+using System.Collections;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace ServiceStack.Net30.Collections.Concurrent
+{
+    internal abstract class ObjectPool<T> where T : class
+    {
+        const int capacity = 20;
+        const int bit = 0x8000000;
+
+        readonly T[] buffer;
+        int addIndex;
+        int removeIndex;
+
+        public ObjectPool ()
+        {
+            buffer = new T[capacity];
+            for (int i = 0; i < capacity; i++)
+                buffer[i] = Creator ();
+            addIndex = capacity - 1;
+        }
+
+        protected abstract T Creator ();
+
+        public T Take ()
+        {
+            if ((addIndex & ~bit) - 1 == removeIndex)
+                return Creator ();
+
+            int i;
+            T result;
+            int tries = 3;
+
+            do {
+                i = removeIndex;
+                if ((addIndex & ~bit) - 1 == i || tries == 0)
+                    return Creator ();
+                result = buffer[i % capacity];
+            } while (Interlocked.CompareExchange (ref removeIndex, i + 1, i) != i && --tries > -1);
+
+            return result;
+        }
+
+        public void Release (T obj)
+        {
+            if (obj == null || addIndex - removeIndex >= capacity - 1)
+                return;
+
+            int i;
+            int tries = 3;
+            do {
+                do {
+                    i = addIndex;
+                } while ((i & bit) > 0);
+                if (i - removeIndex >= capacity - 1)
+                    return;
+            } while (Interlocked.CompareExchange (ref addIndex, i + 1 + bit, i) != i && --tries > 0);
+
+            buffer[i % capacity] = obj;
+            addIndex = addIndex - bit;
+        }
+    }
+}
+
+#endif
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Net30/SplitOrderedList.cs b/lib/ServiceStack/src/ServiceStack.Common/Net30/SplitOrderedList.cs
new file mode 100644
index 0000000..1ee85a6
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Net30/SplitOrderedList.cs
@@ -0,0 +1,519 @@
+// SplitOrderedList.cs
+//
+// Copyright (c) 2010 Jérémie "Garuma" Laval
+//
+// 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.
+//
+//
+
+#if !NET_4_0 
+
+using System;
+using System.Threading;
+using System.Collections;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace ServiceStack.Net30.Collections.Concurrent
+{
+    internal class SplitOrderedList<TKey, T>
+    {
+        class Node
+        {
+            public bool Marked;
+            public ulong Key;
+            public TKey SubKey;
+            public T Data;
+            public Node Next;
+
+            public Node Init (ulong key, TKey subKey, T data)
+            {
+                this.Key = key;
+                this.SubKey = subKey;
+                this.Data = data;
+
+                this.Marked = false;
+                this.Next = null;
+
+                return this;
+            }
+
+            // Used to create dummy node
+            public Node Init (ulong key)
+            {
+                this.Key = key;
+                this.Data = default (T);
+
+                this.Next = null;
+                this.Marked = false;
+                this.SubKey = default (TKey);
+
+                return this;
+            }
+
+            // Used to create marked node
+            public Node Init (Node wrapped)
+            {
+                this.Marked = true;
+                this.Next = wrapped;
+
+                this.Key = 0;
+                this.Data = default (T);
+                this.SubKey = default (TKey);
+
+                return this;
+            }
+        }
+
+        class NodeObjectPool : ObjectPool<Node> {
+            protected override Node Creator ()
+            {
+                return new Node ();
+            }
+        }
+        static readonly NodeObjectPool pool = new NodeObjectPool ();
+
+        const int MaxLoad = 5;
+        const uint BucketSize = 512;
+
+        Node head;
+        Node tail;
+
+        Node[] buckets = new Node [BucketSize];
+        int count;
+        int size = 2;
+
+        SimpleRwLock slim = new SimpleRwLock ();
+
+        readonly IEqualityComparer<TKey> comparer;
+
+        public SplitOrderedList (IEqualityComparer<TKey> comparer)
+        {
+            this.comparer = comparer;
+            head = new Node ().Init (0);
+            tail = new Node ().Init (ulong.MaxValue);
+            head.Next = tail;
+            SetBucket (0, head);
+        }
+
+        public int Count {
+            get {
+                return count;
+            }
+        }
+
+        public T InsertOrUpdate (uint key, TKey subKey, Func<T> addGetter, Func<T, T> updateGetter)
+        {
+            Node current;
+            bool result = InsertInternal (key, subKey, default (T), addGetter, out current);
+
+            if (result)
+                return current.Data;
+
+            // FIXME: this should have a CAS-like behavior
+            return current.Data = updateGetter (current.Data);
+        }
+
+        public T InsertOrUpdate (uint key, TKey subKey, T addValue, T updateValue)
+        {
+            Node current;
+            if (InsertInternal (key, subKey, addValue, null, out current))
+                return current.Data;
+
+            // FIXME: this should have a CAS-like behavior
+            return current.Data = updateValue;
+        }
+        
+        public bool Insert (uint key, TKey subKey, T data)
+        {
+            Node current;
+            return InsertInternal (key, subKey, data, null, out current);
+        }
+
+        public T InsertOrGet (uint key, TKey subKey, T data, Func<T> dataCreator)
+        {
+            Node current;
+            InsertInternal (key, subKey, data, dataCreator, out current);
+            return current.Data;
+        }
+
+        bool InsertInternal (uint key, TKey subKey, T data, Func<T> dataCreator, out Node current)
+        {
+            Node node = pool.Take ().Init (ComputeRegularKey (key), subKey, data);
+
+            uint b = key % (uint)size;
+            Node bucket;
+
+            if ((bucket = GetBucket (b)) == null)
+                bucket = InitializeBucket (b);
+
+            if (!ListInsert (node, bucket, out current, dataCreator))
+                return false;
+
+            int csize = size;
+            if (Interlocked.Increment (ref count) / csize > MaxLoad && (csize & 0x40000000) == 0)
+                Interlocked.CompareExchange (ref size, 2 * csize, csize);
+
+            current = node;
+
+            return true;
+        }
+        
+        public bool Find (uint key, TKey subKey, out T data)
+        {
+            Node node;
+            uint b = key % (uint)size;
+            data = default (T);
+            Node bucket;
+
+            if ((bucket = GetBucket (b)) == null)
+                bucket = InitializeBucket (b);
+
+            if (!ListFind (ComputeRegularKey (key), subKey, bucket, out node))
+                return false;
+
+            data = node.Data;
+
+            return !node.Marked;
+        }
+
+        public bool CompareExchange (uint key, TKey subKey, T data, Func<T, bool> check)
+        {
+            Node node;
+            uint b = key % (uint)size;
+            Node bucket;
+
+            if ((bucket = GetBucket (b)) == null)
+                bucket = InitializeBucket (b);
+
+            if (!ListFind (ComputeRegularKey (key), subKey, bucket, out node))
+                return false;
+
+            if (!check (node.Data))
+                return false;
+
+            node.Data = data;
+
+            return true;
+        }
+
+        public bool Delete (uint key, TKey subKey, out T data)
+        {
+            uint b = key % (uint)size;
+            Node bucket;
+
+            if ((bucket = GetBucket (b)) == null)
+                bucket = InitializeBucket (b);
+
+            if (!ListDelete (bucket, ComputeRegularKey (key), subKey, out data))
+                return false;
+
+            Interlocked.Decrement (ref count);
+            return true;
+        }
+
+        public IEnumerator<T> GetEnumerator ()
+        {
+            Node node = head.Next;
+
+            while (node != tail) {
+                while (node.Marked || (node.Key & 1) == 0) {
+                    node = node.Next;
+                    if (node == tail)
+                        yield break;
+                }
+                yield return node.Data;
+                node = node.Next;
+            }
+        }
+
+        Node InitializeBucket (uint b)
+        {
+            Node current;
+            uint parent = GetParent (b);
+            Node bucket;
+
+            if ((bucket = GetBucket (parent)) == null)
+                bucket = InitializeBucket (parent);
+
+            Node dummy = pool.Take ().Init (ComputeDummyKey (b));
+            if (!ListInsert (dummy, bucket, out current, null))
+                return current;
+
+            return SetBucket (b, dummy);
+        }
+        
+        // Turn v's MSB off
+        static uint GetParent (uint v)
+        {
+            uint t, tt;
+            
+            // Find MSB position in v
+            var pos = (tt = v >> 16) > 0 ?
+                (t = tt >> 8) > 0 ? 24 + logTable[t] : 16 + logTable[tt] :
+                (t = v >> 8) > 0 ? 8 + logTable[t] : logTable[v];
+
+            return (uint)(v & ~(1 << pos));
+        }
+
+        // Reverse integer bits and make sure LSB is set
+        static ulong ComputeRegularKey (uint key)
+        {
+            return ComputeDummyKey (key) | 1;
+        }
+        
+        // Reverse integer bits
+        static ulong ComputeDummyKey (uint key)
+        {
+            return ((ulong)(((uint)reverseTable[key & 0xff] << 24) |
+                            ((uint)reverseTable[(key >> 8) & 0xff] << 16) |
+                            ((uint)reverseTable[(key >> 16) & 0xff] << 8) |
+                            ((uint)reverseTable[(key >> 24) & 0xff]))) << 1;
+        }
+
+        // Bucket storage is abstracted in a simple two-layer tree to avoid too much memory resize
+        Node GetBucket (uint index)
+        {
+            if (index >= buckets.Length)
+                return null;
+            return buckets[index];
+        }
+
+        Node SetBucket (uint index, Node node)
+        {
+            try {
+                slim.EnterReadLock ();
+                CheckSegment (index, true);
+
+                Interlocked.CompareExchange (ref buckets[index], node, null);
+                return buckets[index];
+            } finally {
+                slim.ExitReadLock ();
+            }
+        }
+
+        // When we run out of space for bucket storage, we use a lock-based array resize
+        void CheckSegment (uint segment, bool readLockTaken)
+        {
+            if (segment < buckets.Length)
+                return;
+
+            if (readLockTaken)
+                slim.ExitReadLock ();
+            try {
+                slim.EnterWriteLock ();
+                while (segment >= buckets.Length)
+                    Array.Resize (ref buckets, buckets.Length * 2);
+            } finally {
+                slim.ExitWriteLock ();
+            }
+            if (readLockTaken)
+                slim.EnterReadLock ();
+        }
+
+        Node ListSearch (ulong key, TKey subKey, ref Node left, Node h)
+        {
+            Node leftNodeNext = null, rightNode = null;
+
+            do {
+                Node t = h;
+                Node tNext = t.Next;
+                do {
+                    if (!tNext.Marked) {
+                        left = t;
+                        leftNodeNext = tNext;
+                    }
+                    t = tNext.Marked ? tNext.Next : tNext;
+                    if (t == tail)
+                        break;
+                    
+                    tNext = t.Next;
+                } while (tNext.Marked || t.Key < key || (tNext.Key == key && !comparer.Equals (subKey, t.SubKey)));
+                
+                rightNode = t;
+                
+                if (leftNodeNext == rightNode) {
+                    if (rightNode != tail && rightNode.Next.Marked)
+                        continue;
+                    else 
+                        return rightNode;
+                }
+                
+                if (Interlocked.CompareExchange (ref left.Next, rightNode, leftNodeNext) == leftNodeNext) {
+                    pool.Release (leftNodeNext);
+                    if (rightNode != tail && rightNode.Next.Marked)
+                        continue;
+                    else
+                        return rightNode;
+                }
+            } while (true);
+        }
+
+        bool ListDelete (Node startPoint, ulong key, TKey subKey, out T data)
+        {
+            Node rightNode = null, rightNodeNext = null, leftNode = null;
+            data = default (T);
+            Node markedNode = null;
+            
+            do {
+                rightNode = ListSearch (key, subKey, ref leftNode, startPoint);
+                if (rightNode == tail || rightNode.Key != key)
+                    return false;
+
+                data = rightNode.Data;
+                rightNodeNext = rightNode.Next;
+
+                if (!rightNodeNext.Marked) {
+                    if (markedNode == null)
+                        markedNode = pool.Take ();
+                    markedNode.Init (rightNodeNext);
+
+                    if (Interlocked.CompareExchange (ref rightNode.Next, markedNode, rightNodeNext) == rightNodeNext)
+                        break;
+                }
+            } while (true);
+            
+            if (Interlocked.CompareExchange (ref leftNode.Next, rightNodeNext, rightNode) != rightNode)
+                ListSearch (rightNode.Key, subKey, ref leftNode, startPoint);
+            else
+                pool.Release (rightNode);
+            
+            return true;
+        }
+        
+        bool ListInsert (Node newNode, Node startPoint, out Node current, Func<T> dataCreator)
+        {
+            ulong key = newNode.Key;
+            Node rightNode = null, leftNode = null;
+            
+            do {
+                rightNode = current = ListSearch (key, newNode.SubKey, ref leftNode, startPoint);
+                if (rightNode != tail && rightNode.Key == key && comparer.Equals (newNode.SubKey, rightNode.SubKey))
+                    return false;
+                
+                newNode.Next = rightNode;
+                if (dataCreator != null)
+                    newNode.Data = dataCreator ();
+                if (Interlocked.CompareExchange (ref leftNode.Next, newNode, rightNode) == rightNode)
+                    return true;
+            } while (true);
+        }
+        
+        bool ListFind (ulong key, TKey subKey, Node startPoint, out Node data)
+        {
+            Node rightNode = null, leftNode = null;
+            data = null;
+            
+            rightNode = ListSearch (key, subKey, ref leftNode, startPoint);
+            data = rightNode;
+            
+            return rightNode != tail && rightNode.Key == key;
+        }
+
+        static readonly byte[] reverseTable = {
+            0, 128, 64, 192, 32, 160, 96, 224, 16, 144, 80, 208, 48, 176, 112, 240, 8, 136, 72, 200, 40, 168, 104, 232, 24, 152, 88, 216, 56, 184, 120, 248, 4, 132, 68, 196, 36, 164, 100, 228, 20, 148, 84, 212, 52, 180, 116, 244, 12, 140, 76, 204, 44, 172, 108, 236, 28, 156, 92, 220, 60, 188, 124, 252, 2, 130, 66, 194, 34, 162, 98, 226, 18, 146, 82, 210, 50, 178, 114, 242, 10, 138, 74, 202, 42, 170, 106, 234, 26, 154, 90, 218, 58, 186, 122, 250, 6, 134, 70, 198, 38, 166, 102, 230, 22, 150, 86, 214, 54, 182, 118, 246, 14, 142, 78, 206, 46, 174, 110, 238, 30, 158, 94, 222, 62, 190, 126, 254, 1, 129, 65, 193, 33, 161, 97, 225, 17, 145, 81, 209, 49, 177, 113, 241, 9, 137, 73, 201, 41, 169, 105, 233, 25, 153, 89, 217, 57, 185, 121, 249, 5, 133, 69, 197, 37, 165, 101, 229, 21, 149, 85, 213, 53, 181, 117, 245, 13, 141, 77, 205, 45, 173, 109, 237, 29, 157, 93, 221, 61, 189, 125, 253, 3, 131, 67, 195, 35, 163, 99, 227, 19, 147, 83, 211, 51, 179, 115, 243, 11, 139, 75, 203, 43, 171, 107, 235, 27, 155, 91, 219, 59, 187, 123, 251, 7, 135, 71, 199, 39, 167, 103, 231, 23, 151, 87, 215, 55, 183, 119, 247, 15, 143, 79, 207, 47, 175, 111, 239, 31, 159, 95, 223, 63, 191, 127, 255
+        };
+
+        static readonly byte[] logTable = {
+            0xFF, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+        };
+
+        struct SimpleRwLock
+        {
+            const int RwWait = 1;
+            const int RwWrite = 2;
+            const int RwRead = 4;
+
+            int rwlock;
+
+            public void EnterReadLock ()
+            {
+                SpinWait sw = new SpinWait ();
+                do {
+                    while ((rwlock & (RwWrite | RwWait)) > 0)
+                        sw.SpinOnce ();
+
+                    if ((Interlocked.Add (ref rwlock, RwRead) & (RwWait | RwWait)) == 0)
+                        return;
+
+                    Interlocked.Add (ref rwlock, -RwRead);
+                } while (true);
+            }
+
+            public void ExitReadLock ()
+            {
+                Interlocked.Add (ref rwlock, -RwRead);
+            }
+
+            public void EnterWriteLock ()
+            {
+                SpinWait sw = new SpinWait ();
+                do {
+                    int state = rwlock;
+                    if (state < RwWrite) {
+                        if (Interlocked.CompareExchange (ref rwlock, RwWrite, state) == state)
+                            return;
+                        state = rwlock;
+                    }
+                    // We register our interest in taking the Write lock (if upgradeable it's already done)
+                    while ((state & RwWait) == 0 && Interlocked.CompareExchange (ref rwlock, state | RwWait, state) != state)
+                        state = rwlock;
+                    // Before falling to sleep
+                    while (rwlock > RwWait)
+                        sw.SpinOnce ();
+                } while (true);
+            }
+
+            public void ExitWriteLock ()
+            {
+                Interlocked.Add (ref rwlock, -RwWrite);
+            }
+        }
+    }
+
+#if !NET_4_0
+    internal struct SpinWait
+    {
+        // The number of step until SpinOnce yield on multicore machine
+        const           int  step = 10;
+        const           int  maxTime = 200;
+        static readonly bool isSingleCpu = (Environment.ProcessorCount == 1);
+
+        int ntime;
+
+        public void SpinOnce ()
+        {
+            ntime += 1;
+
+            if (isSingleCpu) {
+                // On a single-CPU system, spinning does no good
+                Thread.Sleep (0);
+            } else {
+                if (ntime % step == 0)
+                    Thread.Sleep (0);
+                else
+                    // Multi-CPU system might be hyper-threaded, let other thread run
+                    Thread.SpinWait (Math.Min (ntime, maxTime) << 1);
+            }
+        }
+    }
+#endif
+}
+
+#endif
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Net30/Tuple.cs b/lib/ServiceStack/src/ServiceStack.Common/Net30/Tuple.cs
new file mode 100644
index 0000000..a8cfc3d
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Net30/Tuple.cs
@@ -0,0 +1,361 @@
+#region (c)2009 Lokad - New BSD license
+
+// Copyright (c) Lokad 2009 
+// Company: http://www.lokad.com
+// This code is released under the terms of the new BSD licence
+
+#endregion
+
+#if !NET_4_0 && !SILVERLIGHT && !MONOTOUCH && !XBOX
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+
+namespace ServiceStack.Net30
+{
+    public static class SystemUtil
+    {
+        internal static int GetHashCode(params object[] args)
+        {
+            unchecked
+            {
+                int result = 0;
+                foreach (var o in args)
+                {
+                    result = (result * 397) ^ (o != null ? o.GetHashCode() : 0);
+                }
+                return result;
+            }
+        }		
+    }
+
+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)]
+    public sealed class ImmutableAttribute : Attribute
+    {
+    }
+
+    /// <summary>
+    /// Helper extensions for tuples
+    /// </summary>
+    public static class ExtendTuple
+    {
+        public static Triple<T1, T2, T3> Append<T1, T2, T3>(this Tuple<T1, T2> tuple, T3 item)
+        {
+            return Tuple.From(tuple.Item1, tuple.Item2, item);
+        }
+
+        public static Quad<T1, T2, T3, T4> Append<T1, T2, T3, T4>(this Tuple<T1, T2, T3> tuple, T4 item)
+        {
+            return Tuple.From(tuple.Item1, tuple.Item2, tuple.Item3, item);
+        }
+
+        public static void AddTuple<T1, T2>(this ICollection<Tuple<T1, T2>> collection, T1 first, T2 second)
+        {
+            collection.Add(Tuple.From(first, second));
+        }
+
+        public static void AddTuple<T1, T2>(this ICollection<Pair<T1, T2>> collection, T1 first, T2 second)
+        {
+            collection.Add(Tuple.From(first, second));
+        }
+
+        public static void AddTuple<T1, T2, T3>(this ICollection<Tuple<T1, T2, T3>> collection, T1 first, T2 second, T3 third)
+        {
+            collection.Add(Tuple.From(first, second, third));
+        }
+
+        public static void AddTuple<T1, T2, T3, T4>(this ICollection<Tuple<T1, T2, T3, T4>> collection, T1 first, T2 second,
+                                                    T3 third, T4 fourth)
+        {
+            collection.Add(Tuple.From(first, second, third, fourth));
+        }
+
+    }
+    
+    [Serializable]
+    [Immutable]
+    public sealed class Pair<TKey, TValue> : Tuple<TKey, TValue>
+    {
+        public Pair(TKey first, TValue second) : base(first, second) {}
+
+        public TKey Key
+        {
+            get { return Item1; }
+        }
+
+        public TValue Value
+        {
+            get { return Item2; }
+        }
+    }
+
+    [Serializable]
+    [Immutable]
+    public sealed class Quad<T1, T2, T3, T4> : Tuple<T1, T2, T3, T4>
+    {
+        public Quad(T1 first, T2 second, T3 third, T4 fourth) : base(first, second, third, fourth)
+        {
+        }
+    }
+
+    [Serializable]
+    [Immutable]
+    public sealed class Triple<T1, T2, T3> : Tuple<T1, T2, T3>
+    {
+        public Triple(T1 first, T2 second, T3 third)
+            : base(first, second, third)
+        {
+        }
+    }
+
+    [Serializable]
+    [Immutable]
+    [DebuggerDisplay("({Item1},{Item2})")]
+    public class Tuple<T1, T2> : IEquatable<Tuple<T1, T2>>
+    {
+        readonly T1 _item1;
+
+        public T1 Item1
+        {
+            get { return _item1; }
+        }
+
+        readonly T2 _item2;
+
+        public T2 Item2
+        {
+            get { return _item2; }
+        }
+
+        public Tuple(T1 first, T2 second)
+        {
+            _item1 = first;
+            _item2 = second;
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj))
+                throw new NullReferenceException("obj is null");
+            if (ReferenceEquals(this, obj)) return true;
+            if (!(obj is Tuple<T1, T2>)) return false;
+            return Equals((Tuple<T1, T2>)obj);
+        }
+
+        public override string ToString()
+        {
+            return string.Format("({0},{1})", Item1, Item2);
+        }
+
+        public bool Equals(Tuple<T1, T2> obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            return Equals(obj.Item1, Item1) && Equals(obj.Item2, Item2);
+        }
+
+        public override int GetHashCode()
+        {
+            return SystemUtil.GetHashCode(Item1, Item2);
+        }
+
+        public static bool operator ==(Tuple<T1, T2> left, Tuple<T1, T2> right)
+        {
+            return Equals(left, right);
+        }
+
+        public static bool operator !=(Tuple<T1, T2> left, Tuple<T1, T2> right)
+        {
+            return !Equals(left, right);
+        }
+    }
+
+    [Serializable]
+    [DebuggerDisplay("({Item1},{Item2},{Item3})")]
+    public class Tuple<T1, T2, T3> : IEquatable<Tuple<T1, T2, T3>>
+    {
+        readonly T1 _item1;
+
+        public T1 Item1
+        {
+            get { return _item1; }
+        }
+
+        readonly T2 _item2;
+
+        public T2 Item2
+        {
+            get { return _item2; }
+        }
+
+        readonly T3 _item3;
+
+        public T3 Item3
+        {
+            get { return _item3; }
+        }
+
+        public Tuple(T1 first, T2 second, T3 third)
+        {
+            _item1 = first;
+            _item2 = second;
+            _item3 = third;
+        }
+
+        public override string ToString()
+        {
+            return string.Format("({0},{1},{2})", Item1, Item2, Item3);
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj))
+                throw new NullReferenceException("obj is null");
+            if (ReferenceEquals(this, obj)) return true;
+            if (!(obj is Tuple<T1, T2, T3>)) return false;
+            return Equals((Tuple<T1, T2, T3>)obj);
+        }
+
+        public bool Equals(Tuple<T1, T2, T3> obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            return Equals(obj.Item1, Item1) && Equals(obj.Item2, Item2) && Equals(obj.Item3, Item3);
+        }
+
+        public override int GetHashCode()
+        {
+            return SystemUtil.GetHashCode(Item1, Item2, Item3);
+        }
+
+        public static bool operator ==(Tuple<T1, T2, T3> left, Tuple<T1, T2, T3> right)
+        {
+            return Equals(left, right);
+        }
+
+        public static bool operator !=(Tuple<T1, T2, T3> left, Tuple<T1, T2, T3> right)
+        {
+            return !Equals(left, right);
+        }
+    }
+
+    [Serializable]
+    [DebuggerDisplay("({Item1},{Item2},{Item3},{Item4})")]
+    [Immutable]
+    public class Tuple<T1, T2, T3, T4> : IEquatable<Tuple<T1, T2, T3, T4>>
+    {
+        readonly T1 _item1;
+
+        public T1 Item1
+        {
+            get { return _item1; }
+        }
+
+        readonly T2 _item2;
+
+        public T2 Item2
+        {
+            get { return _item2; }
+        }
+
+        readonly T3 _item3;
+
+        public T3 Item3
+        {
+            get { return _item3; }
+        }
+
+        readonly T4 _item4;
+
+        public T4 Item4
+        {
+            get { return _item4; }
+        }
+
+        public Tuple(T1 first, T2 second, T3 third, T4 fourth)
+        {
+            _item1 = first;
+            _item2 = second;
+            _item3 = third;
+            _item4 = fourth;
+        }
+
+        public override string ToString()
+        {
+            return string.Format("({0},{1},{2},{3})", Item1, Item2, Item3, Item4);
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj))
+                throw new NullReferenceException("obj is null");
+            if (ReferenceEquals(this, obj)) return true;
+            if (!(obj is Tuple<T1, T2, T3, T4>)) return false;
+            return Equals((Tuple<T1, T2, T3, T4>)obj);
+        }
+
+        public bool Equals(Tuple<T1, T2, T3, T4> obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            return Equals(obj.Item1, Item1)
+                && Equals(obj.Item2, Item2)
+                    && Equals(obj.Item3, Item3)
+                        && Equals(obj.Item4, Item4);
+        }
+
+        public override int GetHashCode()
+        {
+            return SystemUtil.GetHashCode(Item1, Item2, Item3, Item4);
+        }
+
+        public static bool operator ==(Tuple<T1, T2, T3, T4> left, Tuple<T1, T2, T3, T4> right)
+        {
+            return Equals(left, right);
+        }
+
+        public static bool operator !=(Tuple<T1, T2, T3, T4> left, Tuple<T1, T2, T3, T4> right)
+        {
+            return !Equals(left, right);
+        }
+    }
+
+    public static class Tuple
+    {
+        public static Pair<T1, T2> From<T1, T2>(T1 first, T2 second)
+        {
+            return new Pair<T1, T2>(first, second);
+        }
+
+        public static Tuple<T1, T2> Create<T1, T2>(T1 first, T2 second)
+        {
+            return new Pair<T1, T2>(first, second);
+        }
+
+        public static Triple<T1, T2, T3> From<T1, T2, T3>(T1 first, T2 second, T3 third)
+        {
+            return new Triple<T1, T2, T3>(first, second, third);
+        }
+
+        public static Tuple<T1, T2, T3> Create<T1, T2, T3>(T1 first, T2 second, T3 third)
+        {
+            return new Triple<T1, T2, T3>(first, second, third);
+        }
+
+        public static Quad<T1, T2, T3, T4> From<T1, T2, T3, T4>(T1 first, T2 second, T3 third, T4 fourth)
+        {
+            return new Quad<T1, T2, T3, T4>(first, second, third, fourth);
+        }
+
+        public static Tuple<T1, T2, T3, T4> Create<T1, T2, T3, T4>(T1 first, T2 second, T3 third, T4 fourth)
+        {
+            return new Quad<T1, T2, T3, T4>(first, second, third, fourth);
+        }
+    }
+
+}
+
+
+#endif
+
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Properties/AssemblyInfo.cs b/lib/ServiceStack/src/ServiceStack.Common/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..1cafc69
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Properties/AssemblyInfo.cs
@@ -0,0 +1,40 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Serialization;
+
+// 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("ServiceStack.Common")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("ServiceStack")]
+[assembly: AssemblyProduct("ServiceStack.Common")]
+[assembly: AssemblyCopyright("Copyright © ServiceStack 2012")]
+[assembly: AssemblyTrademark("")]
+[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("3871f659-64fb-4dfb-a49f-17dc2f8a47e2")]
+
+// 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 Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("3.9.8.0")]
+
+// CCB Custom
+[assembly: ContractNamespace("http://schemas.servicestack.net/types",
+ ClrNamespace = "ServiceStack.Common.ServiceClient.Web")]
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Reflection/PropertyAccessor.cs b/lib/ServiceStack/src/ServiceStack.Common/Reflection/PropertyAccessor.cs
new file mode 100644
index 0000000..825428a
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Reflection/PropertyAccessor.cs
@@ -0,0 +1,112 @@
+using System;
+using System.Reflection;
+
+namespace ServiceStack.Common.Reflection
+{
+
+    public static class PropertyAccessor
+    {
+        public static Func<TEntity, object> GetPropertyFn<TEntity>(string propertyName)
+        {
+            return new PropertyAccessor<TEntity>(propertyName).GetPropertyFn();
+        }
+
+        //public static Func<object, object> GetPropertyFnByType(Type type, string propertyName)
+        //{
+        //    var mi = typeof(PropertyAccessor).GetMethod("GetPropertyFn");
+        //    var genericMi = mi.MakeGenericMethod(type);
+        //    var getPropertyFn = genericMi.Invoke(null, new object[] { propertyName });
+
+        //    return (Func<object, object>)getPropertyFn;
+        //}
+
+        public static Action<TEntity, object> SetPropertyFn<TEntity>(string propertyName)
+        {
+            return new PropertyAccessor<TEntity>(propertyName).SetPropertyFn();
+        }
+
+        //public static Action<object, object> SetPropertyFnByType(Type type, string propertyName)
+        //{
+        //    var mi = typeof(PropertyAccessor).GetMethod("SetPropertyFn");
+        //    var genericMi = mi.MakeGenericMethod(type);
+        //    var setPropertyFn = genericMi.Invoke(null, new object[] { propertyName });
+
+        //    return (Action<object, object>)setPropertyFn;
+        //}
+    }
+
+    public class PropertyAccessor<TEntity>
+    {
+        readonly PropertyInfo pi;
+        public string Name { get; set; }
+        public Type PropertyType { get; set; }
+
+        private readonly Func<TEntity, object> getPropertyFn;
+        private readonly Action<TEntity, object> setPropertyFn;
+
+        public PropertyAccessor(string propertyName)
+        {
+            this.pi = typeof(TEntity).GetProperty(propertyName);
+            this.Name = propertyName;
+            this.PropertyType = pi.PropertyType;
+
+            getPropertyFn = StaticAccessors<TEntity>.ValueUnTypedGetPropertyTypeFn(pi);
+            setPropertyFn = StaticAccessors<TEntity>.ValueUnTypedSetPropertyTypeFn(pi);
+        }
+
+        public Func<TEntity, object> GetPropertyFn()
+        {
+            return getPropertyFn;
+        }
+
+        public Action<TEntity, object> SetPropertyFn()
+        {
+            return setPropertyFn;
+        }
+
+        /// <summary>
+        /// Func to get the Strongly-typed field
+        /// </summary>
+        public Func<TEntity, TId> TypedGetPropertyFn<TId>()
+        {
+            return StaticAccessors<TEntity>.TypedGetPropertyFn<TId>(pi);
+        }
+
+        /// <summary>
+        /// Required to cast the return ValueType to an object for caching
+        /// </summary>
+        public Func<TEntity, object> ValueTypedGetPropertyFn<TId>()
+        {
+            return StaticAccessors<TEntity>.ValueUnTypedGetPropertyFn<TId>(pi);
+        }
+
+        public Func<object, object> UnTypedGetPropertyFn<TId>()
+        {
+            return StaticAccessors<TEntity>.UnTypedGetPropertyFn<TId>(pi);
+        }
+
+        /// <summary>
+        /// Func to set the Strongly-typed field
+        /// </summary>
+        public Action<TEntity, TId> TypedSetPropertyFn<TId>()
+        {
+            return StaticAccessors<TEntity>.TypedSetPropertyFn<TId>(pi);
+        }
+
+        /// <summary>
+        /// Required to cast the ValueType to an object for caching
+        /// </summary>
+        public Action<TEntity, object> ValueTypesSetPropertyFn<TId>()
+        {
+            return StaticAccessors<TEntity>.ValueUnTypedSetPropertyFn<TId>(pi);
+        }
+
+        /// <summary>
+        /// Required to cast the ValueType to an object for caching
+        /// </summary>
+        public Action<object, object> UnTypedSetPropertyFn<TId>()
+        {
+            return StaticAccessors<TEntity>.UnTypedSetPropertyFn<TId>(pi);
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Reflection/StaticAccessors.cs b/lib/ServiceStack/src/ServiceStack.Common/Reflection/StaticAccessors.cs
new file mode 100644
index 0000000..a37ca81
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Reflection/StaticAccessors.cs
@@ -0,0 +1,169 @@
+using System;
+using System.Reflection;
+
+namespace ServiceStack.Common.Reflection
+{
+
+#if MONOTOUCH || SILVERLIGHT
+    public static class StaticAccessors
+    {
+    }
+#else
+    using System.Linq.Expressions;
+    
+    public static class StaticAccessors
+    {
+        public static Func<object, object> GetValueGetter(Type type, PropertyInfo propertyInfo)
+        {
+            if (type != propertyInfo.DeclaringType)
+            {
+                throw new ArgumentException();
+            }
+
+            var instance = Expression.Parameter(typeof(object), "i");
+            var convertInstance = Expression.TypeAs(instance, propertyInfo.DeclaringType);
+            var property = Expression.Property(convertInstance, propertyInfo);
+            var convertProperty = Expression.TypeAs(property, typeof(object));
+            return Expression.Lambda<Func<object, object>>(convertProperty, instance).Compile();
+        }
+
+        public static Func<T, object> GetValueGetter<T>(this PropertyInfo propertyInfo)
+        {
+            if (typeof(T) != propertyInfo.DeclaringType)
+            {
+                throw new ArgumentException();
+            }
+
+            var instance = Expression.Parameter(propertyInfo.DeclaringType, "i");
+            var property = Expression.Property(instance, propertyInfo);
+            var convert = Expression.TypeAs(property, typeof(object));
+            return Expression.Lambda<Func<T, object>>(convert, instance).Compile();
+        }
+
+        public static Action<T, object> GetValueSetter<T>(this PropertyInfo propertyInfo)
+        {
+            if (typeof(T) != propertyInfo.DeclaringType)
+            {
+                throw new ArgumentException();
+            }
+
+            var instance = Expression.Parameter(propertyInfo.DeclaringType, "i");
+            var argument = Expression.Parameter(typeof(object), "a");
+            var setterCall = Expression.Call(
+                instance,
+                propertyInfo.GetSetMethod(),
+                Expression.Convert(argument, propertyInfo.PropertyType));
+
+            return Expression.Lambda<Action<T, object>>
+                (
+                    setterCall, instance, argument
+                ).Compile();
+        }
+    }
+
+#endif
+
+    public static class StaticAccessors<TEntity>
+    {
+        /// <summary>
+        /// Func to get the Strongly-typed field
+        /// </summary>
+        public static Func<TEntity, TId> TypedGetPropertyFn<TId>(PropertyInfo pi)
+        {
+            var mi = pi.GetGetMethod();
+            return (Func<TEntity, TId>)Delegate.CreateDelegate(typeof(Func<TEntity, TId>), mi);
+        }
+
+        /// <summary>
+        /// Required to cast the return ValueType to an object for caching
+        /// </summary>
+        public static Func<TEntity, object> ValueUnTypedGetPropertyFn<TId>(PropertyInfo pi)
+        {
+            var typedPropertyFn = TypedGetPropertyFn<TId>(pi);
+            return x => typedPropertyFn(x);
+        }
+
+        public static Func<TEntity, object> ValueUnTypedGetPropertyTypeFn(PropertyInfo pi)
+        {
+            var mi = typeof(StaticAccessors<TEntity>).GetMethod("TypedGetPropertyFn");
+            var genericMi = mi.MakeGenericMethod(pi.PropertyType);
+            var typedGetPropertyFn = (Delegate)genericMi.Invoke(null, new[] { pi });
+
+#if MONOTOUCH || SILVERLIGHT
+            return x => typedGetPropertyFn.Method.Invoke(x, new object[] { });
+#else
+            var typedMi = typedGetPropertyFn.Method;
+            var paramFunc = Expression.Parameter(typeof(object), "oFunc");
+            var expr = Expression.Lambda<Func<TEntity, object>> (
+                    Expression.Convert(
+                        Expression.Call(
+                            Expression.Convert(paramFunc, typedMi.DeclaringType),
+                            typedMi
+                        ),
+                        typeof(object)
+                    ),
+                    paramFunc
+                );
+            return expr.Compile();
+#endif
+        }
+
+        public static Func<object, object> UnTypedGetPropertyFn<TId>(PropertyInfo pi)
+        {
+            var typedPropertyFn = TypedGetPropertyFn<TId>(pi);
+            return x => typedPropertyFn((TEntity)x);
+        }
+
+        /// <summary>
+        /// Func to set the Strongly-typed field
+        /// </summary>
+        public static Action<TEntity, TId> TypedSetPropertyFn<TId>(PropertyInfo pi)
+        {
+            var mi = pi.GetSetMethod();
+            return (Action<TEntity, TId>)Delegate.CreateDelegate(typeof(Action<TEntity, TId>), mi);
+        }
+
+        /// <summary>
+        /// Required to cast the ValueType to an object for caching
+        /// </summary>
+        public static Action<TEntity, object> ValueUnTypedSetPropertyFn<TId>(PropertyInfo pi)
+        {
+            var typedPropertyFn = TypedSetPropertyFn<TId>(pi);
+            return (x, y) => typedPropertyFn(x, (TId)y);
+        }
+
+        public static Action<TEntity, object> ValueUnTypedSetPropertyTypeFn(PropertyInfo pi)
+        {
+            var mi = typeof(StaticAccessors<TEntity>).GetMethod("TypedSetPropertyFn");
+            var genericMi = mi.MakeGenericMethod(pi.PropertyType);
+            var typedSetPropertyFn = (Delegate)genericMi.Invoke(null, new[] { pi });
+
+#if MONOTOUCH || SILVERLIGHT
+            return (x, y) => typedSetPropertyFn.Method.Invoke(x, new[] { y });
+#else
+            var typedMi = typedSetPropertyFn.Method;
+            var paramFunc = Expression.Parameter(typeof(object), "oFunc");
+            var paramValue = Expression.Parameter(typeof(object), "oValue");
+            var expr = Expression.Lambda<Action<TEntity, object>>(
+                    Expression.Call(
+                        Expression.Convert(paramFunc, typedMi.DeclaringType),
+                        typedMi,
+                        Expression.Convert(paramValue, pi.PropertyType)
+                    ),
+                    paramFunc,
+                    paramValue
+                );
+            return expr.Compile();
+#endif
+        }
+
+        /// <summary>
+        /// Required to cast the ValueType to an object for caching
+        /// </summary>
+        public static Action<object, object> UnTypedSetPropertyFn<TId>(PropertyInfo pi)
+        {
+            var typedPropertyFn = TypedSetPropertyFn<TId>(pi);
+            return (x, y) => typedPropertyFn((TEntity)x, (TId)y);
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ReflectionExtensions.cs b/lib/ServiceStack/src/ServiceStack.Common/ReflectionExtensions.cs
new file mode 100644
index 0000000..dc0dd24
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ReflectionExtensions.cs
@@ -0,0 +1,205 @@
+using System;
+using System.Diagnostics;
+using System.Linq;
+using System.Reflection;
+using ServiceStack.Common.Utils;
+
+namespace ServiceStack.Common
+{
+    public static class ReflectionExtensions
+    {
+        public static To PopulateWith<To, From>(this To to, From from)
+        {
+            return ReflectionUtils.PopulateObject(to, from);
+        }
+
+        public static To PopulateWithNonDefaultValues<To, From>(this To to, From from)
+        {
+            return ReflectionUtils.PopulateWithNonDefaultValues(to, from);
+        }
+
+        public static To PopulateFromPropertiesWithAttribute<To, From, TAttr>(this To to, From from)
+        {
+            return ReflectionUtils.PopulateFromPropertiesWithAttribute(to, from, typeof(TAttr));
+        }
+
+        public static T TranslateTo<T>(this object from)
+            where T : new()
+        {
+            var to = new T();
+            return to.PopulateWith(from);
+        }
+
+        public static TAttribute FirstAttribute<TAttribute>(this Type type)
+        {
+            return type.FirstAttribute<TAttribute>(true);
+        }
+
+        public static TAttribute FirstAttribute<TAttribute>(this Type type, bool inherit)
+        {
+            var attrs = type.GetCustomAttributes(typeof(TAttribute), inherit);
+            return (TAttribute)(attrs.Length > 0 ? attrs[0] : null);
+        }
+
+        public static TAttribute FirstAttribute<TAttribute>(this PropertyInfo propertyInfo)
+        {
+            return propertyInfo.FirstAttribute<TAttribute>(true);
+        }
+
+        public static TAttribute FirstAttribute<TAttribute>(this PropertyInfo propertyInfo, bool inherit)
+        {
+            var attrs = propertyInfo.GetCustomAttributes(typeof(TAttribute), inherit);
+            return (TAttribute)(attrs.Length > 0 ? attrs[0] : null);
+        }
+
+        public static bool IsGenericType(this Type type)
+        {
+            while (type != null)
+            {
+                if (type.IsGenericType)
+                    return true;
+
+                type = type.BaseType;
+            }
+            return false;
+        }
+
+        public static Type FirstGenericTypeDefinition(this Type type)
+        {
+            while (type != null)
+            {
+                if (type.IsGenericType)
+                    return type.GetGenericTypeDefinition();
+
+                type = type.BaseType;
+            }
+
+            return null;
+        }
+
+        public static bool IsDynamic(this Assembly assembly)
+        {
+#if MONOTOUCH
+            return false;
+#else
+            try
+            {
+                var isDyanmic = assembly is System.Reflection.Emit.AssemblyBuilder
+                    || string.IsNullOrEmpty(assembly.Location);
+                return isDyanmic;
+            }
+            catch (NotSupportedException)
+            {
+                //Ignore assembly.Location not supported in a dynamic assembly.
+                return true;
+            }
+#endif
+        }
+
+        public static bool IsDebugBuild(this Assembly assembly)
+        {
+            return assembly.GetCustomAttributes(false)
+                .OfType<DebuggableAttribute>()
+                .Select(attr => attr.IsJITTrackingEnabled)
+                .FirstOrDefault();
+        }
+    }
+}
+
+
+#if FALSE && DOTNET35
+//Efficient POCO Translator from: http://www.yoda.arachsys.com/csharp/miscutil/
+using System;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+using System.Reflection;
+
+namespace MiscUtil.Reflection
+{
+    /// <summary>
+    /// Generic class which copies to its target type from a source
+    /// type specified in the Copy method. The types are specified
+    /// separately to take advantage of type inference on generic
+    /// method arguments.
+    /// </summary>
+    public static class PropertyCopy<TTarget> where TTarget : class, new()
+    {
+        /// <summary>
+        /// Copies all readable properties from the source to a new instance
+        /// of TTarget.
+        /// </summary>
+        public static TTarget CopyFrom<TSource>(TSource source) where TSource : class
+        {
+            return PropertyCopier<TSource>.Copy(source);
+        }
+
+        /// <summary>
+        /// Static class to efficiently store the compiled delegate which can
+        /// do the copying. We need a bit of work to ensure that exceptions are
+        /// appropriately propagated, as the exception is generated at type initialization
+        /// time, but we wish it to be thrown as an ArgumentException.
+        /// </summary>
+        private static class PropertyCopier<TSource> where TSource : class
+        {
+            private static readonly Func<TSource, TTarget> copier;
+            private static readonly Exception initializationException;
+
+            internal static TTarget Copy(TSource source)
+            {
+                if (initializationException != null)
+                {
+                    throw initializationException;
+                }
+                if (source == null)
+                {
+                    throw new ArgumentNullException("source");
+                }
+                return copier(source);
+            }
+
+            static PropertyCopier()
+            {
+                try
+                {
+                    copier = BuildCopier();
+                    initializationException = null;
+                }
+                catch (Exception e)
+                {
+                    copier = null;
+                    initializationException = e;
+                }
+            }
+
+            private static Func<TSource, TTarget> BuildCopier()
+            {
+                ParameterExpression sourceParameter = Expression.Parameter(typeof(TSource), "source");
+                var bindings = new List<MemberBinding>();
+                foreach (PropertyInfo sourceProperty in typeof(TSource).GetProperties())
+                {
+                    if (!sourceProperty.CanRead)
+                    {
+                        continue;
+                    }
+                    PropertyInfo targetProperty = typeof(TTarget).GetProperty(sourceProperty.Name);
+                    if (targetProperty == null)
+                    {
+                        throw new ArgumentException("Property " + sourceProperty.Name + " is not present and accessible in " + typeof(TTarget).FullName);
+                    }
+                    if (!targetProperty.CanWrite)
+                    {
+                        throw new ArgumentException("Property " + sourceProperty.Name + " is not writable in " + typeof(TTarget).FullName);
+                    }
+                    if (!targetProperty.PropertyType.IsAssignableFrom(sourceProperty.PropertyType))
+                    {
+                        throw new ArgumentException("Property " + sourceProperty.Name + " has an incompatible type in " + typeof(TTarget).FullName);
+                    }
+                    bindings.Add(Expression.Bind(targetProperty, Expression.Property(sourceParameter, sourceProperty)));
+                }
+                Expression initializer = Expression.MemberInit(Expression.New(typeof(TTarget)), bindings);
+                return Expression.Lambda<Func<TSource,TTarget>>(initializer, sourceParameter).Compile();
+            }
+        }
+    }
+}
+#endif
diff --git a/lib/ServiceStack/src/ServiceStack.Common/RequestContextExtensions.cs b/lib/ServiceStack/src/ServiceStack.Common/RequestContextExtensions.cs
new file mode 100644
index 0000000..7d8d099
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/RequestContextExtensions.cs
@@ -0,0 +1,31 @@
+using ServiceStack.ServiceHost;
+
+namespace ServiceStack.Common
+{
+    public static class RequestContextExtensions
+    {
+        /// <summary>
+        /// Store an entry in the IHttpRequest.Items Dictionary
+        /// </summary>
+        public static void SetItem(this IRequestContext requestContext, string key, object value)
+        {
+            if (requestContext == null) return;
+            var httpReq = requestContext.Get<IHttpRequest>();
+            if (httpReq != null)
+                httpReq.Items[key] = value;
+        }
+
+        /// <summary>
+        /// Get an entry from the IHttpRequest.Items Dictionary
+        /// </summary>
+        public static object GetItem(this IRequestContext requestContext, string key)
+        {
+            if (requestContext == null) return null;
+            object value = null;
+            var httpReq = requestContext.Get<IHttpRequest>();
+            if (httpReq != null)
+                httpReq.Items.TryGetValue(key, out value);
+            return value;
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/AsyncServiceClient.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/AsyncServiceClient.cs
new file mode 100644
index 0000000..88db4ea
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/AsyncServiceClient.cs
@@ -0,0 +1,570 @@
+using System;
+using System.IO;
+using System.Net;
+using System.Text;
+using System.Threading;
+using ServiceStack.Logging;
+using ServiceStack.ServiceHost;
+using ServiceStack.Text;
+using ServiceStack.Common.Web;
+
+namespace ServiceStack.ServiceClient.Web
+{
+    /**
+     * Need to provide async request options
+     * http://msdn.microsoft.com/en-us/library/86wf6409(VS.71).aspx
+     */
+
+    public class AsyncServiceClient
+    {
+        private static readonly ILog Log = LogManager.GetLogger(typeof(AsyncServiceClient));
+        private static readonly TimeSpan DefaultTimeout = TimeSpan.FromSeconds(60);
+        private HttpWebRequest _webRequest = null;
+
+        /// <summary>
+        /// The request filter is called before any request.
+        /// This request filter is executed globally.
+        /// </summary>
+        public static Action<HttpWebRequest> HttpWebRequestFilter { get; set; }
+
+        /// <summary>
+        /// The response action is called once the server response is available.
+        /// It will allow you to access raw response information. 
+        /// This response action is executed globally.
+        /// Note that you should NOT consume the response stream as this is handled by ServiceStack
+        /// </summary>
+        public static Action<HttpWebResponse> HttpWebResponseFilter { get; set; }
+
+        /// <summary>
+        /// Called before request resend, when the initial request required authentication
+        /// </summary>
+        public Action<WebRequest> OnAuthenticationRequired { get; set; }
+
+        const int BufferSize = 4096;
+
+        public ICredentials Credentials { get; set; }
+
+        public bool StoreCookies { get; set; }
+
+        public CookieContainer CookieContainer { get; set; }
+
+        /// <summary>
+        /// The request filter is called before any request.
+        /// This request filter only works with the instance where it was set (not global).
+        /// </summary>
+        public Action<HttpWebRequest> LocalHttpWebRequestFilter { get; set; }
+
+        /// <summary>
+        /// The response action is called once the server response is available.
+        /// It will allow you to access raw response information. 
+        /// Note that you should NOT consume the response stream as this is handled by ServiceStack
+        /// </summary>
+        public Action<HttpWebResponse> LocalHttpWebResponseFilter { get; set; }
+
+        public string BaseUri { get; set; }
+
+        internal class RequestState<TResponse> : IDisposable
+        {
+            private bool _timedOut; // Pass the correct error back even on Async Calls
+
+            public RequestState()
+            {
+                BufferRead = new byte[BufferSize];
+                TextData = new StringBuilder();
+                BytesData = new MemoryStream(BufferSize);
+                WebRequest = null;
+                ResponseStream = null;
+            }
+
+            public string HttpMethod;
+
+            public string Url;
+
+            public StringBuilder TextData;
+
+            public MemoryStream BytesData;
+
+            public byte[] BufferRead;
+
+            public object Request;
+
+            public HttpWebRequest WebRequest;
+
+            public HttpWebResponse WebResponse;
+
+            public Stream ResponseStream;
+
+            public int Completed;
+
+            public int RequestCount;
+
+            public Timer Timer;
+
+            public Action<TResponse> OnSuccess;
+
+            public Action<TResponse, Exception> OnError;
+
+#if SILVERLIGHT
+            public bool HandleCallbackOnUIThread { get; set; }
+#endif
+
+            public void HandleSuccess(TResponse response)
+            {
+                if (this.OnSuccess == null)
+                    return;
+
+#if SILVERLIGHT
+                if (this.HandleCallbackOnUIThread)
+                    System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() => this.OnSuccess(response));
+                else
+                    this.OnSuccess(response);
+#else
+                this.OnSuccess(response);
+#endif
+            }
+            
+            public void HandleError(TResponse response, Exception ex)
+            {
+                if (this.OnError == null)
+                    return;
+
+                Exception toReturn = ex;
+                if (_timedOut)
+                {
+#if SILVERLIGHT
+                    WebException we = new WebException("The request timed out", ex, WebExceptionStatus.RequestCanceled, null);
+#else
+                    WebException we = new WebException("The request timed out", ex, WebExceptionStatus.Timeout, null);
+#endif
+                    toReturn = we;
+                }
+
+#if SILVERLIGHT
+                if (this.HandleCallbackOnUIThread)
+                    System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() => this.OnError(response, toReturn));
+                else
+                    this.OnError(response, toReturn);
+#else
+                OnError(response, toReturn);
+#endif
+            }
+
+            public void StartTimer(TimeSpan timeOut)
+            {
+                this.Timer = new Timer(this.TimedOut, this, (int)timeOut.TotalMilliseconds, System.Threading.Timeout.Infinite);
+            }
+
+            public void TimedOut(object state)
+            {
+                if (Interlocked.Increment(ref Completed) == 1)
+                {
+                    if (this.WebRequest != null)
+                    {
+                        _timedOut = true;
+                        this.WebRequest.Abort();
+                    }
+                }
+                this.Timer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
+                this.Timer.Dispose();
+                this.Dispose();
+            }
+
+            public void Dispose()
+            {
+                if (this.BytesData == null) return;
+                this.BytesData.Dispose();
+                this.BytesData = null;
+            }
+        }
+
+        public bool DisableAutoCompression { get; set; }
+
+        public string UserName { get; set; }
+    
+        public string Password { get; set; }
+
+        public void SetCredentials(string userName, string password)
+        {
+            this.UserName = userName;
+            this.Password = password;
+        }
+
+        public TimeSpan? Timeout { get; set; }
+
+        public string ContentType { get; set; }
+
+        public StreamSerializerDelegate StreamSerializer { get; set; }
+
+        public StreamDeserializerDelegate StreamDeserializer { get; set; }
+
+#if SILVERLIGHT
+        public bool HandleCallbackOnUIThread { get; set; }
+
+        public bool UseBrowserHttpHandling { get; set; }
+
+        public bool ShareCookiesWithBrowser { get; set; }
+#endif
+
+        public void SendAsync<TResponse>(string httpMethod, string absoluteUrl, object request,
+            Action<TResponse> onSuccess, Action<TResponse, Exception> onError)
+        {
+            SendWebRequest(httpMethod, absoluteUrl, request, onSuccess, onError);
+        }
+
+        public void CancelAsync()
+        {
+            if (_webRequest != null)
+            {
+                // Request will be nulled after it throws an exception on its async methods
+                // See - http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.abort
+                _webRequest.Abort();
+            }
+        }
+
+#if !SILVERLIGHT
+        internal static void AllowAutoCompression(HttpWebRequest webRequest)
+        {
+            webRequest.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate");
+            webRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;            
+        }
+#endif
+
+        private RequestState<TResponse> SendWebRequest<TResponse>(string httpMethod, string absoluteUrl, object request, 
+            Action<TResponse> onSuccess, Action<TResponse, Exception> onError)
+        {
+            if (httpMethod == null) throw new ArgumentNullException("httpMethod");
+
+            var requestUri = absoluteUrl;
+            var httpGetOrDelete = (httpMethod == "GET" || httpMethod == "DELETE");
+            var hasQueryString = request != null && httpGetOrDelete;
+            if (hasQueryString)
+            {
+                var queryString = QueryStringSerializer.SerializeToString(request);
+                if (!string.IsNullOrEmpty(queryString))
+                {
+                    requestUri += "?" + queryString;
+                }
+            }
+
+#if SILVERLIGHT
+
+            var creator = this.UseBrowserHttpHandling
+                            ? System.Net.Browser.WebRequestCreator.BrowserHttp
+                            : System.Net.Browser.WebRequestCreator.ClientHttp;
+
+            var webRequest = (HttpWebRequest) creator.Create(new Uri(requestUri));
+
+            if (StoreCookies && !UseBrowserHttpHandling)
+            {
+                if (ShareCookiesWithBrowser)
+                {
+                    if (CookieContainer == null)
+                        CookieContainer = new CookieContainer();
+                    CookieContainer.SetCookies(new Uri(BaseUri), System.Windows.Browser.HtmlPage.Document.Cookies);
+                }
+                
+                webRequest.CookieContainer = CookieContainer;	
+            }
+
+#else
+            _webRequest = (HttpWebRequest)WebRequest.Create(requestUri);
+
+            if (StoreCookies)
+            {
+                _webRequest.CookieContainer = CookieContainer;
+            }
+#endif
+
+#if !SILVERLIGHT
+            if (!DisableAutoCompression)
+            {
+                _webRequest.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate");
+                _webRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;                
+            }
+#endif
+
+            var requestState = new RequestState<TResponse>
+            {
+                HttpMethod = httpMethod,
+                Url = requestUri,
+#if SILVERLIGHT
+                WebRequest = webRequest,
+#else
+                WebRequest = _webRequest,
+#endif
+                Request = request,
+                OnSuccess = onSuccess,
+                OnError = onError,
+#if SILVERLIGHT
+                HandleCallbackOnUIThread = HandleCallbackOnUIThread,
+#endif
+            };
+            requestState.StartTimer(this.Timeout.GetValueOrDefault(DefaultTimeout));
+
+#if SILVERLIGHT
+            SendWebRequestAsync(httpMethod, request, requestState, webRequest);
+#else
+            SendWebRequestAsync(httpMethod, request, requestState, _webRequest);
+#endif
+
+            return requestState;
+        }
+
+        private void SendWebRequestAsync<TResponse>(string httpMethod, object request, 
+            RequestState<TResponse> requestState, HttpWebRequest webRequest)
+        {
+            var httpGetOrDelete = (httpMethod == "GET" || httpMethod == "DELETE");
+            webRequest.Accept = string.Format("{0}, */*", ContentType);
+
+#if !SILVERLIGHT 
+            webRequest.Method = httpMethod;
+#else
+            //Methods others than GET and POST are only supported by Client request creator, see
+            //http://msdn.microsoft.com/en-us/library/cc838250(v=vs.95).aspx
+            
+            if (this.UseBrowserHttpHandling && httpMethod != "GET" && httpMethod != "POST") 
+            {
+                webRequest.Method = "POST"; 
+                webRequest.Headers[HttpHeaders.XHttpMethodOverride] = httpMethod;
+            }
+            else
+            {
+                webRequest.Method = httpMethod;
+            }
+#endif
+
+            if (this.Credentials != null)
+            {
+                webRequest.Credentials = this.Credentials;
+            }
+
+            ApplyWebRequestFilters(webRequest);
+
+            try
+            {
+                if (!httpGetOrDelete && request != null)
+                {
+                    webRequest.ContentType = ContentType;
+                    webRequest.BeginGetRequestStream(RequestCallback<TResponse>, requestState);
+                }
+                else
+                {
+                    requestState.WebRequest.BeginGetResponse(ResponseCallback<TResponse>, requestState);
+                }
+            }
+            catch (Exception ex)
+            {
+                // BeginGetRequestStream can throw if request was aborted
+                HandleResponseError(ex, requestState);
+            }
+        }
+
+        private void RequestCallback<T>(IAsyncResult asyncResult)
+        {
+            var requestState = (RequestState<T>)asyncResult.AsyncState;
+            try
+            {
+                var req = requestState.WebRequest;
+
+                var postStream = req.EndGetRequestStream(asyncResult);
+                StreamSerializer(null, requestState.Request, postStream);
+                postStream.Close();
+                requestState.WebRequest.BeginGetResponse(ResponseCallback<T>, requestState);
+            }
+            catch (Exception ex)
+            {
+                HandleResponseError(ex, requestState);
+            }
+        }
+
+        private void ResponseCallback<T>(IAsyncResult asyncResult)
+        {
+            var requestState = (RequestState<T>)asyncResult.AsyncState;
+            try
+            {
+                var webRequest = requestState.WebRequest;
+
+                requestState.WebResponse = (HttpWebResponse)webRequest.EndGetResponse(asyncResult);
+
+                ApplyWebResponseFilters(requestState.WebResponse);
+
+                // Read the response into a Stream object.
+                var responseStream = requestState.WebResponse.GetResponseStream();
+                requestState.ResponseStream = responseStream;
+
+                responseStream.BeginRead(requestState.BufferRead, 0, BufferSize, ReadCallBack<T>, requestState);
+                return;
+            }
+            catch (Exception ex)
+            {
+                var firstCall = Interlocked.Increment(ref requestState.RequestCount) == 1;
+                if (firstCall && WebRequestUtils.ShouldAuthenticate(ex, this.UserName, this.Password))
+                {
+                    try
+                    {
+                        requestState.WebRequest = (HttpWebRequest)WebRequest.Create(requestState.Url);
+
+                        requestState.WebRequest.AddBasicAuth(this.UserName, this.Password);
+
+                        if (OnAuthenticationRequired != null)
+                        {
+                            OnAuthenticationRequired(requestState.WebRequest);
+                        }
+
+                        SendWebRequestAsync(
+                            requestState.HttpMethod, requestState.Request,
+                            requestState, requestState.WebRequest);
+                    }
+                    catch (Exception /*subEx*/)
+                    {
+                        HandleResponseError(ex, requestState);
+                    }
+                    return;
+                }
+
+                HandleResponseError(ex, requestState);
+            }
+        }
+
+        private void ReadCallBack<T>(IAsyncResult asyncResult)
+        {
+            var requestState = (RequestState<T>)asyncResult.AsyncState;
+            try
+            {
+                var responseStream = requestState.ResponseStream;
+                int read = responseStream.EndRead(asyncResult);
+
+                if (read > 0)
+                {
+                    requestState.BytesData.Write(requestState.BufferRead, 0, read);
+                    responseStream.BeginRead(
+                        requestState.BufferRead, 0, BufferSize, ReadCallBack<T>, requestState);
+
+                    return;
+                }
+
+                Interlocked.Increment(ref requestState.Completed);
+
+                var response = default(T);
+                try
+                {
+                    requestState.BytesData.Position = 0;
+                    using (var reader = requestState.BytesData)
+                    {
+                        response = (T)this.StreamDeserializer(typeof(T), reader);
+                    }
+
+#if SILVERLIGHT
+                    if (this.StoreCookies && this.ShareCookiesWithBrowser && !this.UseBrowserHttpHandling)
+                    {
+                        // browser cookies must be set on the ui thread
+                        System.Windows.Deployment.Current.Dispatcher.BeginInvoke(
+                            () =>
+                                {
+                                    var cookieHeader = this.CookieContainer.GetCookieHeader(new Uri(BaseUri));
+                                    System.Windows.Browser.HtmlPage.Document.Cookies = cookieHeader;
+                                });
+                    }
+#endif
+
+                    requestState.HandleSuccess(response);
+                }
+                catch (Exception ex)
+                {
+                    Log.Debug(string.Format("Error Reading Response Error: {0}", ex.Message), ex);
+                    requestState.HandleError(default(T), ex);
+                }
+                finally
+                {
+                    responseStream.Close();
+                    _webRequest = null;
+                }
+            }
+            catch (Exception ex)
+            {
+                HandleResponseError(ex, requestState);
+            }
+        }
+
+        private void HandleResponseError<TResponse>(Exception exception, RequestState<TResponse> requestState)
+        {
+            var webEx = exception as WebException;
+            if (webEx != null
+#if !SILVERLIGHT 
+                && webEx.Status == WebExceptionStatus.ProtocolError
+#endif
+            )
+            {
+                var errorResponse = ((HttpWebResponse)webEx.Response);
+                Log.Error(webEx);
+                Log.DebugFormat("Status Code : {0}", errorResponse.StatusCode);
+                Log.DebugFormat("Status Description : {0}", errorResponse.StatusDescription);
+
+                var serviceEx = new WebServiceException(errorResponse.StatusDescription)
+                {
+                    StatusCode = (int)errorResponse.StatusCode,
+                };
+
+                try
+                {
+                    using (var stream = errorResponse.GetResponseStream())
+                    {
+                        //Uncomment to Debug exceptions:
+                        //var strResponse = new StreamReader(stream).ReadToEnd();
+                        //Console.WriteLine("Response: " + strResponse);
+                        //stream.Position = 0;
+
+                        serviceEx.ResponseDto = this.StreamDeserializer(typeof(TResponse), stream);
+                        requestState.HandleError((TResponse)serviceEx.ResponseDto, serviceEx);
+                    }
+                }
+                catch (Exception innerEx)
+                {
+                    // Oh, well, we tried
+                    Log.Debug(string.Format("WebException Reading Response Error: {0}", innerEx.Message), innerEx);
+                    requestState.HandleError(default(TResponse), new WebServiceException(errorResponse.StatusDescription, innerEx)
+                        {
+                            StatusCode = (int)errorResponse.StatusCode,
+                        });
+                }
+                return;
+            }
+
+            var authEx = exception as AuthenticationException;
+            if (authEx != null)
+            {
+                var customEx = WebRequestUtils.CreateCustomException(requestState.Url, authEx);
+
+                Log.Debug(string.Format("AuthenticationException: {0}", customEx.Message), customEx);
+                requestState.HandleError(default(TResponse), authEx);
+            }
+
+            Log.Debug(string.Format("Exception Reading Response Error: {0}", exception.Message), exception);
+            requestState.HandleError(default(TResponse), exception);
+
+            _webRequest = null;
+        }
+
+        private void ApplyWebResponseFilters(WebResponse webResponse)
+        {
+            if (!(webResponse is HttpWebResponse)) return;
+
+            if (HttpWebResponseFilter != null)
+                HttpWebResponseFilter((HttpWebResponse)webResponse);
+            if (LocalHttpWebResponseFilter != null)
+                LocalHttpWebResponseFilter((HttpWebResponse)webResponse);
+        }
+
+        private void ApplyWebRequestFilters(HttpWebRequest client)
+        {
+            if (LocalHttpWebRequestFilter != null)
+                LocalHttpWebRequestFilter(client);
+
+            if (HttpWebRequestFilter != null)
+                HttpWebRequestFilter(client);
+        }
+
+        public void Dispose() { }
+    }
+
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/AuthDtos.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/AuthDtos.cs
new file mode 100644
index 0000000..c299534
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/AuthDtos.cs
@@ -0,0 +1,30 @@
+using ServiceStack.ServiceInterface.ServiceModel;
+
+namespace ServiceStack.Common.ServiceClient.Web
+{
+    //Copy from ServiceStack.ServiceInterface.Auth to avoid deps
+    public class Auth
+    {
+        public string provider { get; set; }
+        public string State { get; set; }
+        public string oauth_token { get; set; }
+        public string oauth_verifier { get; set; }
+        public string UserName { get; set; }
+        public string Password { get; set; }
+        public bool? RememberMe { get; set; }
+    }
+
+    public class AuthResponse
+    {
+        public AuthResponse()
+        {
+            this.ResponseStatus = new ResponseStatus();
+        }
+
+        public string SessionId { get; set; }
+
+        public string UserName { get; set; }
+
+        public ResponseStatus ResponseStatus { get; set; }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/DictionaryExtensions.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/DictionaryExtensions.cs
new file mode 100644
index 0000000..7ebfb2e
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/DictionaryExtensions.cs
@@ -0,0 +1,33 @@
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+
+using System.Collections.Generic;
+using System.Collections.Specialized;
+
+namespace ServiceStack.ServiceModel.Extensions
+{
+    public static class DictionaryExtensions
+    {
+        public static Dictionary<string, string> ToDictionary(this NameValueCollection nameValues)
+        {
+            var map = new Dictionary<string, string>();
+            foreach (var key in nameValues.AllKeys)
+            {
+                if (key == null)
+                {
+                    //occurs when no value is specified, e.g. 'path/to/page?debug'
+                    //throw new ArgumentNullException("key", "nameValues: " + nameValues);
+                    continue;
+                }
+
+                var values = nameValues.GetValues(key);
+                if (values != null && values.Length > 0)
+                {
+                    map[key] = values[0];
+                }
+            }
+            return map;
+        }		
+    }
+
+}
+#endif
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/GenericProxy.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/GenericProxy.cs
new file mode 100644
index 0000000..2fd9383
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/GenericProxy.cs
@@ -0,0 +1,48 @@
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+using System.ServiceModel;
+using System.ServiceModel.Description;
+
+namespace ServiceStack.ServiceClient.Web
+{
+    /// <summary>
+    /// Generic Proxy for service calls.
+    /// </summary>
+    /// <typeparam name="T">The service Contract</typeparam>
+    public class GenericProxy<T> : ClientBase<T> where T : class
+    {
+        public GenericProxy()
+            : base()
+        {
+            Initialize();
+        }
+
+        public GenericProxy(string endpoint)
+            : base(endpoint)
+        {
+            Initialize();
+        }
+
+        public GenericProxy(ServiceEndpoint endpoint)
+            : base(endpoint.Binding, endpoint.Address)
+        {
+            Initialize();
+        }
+
+        public void Initialize()
+        {
+            //this.Endpoint.Behaviors.Add(new ServiceEndpointBehaviour());
+        }
+
+        /// <summary>
+        /// Returns the transparent proxy for the service call
+        /// </summary>
+        public T Proxy
+        {
+            get
+            {
+                return base.Channel;
+            }
+        }
+    }
+}
+#endif
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/HttpMethod.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/HttpMethod.cs
new file mode 100644
index 0000000..98d89e1
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/HttpMethod.cs
@@ -0,0 +1,14 @@
+namespace ServiceStack.ServiceClient.Web
+{
+    public static class HttpMethod
+    {
+        public const string Get = "GET";
+        public const string Post = "POST";
+        public const string Put = "PUT";
+        public const string Delete = "DELETE";
+        public const string Options = "OPTIONS";
+        public const string Head = "HEAD";
+        public const string Patch = "PATCH";
+
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/IDuplex.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/IDuplex.cs
new file mode 100644
index 0000000..0fa844b
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/IDuplex.cs
@@ -0,0 +1,14 @@
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+using System.ServiceModel;
+using System.ServiceModel.Channels;
+
+namespace ServiceStack.ServiceClient.Web
+{
+    [ServiceContract(Namespace = "http://services.servicestack.net/", CallbackContract = typeof(IDuplexCallback))]
+    public interface IDuplex
+    {
+        [OperationContract(Action = "*", ReplyAction = "*")]
+        void BeginSend(Message msg);
+    }
+}
+#endif
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/IDuplexCallback.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/IDuplexCallback.cs
new file mode 100644
index 0000000..4431ce0
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/IDuplexCallback.cs
@@ -0,0 +1,14 @@
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+using System.ServiceModel;
+using System.ServiceModel.Channels;
+
+namespace ServiceStack.ServiceClient.Web
+{
+    [ServiceContract(Namespace = "http://services.servicestack.net/")]
+    public interface IDuplexCallback
+    {
+        [OperationContract(Action = "*", ReplyAction = "*")]
+        void OnMessageReceived(Message msg);
+    }
+}
+#endif
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/IOneWay.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/IOneWay.cs
new file mode 100644
index 0000000..c724e4e
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/IOneWay.cs
@@ -0,0 +1,14 @@
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+using System.ServiceModel;
+using System.ServiceModel.Channels;
+
+namespace ServiceStack.ServiceClient.Web
+{
+    [ServiceContract(Namespace = "http://services.servicestack.net/")]
+    public interface IOneWay
+    {
+        [OperationContract(Action = "*", IsOneWay = true)]
+        void SendOneWay(Message requestMsg);
+    }
+}
+#endif
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/ISyncReply.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/ISyncReply.cs
new file mode 100644
index 0000000..863a44a
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/ISyncReply.cs
@@ -0,0 +1,14 @@
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+using System.ServiceModel;
+using System.ServiceModel.Channels;
+
+namespace ServiceStack.ServiceClient.Web
+{
+    [ServiceContract(Namespace = "http://services.servicestack.net/")]
+    public interface ISyncReply
+    {
+        [OperationContract(Action = "*", ReplyAction = "*")]
+        Message Send(Message requestMsg);
+    }
+}
+#endif
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/IWcfServiceClient.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/IWcfServiceClient.cs
new file mode 100644
index 0000000..f1cea25
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/IWcfServiceClient.cs
@@ -0,0 +1,22 @@
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+using System;
+using System.ServiceModel.Channels;
+using ServiceStack.Service;
+using System.Xml;
+
+namespace ServiceStack.ServiceClient.Web
+{
+    public interface IWcfServiceClient : IServiceClient
+    {
+        string Uri { get; set; }
+        void SetProxy(Uri proxyAddress);
+        Message Send(object request);
+        Message Send(object request, string action);
+        Message Send(XmlReader reader, string action);
+        Message Send(Message message);
+        void SendOneWay(object request, string action);
+        void SendOneWay(XmlReader reader, string action);
+        void SendOneWay(Message message);
+    }
+}
+#endif
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/JsonRestClientAsync.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/JsonRestClientAsync.cs
new file mode 100644
index 0000000..d5a3d07
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/JsonRestClientAsync.cs
@@ -0,0 +1,82 @@
+using System;
+using System.IO;
+using System.Threading;
+using ServiceStack.Service;
+using ServiceStack.ServiceHost;
+using ServiceStack.Text;
+
+namespace ServiceStack.ServiceClient.Web
+{
+    public class JsonRestClientAsync 
+        : IRestClientAsync
+    {
+        public const string ContentType = "application/json";
+
+        public JsonRestClientAsync(string baseUri)
+            : this()
+        {
+            this.BaseUri = baseUri.WithTrailingSlash();
+        }
+
+        public JsonRestClientAsync()
+        {
+            this.client = new AsyncServiceClient {
+                ContentType = ContentType,
+                StreamSerializer = SerializeToStream,
+                StreamDeserializer = JsonSerializer.DeserializeFromStream
+            };
+        }
+
+        public TimeSpan? Timeout
+        {
+            get { return this.client.Timeout; }
+            set { this.client.Timeout = value; }
+        }
+
+        private static void SerializeToStream(IRequestContext requestContext, object dto, Stream stream)
+        {
+            JsonSerializer.SerializeToStream(dto, stream);
+        }
+
+        private readonly AsyncServiceClient client;
+
+        public string BaseUri { get; set; }
+
+        public void SetCredentials(string userName, string password)
+        {
+            this.client.SetCredentials(userName, password);
+        }
+
+        private string GetUrl(string relativeOrAbsoluteUrl)
+        {
+            return relativeOrAbsoluteUrl.StartsWith("http:")
+                || relativeOrAbsoluteUrl.StartsWith("https:")
+                     ? relativeOrAbsoluteUrl
+                     : this.BaseUri + relativeOrAbsoluteUrl;
+        }
+
+        public void GetAsync<TResponse>(string relativeOrAbsoluteUrl, Action<TResponse> onSuccess, Action<TResponse, Exception> onError)
+        {
+            this.client.SendAsync(HttpMethod.Get, GetUrl(relativeOrAbsoluteUrl), null, onSuccess, onError);
+        }
+
+        public void DeleteAsync<TResponse>(string relativeOrAbsoluteUrl, Action<TResponse> onSuccess, Action<TResponse, Exception> onError)
+        {
+            this.client.SendAsync(HttpMethod.Delete, GetUrl(relativeOrAbsoluteUrl), null, onSuccess, onError);
+        }
+
+        public void PostAsync<TResponse>(string relativeOrAbsoluteUrl, object request, Action<TResponse> onSuccess, Action<TResponse, Exception> onError)
+        {
+            this.client.SendAsync(HttpMethod.Post, GetUrl(relativeOrAbsoluteUrl), request, onSuccess, onError);
+        }
+
+        public void PutAsync<TResponse>(string relativeOrAbsoluteUrl, object request, Action<TResponse> onSuccess, Action<TResponse, Exception> onError)
+        {
+            this.client.SendAsync(HttpMethod.Put, GetUrl(relativeOrAbsoluteUrl), request, onSuccess, onError);
+        }
+
+        public void Dispose()
+        {
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/JsonServiceClient.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/JsonServiceClient.cs
new file mode 100644
index 0000000..b0be805
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/JsonServiceClient.cs
@@ -0,0 +1,51 @@
+using System;
+using System.IO;
+using ServiceStack.ServiceHost;
+using ServiceStack.ServiceModel.Serialization;
+using ServiceStack.Text;
+
+namespace ServiceStack.ServiceClient.Web
+{
+    public class JsonServiceClient
+        : ServiceClientBase
+    {
+        public override string Format
+        {
+            get { return "json"; }
+        }
+
+        public JsonServiceClient()
+        {
+        }
+
+        public JsonServiceClient(string baseUri) 
+        {			
+            SetBaseUri(baseUri);
+        }
+
+        public JsonServiceClient(string syncReplyBaseUri, string asyncOneWayBaseUri) 
+            : base(syncReplyBaseUri, asyncOneWayBaseUri)
+        {
+        }
+
+        public override string ContentType
+        {
+            get { return String.Format("application/{0}", Format); }
+        }
+
+        public override void SerializeToStream(IRequestContext requestContext, object request, Stream stream)
+        {
+            JsonDataContractSerializer.Instance.SerializeToStream(request, stream);
+        }
+
+        public override T DeserializeFromStream<T>(Stream stream)
+        {
+            return JsonDataContractDeserializer.Instance.DeserializeFromStream<T>(stream);
+        }
+
+        public override StreamDeserializerDelegate StreamDeserializer
+        {
+            get { return JsonSerializer.DeserializeFromStream; }
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/JsvRestClientAsync.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/JsvRestClientAsync.cs
new file mode 100644
index 0000000..8bd3041
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/JsvRestClientAsync.cs
@@ -0,0 +1,79 @@
+using System;
+using System.IO;
+using ServiceStack.Service;
+using ServiceStack.ServiceHost;
+using ServiceStack.Text;
+
+namespace ServiceStack.ServiceClient.Web
+{
+    public class JsvRestClientAsync 
+        : IRestClientAsync
+    {
+        public const string ContentType = "application/jsv";
+
+        public JsvRestClientAsync(string baseUri)
+            : this()
+        {
+            this.BaseUri = baseUri.WithTrailingSlash();
+        }
+
+        public JsvRestClientAsync()
+        {
+            this.client = new AsyncServiceClient {
+                ContentType = ContentType,
+                StreamSerializer = SerializeToStream,
+                StreamDeserializer = TypeSerializer.DeserializeFromStream
+            };
+        }
+
+        public TimeSpan? Timeout
+        {
+            get { return this.client.Timeout; }
+            set { this.client.Timeout = value; }
+        }
+
+        private static void SerializeToStream(IRequestContext requestContext, object dto, Stream stream)
+        {
+            TypeSerializer.SerializeToStream(dto, stream);
+        }
+
+        private readonly AsyncServiceClient client;
+
+        public string BaseUri { get; set; }
+
+        public void SetCredentials(string userName, string password)
+        {
+            this.client.SetCredentials(userName, password);
+        }
+
+        private string GetUrl(string relativeOrAbsoluteUrl)
+        {
+            return relativeOrAbsoluteUrl.StartsWith("http:")
+                || relativeOrAbsoluteUrl.StartsWith("https:")
+                     ? relativeOrAbsoluteUrl
+                     : this.BaseUri + relativeOrAbsoluteUrl;
+        }
+
+        public void GetAsync<TResponse>(string relativeOrAbsoluteUrl, Action<TResponse> onSuccess, Action<TResponse, Exception> onError)
+        {
+            this.client.SendAsync(HttpMethod.Get, GetUrl(relativeOrAbsoluteUrl), null, onSuccess, onError);
+        }
+
+        public void DeleteAsync<TResponse>(string relativeOrAbsoluteUrl, Action<TResponse> onSuccess, Action<TResponse, Exception> onError)
+        {
+            this.client.SendAsync(HttpMethod.Delete, GetUrl(relativeOrAbsoluteUrl), null, onSuccess, onError);
+        }
+
+        public void PostAsync<TResponse>(string relativeOrAbsoluteUrl, object request, Action<TResponse> onSuccess, Action<TResponse, Exception> onError)
+        {
+            this.client.SendAsync(HttpMethod.Post, GetUrl(relativeOrAbsoluteUrl), request, onSuccess, onError);
+        }
+
+        public void PutAsync<TResponse>(string relativeOrAbsoluteUrl, object request, Action<TResponse> onSuccess, Action<TResponse, Exception> onError)
+        {
+            this.client.SendAsync(HttpMethod.Put, GetUrl(relativeOrAbsoluteUrl), request, onSuccess, onError);
+        }
+
+        public void Dispose() {}
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/JsvServiceClient.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/JsvServiceClient.cs
new file mode 100644
index 0000000..00e413c
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/JsvServiceClient.cs
@@ -0,0 +1,56 @@
+using System;
+using System.IO;
+using ServiceStack.ServiceHost;
+using ServiceStack.Text;
+
+namespace ServiceStack.ServiceClient.Web
+{
+    public class JsvServiceClient
+        : ServiceClientBase
+    {
+        public override string Format
+        {
+            get { return "jsv"; }
+        }
+
+        public JsvServiceClient()
+        {
+        }
+
+        public JsvServiceClient(string baseUri) 
+        {
+            SetBaseUri(baseUri);
+        }
+
+        public JsvServiceClient(string syncReplyBaseUri, string asyncOneWayBaseUri) 
+            : base(syncReplyBaseUri, asyncOneWayBaseUri)
+        {
+        }
+
+        public override string ContentType
+        {
+            get { return String.Format("application/{0}", Format); }
+        }
+
+        public override void SerializeToStream(IRequestContext requestContext, object request, Stream stream)
+        {
+            using (var writer = new StreamWriter(stream))
+            {
+                TypeSerializer.SerializeToWriter(request, writer);
+            }
+        }
+
+        public override T DeserializeFromStream<T>(Stream stream)
+        {
+            using (var reader = new StreamReader(stream))
+            {
+                return TypeSerializer.DeserializeFromReader<T>(reader);
+            }
+        }
+
+        public override StreamDeserializerDelegate StreamDeserializer
+        {
+            get { return TypeSerializer.DeserializeFromStream; }
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/ServiceClientBase.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/ServiceClientBase.cs
new file mode 100644
index 0000000..6123758
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/ServiceClientBase.cs
@@ -0,0 +1,835 @@
+using System;
+using System.IO;
+using System.Net;
+#if !(MONOTOUCH || SILVERLIGHT)
+using System.Web;
+#endif
+using ServiceStack.Common;
+using ServiceStack.Common.Web;
+using ServiceStack.Logging;
+using ServiceStack.Service;
+using ServiceStack.ServiceHost;
+using ServiceStack.Text;
+
+namespace ServiceStack.ServiceClient.Web
+{
+
+    /**
+     * Need to provide async request options
+     * http://msdn.microsoft.com/en-us/library/86wf6409(VS.71).aspx
+     */
+    public abstract class ServiceClientBase
+#if !SILVERLIGHT
+ : IServiceClient, IRestClient
+#else
+        : IServiceClient
+#endif
+    {
+        private static readonly ILog log = LogManager.GetLogger(typeof(ServiceClientBase));
+
+        /// <summary>
+        /// The request filter is called before any request.
+        /// This request filter is executed globally.
+        /// </summary>
+        private static Action<HttpWebRequest> httpWebRequestFilter;
+        public static Action<HttpWebRequest> HttpWebRequestFilter
+        {
+            get
+            {
+                return httpWebRequestFilter;
+            }
+            set
+            {
+                httpWebRequestFilter = value;
+                AsyncServiceClient.HttpWebRequestFilter = value;
+            }
+        }
+
+        /// <summary>
+        /// The response action is called once the server response is available.
+        /// It will allow you to access raw response information. 
+        /// This response action is executed globally.
+        /// Note that you should NOT consume the response stream as this is handled by ServiceStack
+        /// </summary>
+        private static Action<HttpWebResponse> httpWebResponseFilter;
+        public static Action<HttpWebResponse> HttpWebResponseFilter
+        {
+            get
+            {
+                return httpWebResponseFilter;
+            }
+            set
+            {
+                httpWebResponseFilter = value;
+                AsyncServiceClient.HttpWebResponseFilter = value;
+            }
+        }
+
+        public const string DefaultHttpMethod = "POST";
+
+        readonly AsyncServiceClient asyncClient;
+
+        protected ServiceClientBase()
+        {
+            this.HttpMethod = DefaultHttpMethod;
+            this.CookieContainer = new CookieContainer();
+            asyncClient = new AsyncServiceClient
+            {
+                ContentType = ContentType,
+                StreamSerializer = SerializeToStream,
+                StreamDeserializer = StreamDeserializer,
+                CookieContainer = this.CookieContainer,
+                UserName = this.UserName,
+                Password = this.Password,
+                LocalHttpWebRequestFilter = this.LocalHttpWebRequestFilter,
+                LocalHttpWebResponseFilter = this.LocalHttpWebResponseFilter
+            };
+            this.StoreCookies = true; //leave
+
+#if SILVERLIGHT
+            asyncClient.HandleCallbackOnUIThread = this.HandleCallbackOnUIThread = true;
+            asyncClient.UseBrowserHttpHandling = this.UseBrowserHttpHandling = false;
+            asyncClient.ShareCookiesWithBrowser = this.ShareCookiesWithBrowser = true;
+#endif
+        }
+
+        protected ServiceClientBase(string syncReplyBaseUri, string asyncOneWayBaseUri)
+            : this()
+        {
+            this.SyncReplyBaseUri = syncReplyBaseUri;
+            this.AsyncOneWayBaseUri = asyncOneWayBaseUri;
+        }
+
+        /// <summary>
+        /// Sets all baseUri properties, using the Format property for the SyncReplyBaseUri and AsyncOneWayBaseUri
+        /// </summary>
+        /// <param name="baseUri">Base URI of the service</param>
+        public void SetBaseUri(string baseUri)
+        {
+            this.BaseUri = baseUri;
+            this.asyncClient.BaseUri = baseUri;
+            this.SyncReplyBaseUri = baseUri.WithTrailingSlash() + Format + "/syncreply/";
+            this.AsyncOneWayBaseUri = baseUri.WithTrailingSlash() + Format + "/asynconeway/";
+        }
+
+        /// <summary>
+        /// Sets all baseUri properties allowing for a temporary override of the Format property
+        /// </summary>
+        /// <param name="baseUri">Base URI of the service</param>
+        /// <param name="format">Override of the Format property for the service</param>
+        //Marked obsolete on 4/11/2012
+        [Obsolete("Please call the SetBaseUri(string baseUri) method, which uses the specific implementation's Format property.")]
+        public void SetBaseUri(string baseUri, string format)
+        {
+            this.BaseUri = baseUri;
+            this.asyncClient.BaseUri = baseUri;
+            this.SyncReplyBaseUri = baseUri.WithTrailingSlash() + format + "/syncreply/";
+            this.AsyncOneWayBaseUri = baseUri.WithTrailingSlash() + format + "/asynconeway/";
+        }
+
+        private bool _disableAutoCompression;
+        /// <summary>
+        /// Whether to Accept Gzip,Deflate Content-Encoding and to auto decompress responses
+        /// </summary>
+        public bool DisableAutoCompression
+        {
+            get { return _disableAutoCompression; }
+            set
+            {
+                _disableAutoCompression = value;
+                asyncClient.DisableAutoCompression = value;
+            }
+        }
+
+        private string _username;
+        /// <summary>
+        /// The user name for basic authentication
+        /// </summary>
+        public string UserName
+        {
+            get { return _username; }
+            set
+            {
+                _username = value;
+                asyncClient.UserName = value;
+            }
+        }
+
+        private string _password;
+        /// <summary>
+        /// The password for basic authentication
+        /// </summary>
+        public string Password
+        {
+            get { return _password; }
+            set
+            {
+                _password = value;
+                asyncClient.Password = value;
+            }
+        }
+
+        /// <summary>
+        /// Sets the username and the password for basic authentication.
+        /// </summary>
+        public void SetCredentials(string userName, string password)
+        {
+            this.UserName = userName;
+            this.Password = password;
+        }
+
+        public string BaseUri { get; set; }
+
+        public abstract string Format { get; }
+
+        public string SyncReplyBaseUri { get; set; }
+
+        public string AsyncOneWayBaseUri { get; set; }
+
+        private TimeSpan? timeout;
+        public TimeSpan? Timeout
+        {
+            get { return this.timeout; }
+            set
+            {
+                this.timeout = value;
+                this.asyncClient.Timeout = value;
+            }
+        }
+
+        public abstract string ContentType { get; }
+
+        public string HttpMethod { get; set; }
+
+#if !SILVERLIGHT
+        public IWebProxy Proxy { get; set; }
+#endif
+
+#if SILVERLIGHT
+        private bool handleCallbackOnUiThread;
+        public bool HandleCallbackOnUIThread
+        {
+            get { return this.handleCallbackOnUiThread; }
+            set { asyncClient.HandleCallbackOnUIThread = this.handleCallbackOnUiThread = value; }
+        }
+
+        private bool useBrowserHttpHandling;
+        public bool UseBrowserHttpHandling
+        {
+            get { return this.useBrowserHttpHandling; }
+            set { asyncClient.UseBrowserHttpHandling = this.useBrowserHttpHandling = value; }
+        }
+
+        private bool shareCookiesWithBrowser;
+        public bool ShareCookiesWithBrowser
+        {
+            get { return this.shareCookiesWithBrowser; }
+            set { asyncClient.ShareCookiesWithBrowser = this.shareCookiesWithBrowser = value; }
+        }
+
+#endif
+
+        private ICredentials credentials;
+
+        /// <summary>
+        /// Gets or sets authentication information for the request.
+        /// Warning: It's recommened to use <see cref="UserName"/> and <see cref="Password"/> for basic auth.
+        /// This property is only used for IIS level authentication.
+        /// </summary>
+        public ICredentials Credentials
+        {
+            set
+            {
+                this.credentials = value;
+                this.asyncClient.Credentials = value;
+            }
+        }
+
+        /// <summary>
+        /// Determines if the basic auth header should be sent with every request.
+        /// By default, the basic auth header is only sent when "401 Unauthorized" is returned.
+        /// </summary>
+        public bool AlwaysSendBasicAuthHeader { get; set; }
+
+
+        /// <summary>
+        /// Specifies if cookies should be stored
+        /// </summary>
+        private bool storeCookies;
+        public bool StoreCookies
+        {
+            get { return storeCookies; }
+            set { asyncClient.StoreCookies = storeCookies = value; }
+        }
+
+        public CookieContainer CookieContainer { get; set; }
+
+        /// <summary>
+        /// Called before request resend, when the initial request required authentication
+        /// </summary>
+        private Action<WebRequest> onAuthenticationRequired { get; set; }
+        public Action<WebRequest> OnAuthenticationRequired
+        {
+            get
+            {
+                return onAuthenticationRequired;
+            }
+            set
+            {
+                onAuthenticationRequired = value;
+                asyncClient.OnAuthenticationRequired = value;
+            }
+        }
+
+        /// <summary>
+        /// The request filter is called before any request.
+        /// This request filter only works with the instance where it was set (not global).
+        /// </summary>
+        private Action<HttpWebRequest> localHttpWebRequestFilter { get; set; }
+        public Action<HttpWebRequest> LocalHttpWebRequestFilter
+        {
+            get
+            {
+                return localHttpWebRequestFilter;
+            }
+            set
+            {
+                localHttpWebRequestFilter = value;
+                asyncClient.LocalHttpWebRequestFilter = value;
+            }
+        }
+
+        /// <summary>
+        /// The response action is called once the server response is available.
+        /// It will allow you to access raw response information. 
+        /// Note that you should NOT consume the response stream as this is handled by ServiceStack
+        /// </summary>
+        private Action<HttpWebResponse> localHttpWebResponseFilter { get; set; }
+        public Action<HttpWebResponse> LocalHttpWebResponseFilter
+        {
+            get
+            {
+                return localHttpWebResponseFilter;
+            }
+            set
+            {
+                localHttpWebResponseFilter = value;
+                asyncClient.LocalHttpWebResponseFilter = value;
+            }
+        }
+
+        public abstract void SerializeToStream(IRequestContext requestContext, object request, Stream stream);
+
+        public abstract T DeserializeFromStream<T>(Stream stream);
+
+        public abstract StreamDeserializerDelegate StreamDeserializer { get; }
+
+#if !SILVERLIGHT
+        public virtual TResponse Send<TResponse>(object request)
+        {
+            var requestUri = this.SyncReplyBaseUri.WithTrailingSlash() + request.GetType().Name;
+            var client = SendRequest(requestUri, request);
+
+            try
+            {
+                var webResponse = client.GetResponse();
+                return HandleResponse<TResponse>(webResponse);
+            }
+            catch (Exception ex)
+            {
+                TResponse response;
+
+                if (!HandleResponseException(ex, requestUri, () => SendRequest(Web.HttpMethod.Post, requestUri, request), c => c.GetResponse(), out response))
+                {
+                    throw;
+                }
+
+                return response;
+            }
+        }
+
+        private bool HandleResponseException<TResponse>(Exception ex, string requestUri, Func<WebRequest> createWebRequest, Func<WebRequest, WebResponse> getResponse, out TResponse response)
+        {
+            try
+            {
+                if (WebRequestUtils.ShouldAuthenticate(ex, this.UserName, this.Password))
+                {
+                    var client = createWebRequest();
+                    client.AddBasicAuth(this.UserName, this.Password);
+                    if (OnAuthenticationRequired != null)
+                    {
+                        OnAuthenticationRequired(client);
+                    }
+
+                    var webResponse = getResponse(client);
+
+                    response = HandleResponse<TResponse>(webResponse);
+                    return true;
+                }
+            }
+            catch (Exception subEx)
+            {
+                // Since we are effectively re-executing the call, 
+                // the new exception should be shown to the caller rather
+                // than the old one.
+                // The new exception is either this one or the one thrown
+                // by the following method.
+                HandleResponseException<TResponse>(subEx, requestUri);
+                throw;
+            }
+
+            // If this doesn't throw, the calling method 
+            // should rethrow the original exception upon
+            // return value of false.
+            HandleResponseException<TResponse>(ex, requestUri);
+
+            response = default(TResponse);
+            return false;
+        }
+
+        private void HandleResponseException<TResponse>(Exception ex, string requestUri)
+        {
+            var webEx = ex as WebException;
+            if (webEx != null && webEx.Status == WebExceptionStatus.ProtocolError)
+            {
+                var errorResponse = ((HttpWebResponse)webEx.Response);
+                log.Error(webEx);
+                log.DebugFormat("Status Code : {0}", errorResponse.StatusCode);
+                log.DebugFormat("Status Description : {0}", errorResponse.StatusDescription);
+
+                var serviceEx = new WebServiceException(errorResponse.StatusDescription)
+                {
+                    StatusCode = (int)errorResponse.StatusCode,
+                    StatusDescription = errorResponse.StatusDescription,
+                };
+
+                try
+                {
+                    if (errorResponse.ContentType.MatchesContentType(ContentType))
+                    {
+                        using (var stream = errorResponse.GetResponseStream())
+                        {
+                            serviceEx.ResponseDto = DeserializeFromStream<TResponse>(stream);
+                        }
+                    }
+                    else
+                    {
+                        serviceEx.ResponseBody = errorResponse.GetResponseStream().ReadFully().FromUtf8Bytes();
+                    }
+                }
+                catch (Exception innerEx)
+                {
+                    // Oh, well, we tried
+                    throw new WebServiceException(errorResponse.StatusDescription, innerEx)
+                    {
+                        StatusCode = (int)errorResponse.StatusCode,
+                        StatusDescription = errorResponse.StatusDescription,
+                    };
+                }
+
+                //Escape deserialize exception handling and throw here
+                throw serviceEx;
+            }
+
+            var authEx = ex as AuthenticationException;
+            if (authEx != null)
+            {
+                throw WebRequestUtils.CreateCustomException(requestUri, authEx);
+            }
+        }
+
+        private WebRequest SendRequest(string requestUri, object request)
+        {
+            return SendRequest(HttpMethod ?? DefaultHttpMethod, requestUri, request);
+        }
+
+        private WebRequest SendRequest(string httpMethod, string requestUri, object request)
+        {
+            return PrepareWebRequest(httpMethod, requestUri, request, client =>
+                {
+                    using (var requestStream = client.GetRequestStream())
+                    {
+                        SerializeToStream(null, request, requestStream);
+                    }
+                });
+        }
+
+        private WebRequest PrepareWebRequest(string httpMethod, string requestUri, object request, Action<HttpWebRequest> sendRequestAction)
+        {
+            if (httpMethod == null)
+                throw new ArgumentNullException("httpMethod");
+
+            if (httpMethod == Web.HttpMethod.Get && request != null)
+            {
+                var queryString = QueryStringSerializer.SerializeToString(request);
+                if (!string.IsNullOrEmpty(queryString))
+                {
+                    requestUri += "?" + queryString;
+                }
+            }
+
+            var client = (HttpWebRequest)WebRequest.Create(requestUri);
+            try
+            {
+                client.Accept = ContentType;
+                client.Method = httpMethod;
+
+                if (Proxy != null) client.Proxy = Proxy;
+                if (this.Timeout.HasValue) client.Timeout = (int)this.Timeout.Value.TotalMilliseconds;
+                if (this.credentials != null) client.Credentials = this.credentials;
+                if (this.AlwaysSendBasicAuthHeader) client.AddBasicAuth(this.UserName, this.Password);
+
+                if (!DisableAutoCompression)
+                {
+                    client.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate");
+                    client.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
+                }
+
+                if (StoreCookies)
+                {
+                    client.CookieContainer = CookieContainer;
+                }
+
+                ApplyWebRequestFilters(client);
+
+                if (httpMethod != Web.HttpMethod.Get
+                    && httpMethod != Web.HttpMethod.Delete)
+                {
+                    client.ContentType = ContentType;
+
+                    if (sendRequestAction != null) sendRequestAction(client);
+                }
+            }
+            catch (AuthenticationException ex)
+            {
+                throw WebRequestUtils.CreateCustomException(requestUri, ex) ?? ex;
+            }
+            return client;
+        }
+
+        private void ApplyWebResponseFilters(WebResponse webResponse)
+        {
+            if (!(webResponse is HttpWebResponse)) return;
+
+            if (HttpWebResponseFilter != null)
+                HttpWebResponseFilter((HttpWebResponse)webResponse);
+            if (LocalHttpWebResponseFilter != null)
+                LocalHttpWebResponseFilter((HttpWebResponse)webResponse);
+        }
+
+        private void ApplyWebRequestFilters(HttpWebRequest client)
+        {
+            if (LocalHttpWebRequestFilter != null)
+                LocalHttpWebRequestFilter(client);
+
+            if (HttpWebRequestFilter != null)
+                HttpWebRequestFilter(client);
+        }
+#else
+        private void SendRequest(string requestUri, object request, Action<WebRequest> callback)
+        {
+            var isHttpGet = HttpMethod != null && HttpMethod.ToUpper() == "GET";
+            if (isHttpGet)
+            {
+                var queryString = QueryStringSerializer.SerializeToString(request);
+                if (!string.IsNullOrEmpty(queryString))
+                {
+                    requestUri += "?" + queryString;
+                }
+            }
+
+            SendRequest(HttpMethod ?? DefaultHttpMethod, requestUri, request, callback);
+        }
+
+        private void SendRequest(string httpMethod, string requestUri, object request, Action<WebRequest> callback)
+        {
+            if (httpMethod == null)
+                throw new ArgumentNullException("httpMethod");
+
+            var client = (HttpWebRequest)WebRequest.Create(requestUri);
+            try
+            {
+                client.Accept = ContentType;
+                client.Method = httpMethod;
+
+                if (this.credentials != null) client.Credentials = this.credentials;
+                if (this.AlwaysSendBasicAuthHeader) client.AddBasicAuth(this.UserName, this.Password);
+
+                if (StoreCookies)
+                {
+                    client.CookieContainer = CookieContainer;
+                }
+
+                if (this.LocalHttpWebRequestFilter != null)
+                    LocalHttpWebRequestFilter(client);
+
+                if (HttpWebRequestFilter != null)
+                    HttpWebRequestFilter(client);
+
+                if (httpMethod != Web.HttpMethod.Get
+                    && httpMethod != Web.HttpMethod.Delete)
+                {
+                    client.ContentType = ContentType;
+
+                    client.BeginGetRequestStream(delegate(IAsyncResult target)
+                    {
+                        var webReq = (HttpWebRequest)target.AsyncState;
+                        var requestStream = webReq.EndGetRequestStream(target);
+                        SerializeToStream(null, request, requestStream);
+                        callback(client);
+                    }, null);
+                }
+            }
+            catch (AuthenticationException ex)
+            {
+                throw WebRequestUtils.CreateCustomException(requestUri, ex) ?? ex;
+            }
+        }
+#endif
+
+        private string GetUrl(string relativeOrAbsoluteUrl)
+        {
+            return relativeOrAbsoluteUrl.StartsWith("http:")
+                || relativeOrAbsoluteUrl.StartsWith("https:")
+                     ? relativeOrAbsoluteUrl
+                     : this.BaseUri.CombineWith(relativeOrAbsoluteUrl);
+        }
+
+#if !SILVERLIGHT
+        private byte[] DownloadBytes(string requestUri, object request)
+        {
+            var webRequest = SendRequest(requestUri, request);
+            using (var response = webRequest.GetResponse())
+            {
+                ApplyWebResponseFilters(response);
+                using (var stream = response.GetResponseStream())
+                    return stream.ReadFully();
+            }
+        }
+#else
+        private void DownloadBytes(string requestUri, object request, Action<byte[]> callback = null)
+        {
+            SendRequest(requestUri, request, webRequest => webRequest.BeginGetResponse(delegate(IAsyncResult result)
+            {
+                var webReq = (HttpWebRequest)result.AsyncState;
+                var response = (HttpWebResponse)webReq.EndGetResponse(result);
+                using (var stream = response.GetResponseStream())
+                {
+                    var bytes = stream.ReadFully();
+                    if (callback != null)
+                    {
+                        callback(bytes);
+                    }
+                }
+            }, null));
+        }
+#endif
+
+        public virtual void SendOneWay(object request)
+        {
+            var requestUri = this.AsyncOneWayBaseUri.WithTrailingSlash() + request.GetType().Name;
+            DownloadBytes(requestUri, request);
+        }
+
+        public virtual void SendOneWay(string relativeOrAbsoluteUrl, object request)
+        {
+            var requestUri = GetUrl(relativeOrAbsoluteUrl);
+            DownloadBytes(requestUri, request);
+        }
+
+        public virtual void SendAsync<TResponse>(object request, Action<TResponse> onSuccess, Action<TResponse, Exception> onError)
+        {
+            var requestUri = this.SyncReplyBaseUri.WithTrailingSlash() + request.GetType().Name;
+            asyncClient.SendAsync(Web.HttpMethod.Post, requestUri, request, onSuccess, onError);
+        }
+
+        public virtual void GetAsync<TResponse>(string relativeOrAbsoluteUrl, Action<TResponse> onSuccess, Action<TResponse, Exception> onError)
+        {
+            asyncClient.SendAsync(Web.HttpMethod.Get, GetUrl(relativeOrAbsoluteUrl), null, onSuccess, onError);
+        }
+
+        public virtual void DeleteAsync<TResponse>(string relativeOrAbsoluteUrl, Action<TResponse> onSuccess, Action<TResponse, Exception> onError)
+        {
+            asyncClient.SendAsync(Web.HttpMethod.Delete, GetUrl(relativeOrAbsoluteUrl), null, onSuccess, onError);
+        }
+
+        public virtual void PostAsync<TResponse>(string relativeOrAbsoluteUrl, object request, Action<TResponse> onSuccess, Action<TResponse, Exception> onError)
+        {
+            asyncClient.SendAsync(Web.HttpMethod.Post, GetUrl(relativeOrAbsoluteUrl), request, onSuccess, onError);
+        }
+
+        public virtual void PutAsync<TResponse>(string relativeOrAbsoluteUrl, object request, Action<TResponse> onSuccess, Action<TResponse, Exception> onError)
+        {
+            asyncClient.SendAsync(Web.HttpMethod.Put, GetUrl(relativeOrAbsoluteUrl), request, onSuccess, onError);
+        }
+
+        public virtual void CancelAsync()
+        {
+            asyncClient.CancelAsync();
+        }
+
+#if !SILVERLIGHT
+        public virtual TResponse Send<TResponse>(string httpMethod, string relativeOrAbsoluteUrl, object request)
+        {
+            var requestUri = GetUrl(relativeOrAbsoluteUrl);
+            var client = SendRequest(httpMethod, requestUri, request);
+
+            try
+            {
+                var webResponse = client.GetResponse();
+                return HandleResponse<TResponse>(webResponse);
+            }
+            catch (Exception ex)
+            {
+                TResponse response;
+
+                if (!HandleResponseException(ex, requestUri, () => SendRequest(httpMethod, requestUri, request), c => c.GetResponse(), out response))
+                {
+                    throw;
+                }
+
+                return response;
+            }
+        }
+
+        public virtual TResponse Get<TResponse>(string relativeOrAbsoluteUrl)
+        {
+            return Send<TResponse>(Web.HttpMethod.Get, relativeOrAbsoluteUrl, null);
+        }
+
+        public virtual TResponse Delete<TResponse>(string relativeOrAbsoluteUrl)
+        {
+            return Send<TResponse>(Web.HttpMethod.Delete, relativeOrAbsoluteUrl, null);
+        }
+
+        public virtual TResponse Post<TResponse>(string relativeOrAbsoluteUrl, object request)
+        {
+            return Send<TResponse>(Web.HttpMethod.Post, relativeOrAbsoluteUrl, request);
+        }
+
+        public virtual TResponse Put<TResponse>(string relativeOrAbsoluteUrl, object request)
+        {
+            return Send<TResponse>(Web.HttpMethod.Put, relativeOrAbsoluteUrl, request);
+        }
+
+		public virtual TResponse Patch<TResponse>(string relativeOrAbsoluteUrl, object request)
+        {
+            return Send<TResponse>(Web.HttpMethod.Patch, relativeOrAbsoluteUrl, request);
+        }
+
+        public virtual TResponse PostFileWithRequest<TResponse>(string relativeOrAbsoluteUrl, FileInfo fileToUpload, object request)
+        {
+            return PostFileWithRequest<TResponse>(relativeOrAbsoluteUrl, fileToUpload.OpenRead(), fileToUpload.Name, request);
+        }
+
+        public virtual TResponse PostFileWithRequest<TResponse>(string relativeOrAbsoluteUrl, Stream fileToUpload, string fileName, object request)
+        {
+            var requestUri = GetUrl(relativeOrAbsoluteUrl);
+            var currentStreamPosition = fileToUpload.Position;
+
+            Func<WebRequest> createWebRequest = () => {
+                var webRequest = PrepareWebRequest(Web.HttpMethod.Post, requestUri, null, null);
+
+                var queryString = QueryStringSerializer.SerializeToString(request);
+#if !MONOTOUCH
+                var nameValueCollection = HttpUtility.ParseQueryString(queryString);
+#endif
+                var boundary = DateTime.Now.Ticks.ToString();
+                webRequest.ContentType = "multipart/form-data; boundary=" + boundary;
+                boundary = "--" + boundary;
+                var newLine = Environment.NewLine;
+                using (var outputStream = webRequest.GetRequestStream())
+                {
+#if !MONOTOUCH
+                    foreach (var key in nameValueCollection.AllKeys)
+                    {
+                        outputStream.Write(boundary + newLine);
+                        outputStream.Write("Content-Disposition: form-data;name=\"{0}\"{1}{2}".FormatWith(key, newLine, newLine));
+                        outputStream.Write(nameValueCollection[key] + newLine);
+                    }
+#endif
+                    outputStream.Write(boundary + newLine);
+                    outputStream.Write("Content-Disposition: form-data;name=\"{0}\";filename=\"{1}\"{2}{3}".FormatWith("upload", fileName, newLine, newLine));
+                    var buffer = new byte[4096];
+                    int byteCount;
+                    while ((byteCount = fileToUpload.Read(buffer, 0, 4096)) > 0)
+                    {
+                        outputStream.Write(buffer, 0, byteCount);
+                    }
+                    outputStream.Write(newLine);
+                    outputStream.Write(boundary + "--");
+                }
+
+                return webRequest;
+            };
+
+            try
+            {
+                var webRequest = createWebRequest();
+                var webResponse = webRequest.GetResponse();
+                return HandleResponse<TResponse>(webResponse);
+            }
+            catch (Exception ex)
+            {
+                TResponse response;
+
+                // restore original position before retry
+                fileToUpload.Seek(currentStreamPosition, SeekOrigin.Begin);
+
+                if (!HandleResponseException(ex, requestUri, createWebRequest, c => c.GetResponse(), out response))
+                {
+                    throw;
+                }
+
+                return response;
+            }
+        }
+
+        public virtual TResponse PostFile<TResponse>(string relativeOrAbsoluteUrl, FileInfo fileToUpload, string mimeType)
+        {
+            return PostFile<TResponse>(relativeOrAbsoluteUrl, fileToUpload.OpenRead(), fileToUpload.Name, mimeType);
+        }
+
+        public virtual TResponse PostFile<TResponse>(string relativeOrAbsoluteUrl, Stream fileToUpload, string fileName, string mimeType)
+        {
+            var currentStreamPosition = fileToUpload.Position;
+            var requestUri = GetUrl(relativeOrAbsoluteUrl);
+            Func<WebRequest> createWebRequest = () => PrepareWebRequest(Web.HttpMethod.Post, requestUri, null, null);
+
+            try
+            {
+                var webRequest = createWebRequest();
+                webRequest.UploadFile(fileToUpload, fileName, mimeType);
+                var webResponse = webRequest.GetResponse();
+                return HandleResponse<TResponse>(webResponse);
+            }
+            catch (Exception ex)
+            {
+                TResponse response;
+
+                // restore original position before retry
+                fileToUpload.Seek(currentStreamPosition, SeekOrigin.Begin);
+
+                if (!HandleResponseException(ex, requestUri, createWebRequest, c => { c.UploadFile(fileToUpload, fileName, mimeType); return c.GetResponse(); }, out response))
+                {
+                    throw;
+                }
+
+                return response;
+            }
+        }
+
+        private TResponse HandleResponse<TResponse>(WebResponse webResponse)
+        {
+            ApplyWebResponseFilters(webResponse);
+            using (var responseStream = webResponse.GetResponseStream())
+            {
+                var response = DeserializeFromStream<TResponse>(responseStream);
+                return response;
+            }
+        }
+#endif
+
+        public void Dispose() { }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/Soap11ServiceClient.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/Soap11ServiceClient.cs
new file mode 100644
index 0000000..3d8bd9d
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/Soap11ServiceClient.cs
@@ -0,0 +1,146 @@
+using System;
+using System.IO;
+using ServiceStack.Service;
+
+namespace ServiceStack.ServiceClient.Web
+{
+
+#if SILVERLIGHT || MONOTOUCH || XBOX
+
+    public class Soap11ServiceClient : IServiceClient
+    {
+        public Soap11ServiceClient(string uri)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void Dispose()
+        {
+            throw new NotImplementedException();
+        }
+
+        public void SetCredentials(string userName, string password)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void GetAsync<TResponse>(string relativeOrAbsoluteUrl, Action<TResponse> onSuccess, 
+            Action<TResponse, Exception> onError)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void DeleteAsync<TResponse>(string relativeOrAbsoluteUrl, Action<TResponse> onSuccess, 
+            Action<TResponse, Exception> onError)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void PostAsync<TResponse>(string relativeOrAbsoluteUrl, object request, 
+            Action<TResponse> onSuccess, Action<TResponse,Exception> onError)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void PutAsync<TResponse>(string relativeOrAbsoluteUrl, object request, Action<TResponse> onSuccess, 
+            Action<TResponse,Exception> onError)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void SendAsync<TResponse>(object request, Action<TResponse> onSuccess, Action<TResponse, Exception> onError)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void SendOneWay(object request)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void SendOneWay(string relativeOrAbsoluteUrl, object request)
+        {
+            throw new NotImplementedException();
+        }
+
+        public TResponse Send<TResponse>(object request)
+        {
+            throw new NotImplementedException();
+        }
+
+        public TResponse PostFile<TResponse>(string relativeOrAbsoluteUrl, FileInfo fileToUpload, string mimeType)
+        {
+            throw new NotImplementedException();
+        }
+
+        public TResponse PostFile<TResponse>(string relativeOrAbsoluteUrl, Stream fileToUpload, string fileName, string mimeType)
+        {
+            throw new NotImplementedException();
+        }
+
+        public TResponse PostFileWithRequest<TResponse>(string relativeOrAbsoluteUrl, FileInfo fileToUpload, object request)
+        {
+            throw new NotImplementedException();
+        }
+        
+        public TResponse PostFileWithRequest<TResponse>(string relativeOrAbsoluteUrl, Stream fileToUpload, string fileName, object request)
+        {
+            throw new NotImplementedException();
+        }
+    }
+
+#else
+    using ServiceStack.Service;
+
+    using System.ServiceModel;
+    using System.ServiceModel.Channels;
+    using ServiceStack.Text;
+
+    public class Soap11ServiceClient : WcfServiceClient
+    {
+        private BasicHttpBinding binding;
+
+        public Soap11ServiceClient(string uri)
+        {
+            this.Uri = uri.WithTrailingSlash() + "Soap11";
+        }
+
+        private Binding BasicHttpBinding
+        {
+            get
+            {
+                if (this.binding == null)
+                {
+                    this.binding = new BasicHttpBinding {
+                        MaxReceivedMessageSize = int.MaxValue,
+                        HostNameComparisonMode = HostNameComparisonMode.StrongWildcard
+                    };
+                }
+                return this.binding;
+            }
+        }
+
+        protected override Binding Binding
+        {
+            get { return this.BasicHttpBinding; }
+        }
+
+        protected override MessageVersion MessageVersion
+        {
+            get { return this.BasicHttpBinding.MessageVersion; }
+        }
+
+        public override void SetProxy(Uri proxyAddress)
+        {
+            var basicBinding = (BasicHttpBinding)Binding;
+
+            basicBinding.ProxyAddress = proxyAddress;
+            basicBinding.UseDefaultWebProxy = false;
+            basicBinding.BypassProxyOnLocal = false;
+            return;
+        }
+    }
+
+#endif
+
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/Soap12ServiceClient.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/Soap12ServiceClient.cs
new file mode 100644
index 0000000..55c72b4
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/Soap12ServiceClient.cs
@@ -0,0 +1,154 @@
+using System;
+using System.IO;
+using ServiceStack.Service;
+using System.Net;
+
+namespace ServiceStack.ServiceClient.Web
+{
+#if SILVERLIGHT || MONOTOUCH || XBOX || ANDROID
+
+    public class Soap12ServiceClient  : IServiceClient
+    {
+        public Soap12ServiceClient(string uri)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void Dispose()
+        {
+            throw new NotImplementedException();
+        }
+
+        public void SetCredentials(string userName, string password)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void GetAsync<TResponse>(string relativeOrAbsoluteUrl, Action<TResponse> onSuccess, 
+            Action<TResponse, Exception> onError)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void DeleteAsync<TResponse>(string relativeOrAbsoluteUrl, Action<TResponse> onSuccess, 
+            Action<TResponse, Exception> onError)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void PostAsync<TResponse>(string relativeOrAbsoluteUrl, object request, 
+            Action<TResponse> onSuccess, Action<TResponse,Exception> onError)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void PutAsync<TResponse>(string relativeOrAbsoluteUrl, object request, Action<TResponse> onSuccess, 
+            Action<TResponse,Exception> onError)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void SendAsync<TResponse>(object request, Action<TResponse> onSuccess, Action<TResponse, Exception> onError)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void SendOneWay(object request)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void SendOneWay(string relativeOrAbsoluteUrl, object request)
+        {
+            throw new NotImplementedException();
+        }
+
+        public TResponse Send<TResponse>(object request)
+        {
+            throw new NotImplementedException();
+        }
+
+        public TResponse PostFile<TResponse>(string relativeOrAbsoluteUrl, FileInfo fileToUpload, string mimeType)
+        {
+            throw new NotImplementedException();
+        }
+
+        public TResponse PostFile<TResponse>(string relativeOrAbsoluteUrl, Stream fileToUpload, string fileName, string mimeType)
+        {
+            throw new NotImplementedException();
+        }
+
+        public TResponse PostFileWithRequest<TResponse>(string relativeOrAbsoluteUrl, FileInfo fileToUpload, object request)
+        {
+            throw new NotImplementedException();
+        }
+        
+        public TResponse PostFileWithRequest<TResponse>(string relativeOrAbsoluteUrl, Stream fileToUpload, string fileName, object request)
+        {
+            throw new NotImplementedException();
+        }
+    }
+
+#else
+
+    using System.ServiceModel;
+    using System.ServiceModel.Channels;
+    using ServiceStack.Text;
+    using ServiceStack.Service;
+
+    public class Soap12ServiceClient : WcfServiceClient
+    {
+        public Soap12ServiceClient(string uri)
+        {
+            this.Uri = uri.WithTrailingSlash() + "Soap12";
+            this.StoreCookies = true;
+        }
+
+        private WSHttpBinding binding;
+
+        private Binding WsHttpBinding
+        {
+            get
+            {
+                if (this.binding == null)
+                {
+                    this.binding = new WSHttpBinding {
+                        MaxReceivedMessageSize = int.MaxValue,
+                        HostNameComparisonMode = HostNameComparisonMode.StrongWildcard,						
+                        MaxBufferPoolSize = 524288,
+                    };
+                    this.binding.Security.Mode = SecurityMode.None;
+                    // CCB Custom
+                    // Yes, you need this to manage cookies yourself.  Seems counterintutive, but set to true,
+                    // it only means that the framework will manage cookie propagation for the same call, which is
+                    // not what we want.
+                    if (StoreCookies)
+                        this.binding.AllowCookies = false;
+                }
+                return this.binding;
+            }
+        }
+
+        protected override Binding Binding
+        {
+            get { return this.WsHttpBinding; }
+        }
+
+        protected override MessageVersion MessageVersion
+        {
+            get { return MessageVersion.Default; }
+        }
+
+        public override void SetProxy(Uri proxyAddress)
+        {
+            var wsHttpBinding = (WSHttpBinding)Binding;
+
+            wsHttpBinding.ProxyAddress = proxyAddress;
+            wsHttpBinding.UseDefaultWebProxy = false;
+            wsHttpBinding.BypassProxyOnLocal = false;
+            return;
+        }
+    }
+
+#endif
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/WcfServiceClient.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/WcfServiceClient.cs
new file mode 100644
index 0000000..a56778a
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/WcfServiceClient.cs
@@ -0,0 +1,383 @@
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+using System;
+using System.IO;
+using System.Net;
+using System.Xml;
+using System.ServiceModel;
+using System.ServiceModel.Channels;
+using System.ServiceModel.Description;
+using System.ServiceModel.Dispatcher;
+using ServiceStack.Common.Utils;
+using ServiceStack.ServiceInterface.ServiceModel;
+
+
+namespace ServiceStack.ServiceClient.Web
+{
+    /// <summary>
+    /// Adds the singleton instance of <see cref="CookieManagerMessageInspector"/> to an endpoint on the client.
+    /// </summary>
+    /// <remarks>
+    /// Based on http://megakemp.wordpress.com/2009/02/06/managing-shared-cookies-in-wcf/
+    /// </remarks>
+    public class CookieManagerEndpointBehavior : IEndpointBehavior
+    {
+        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
+        {
+            return;
+        }
+
+        /// <summary>
+        /// Adds the singleton of the <see cref="ClientIdentityMessageInspector"/> class to the client endpoint's message inspectors.
+        /// </summary>
+        /// <param name="endpoint">The endpoint that is to be customized.</param>
+        /// <param name="clientRuntime">The client runtime to be customized.</param>
+        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
+        {
+            var cm = CookieManagerMessageInspector.Instance;
+            cm.Uri = endpoint.ListenUri.AbsoluteUri;
+            clientRuntime.MessageInspectors.Add(cm);
+        }
+
+        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
+        {
+            return;
+        }
+
+        public void Validate(ServiceEndpoint endpoint)
+        {
+            return;
+        }
+    }
+
+    /// <summary>
+    /// Maintains a copy of the cookies contained in the incoming HTTP response received from any service
+    /// and appends it to all outgoing HTTP requests.
+    /// </summary>
+    /// <remarks>
+    /// This class effectively allows to send any received HTTP cookies to different services,
+    /// reproducing the same functionality available in ASMX Web Services proxies with the <see cref="System.Net.CookieContainer"/> class.
+    /// Based on http://megakemp.wordpress.com/2009/02/06/managing-shared-cookies-in-wcf/
+    /// </remarks>
+    public class CookieManagerMessageInspector : IClientMessageInspector
+    {
+        private static CookieManagerMessageInspector instance;
+        private CookieContainer cookieContainer;
+        public string Uri { get; set; }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ClientIdentityMessageInspector"/> class.
+        /// </summary>
+        public CookieManagerMessageInspector()
+        {
+            cookieContainer = new CookieContainer();
+            Uri = "http://tempuri.org";
+        }
+
+        public CookieManagerMessageInspector(string uri)
+        {
+            cookieContainer = new CookieContainer();
+            Uri = uri;
+        }
+
+        /// <summary>
+        /// Gets the singleton <see cref="ClientIdentityMessageInspector" /> instance.
+        /// </summary>
+        public static CookieManagerMessageInspector Instance
+        {
+            get
+            {
+                if (instance == null)
+                {
+                    instance = new CookieManagerMessageInspector();
+                }
+
+                return instance;
+            }
+        }
+
+        /// <summary>
+        /// Inspects a message after a reply message is received but prior to passing it back to the client application.
+        /// </summary>
+        /// <param name="reply">The message to be transformed into types and handed back to the client application.</param>
+        /// <param name="correlationState">Correlation state data.</param>
+        public void AfterReceiveReply(ref Message reply, object correlationState)
+        {
+            HttpResponseMessageProperty httpResponse =
+                reply.Properties[HttpResponseMessageProperty.Name] as HttpResponseMessageProperty;
+
+            if (httpResponse != null)
+            {
+                string cookie = httpResponse.Headers[HttpResponseHeader.SetCookie];
+
+                if (!string.IsNullOrEmpty(cookie))
+                {
+                    cookieContainer.SetCookies(new System.Uri(Uri), cookie);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Inspects a message before a request message is sent to a service.
+        /// </summary>
+        /// <param name="request">The message to be sent to the service.</param>
+        /// <param name="channel">The client object channel.</param>
+        /// <returns>
+        /// <strong>Null</strong> since no message correlation is used.
+        /// </returns>
+        public object BeforeSendRequest(ref Message request, IClientChannel channel)
+        {
+            HttpRequestMessageProperty httpRequest;
+
+            // The HTTP request object is made available in the outgoing message only when
+            // the Visual Studio Debugger is attacched to the running process
+            if (!request.Properties.ContainsKey(HttpRequestMessageProperty.Name))
+            {
+                request.Properties.Add(HttpRequestMessageProperty.Name, new HttpRequestMessageProperty());
+            }
+
+            httpRequest = (HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name];
+            httpRequest.Headers.Add(HttpRequestHeader.Cookie, cookieContainer.GetCookieHeader(new System.Uri(Uri)));
+
+            return null;
+        }
+    }
+
+    public abstract class WcfServiceClient : IWcfServiceClient
+    {
+        const string XPATH_SOAP_FAULT = "/s:Fault";
+        const string XPATH_SOAP_FAULT_REASON = "/s:Fault/s:Reason";
+        const string NAMESPACE_SOAP = "http://www.w3.org/2003/05/soap-envelope";
+        const string NAMESPACE_SOAP_ALIAS = "s";
+
+        public string Uri { get; set; }
+
+        public abstract void SetProxy(Uri proxyAddress);
+        protected abstract MessageVersion MessageVersion { get; }
+        protected abstract Binding Binding { get; }
+
+        /// <summary>
+        /// Specifies if cookies should be stored
+        /// </summary>
+        // CCB Custom
+        public bool StoreCookies { get; set; }
+
+        public WcfServiceClient()
+        {
+            // CCB Custom
+            this.StoreCookies = true;
+        }
+
+        private static XmlNamespaceManager GetNamespaceManager(XmlDocument doc)
+        {
+            var nsmgr = new XmlNamespaceManager(doc.NameTable);
+            nsmgr.AddNamespace(NAMESPACE_SOAP_ALIAS, NAMESPACE_SOAP);
+            return nsmgr;
+        }
+
+        private static Exception CreateException(Exception e, XmlReader reader)
+        {
+            var doc = new XmlDocument();
+            doc.Load(reader);
+            var node = doc.SelectSingleNode(XPATH_SOAP_FAULT, GetNamespaceManager(doc));
+            if (node != null)
+            {
+                string errMsg = null;
+                var nodeReason = doc.SelectSingleNode(XPATH_SOAP_FAULT_REASON, GetNamespaceManager(doc));
+                if (nodeReason != null)
+                {
+                    errMsg = nodeReason.FirstChild.InnerXml;
+                }
+                return new Exception(string.Format("SOAP FAULT '{0}': {1}", errMsg, node.InnerXml), e);
+            }
+            return e;
+        }
+
+        private ServiceEndpoint SyncReply
+        {
+            get
+            {
+                var contract = new ContractDescription("ServiceStack.ServiceClient.Web.ISyncReply", "http://services.servicestack.net/");
+                var addr = new EndpointAddress(Uri);
+                var endpoint = new ServiceEndpoint(contract, Binding, addr);
+                return endpoint;
+            }
+        }
+
+        public Message Send(object request)
+        {
+            return Send(request, request.GetType().Name);
+        }
+
+        public Message Send(object request, string action)
+        {
+            return Send(Message.CreateMessage(MessageVersion, action, request));
+        }
+
+        public Message Send(XmlReader reader, string action)
+        {
+            return Send(Message.CreateMessage(MessageVersion, action, reader));
+        }
+
+        public Message Send(Message message)
+        {
+            using (var client = new GenericProxy<ISyncReply>(SyncReply))
+            {
+                // CCB Custom...add behavior to propagate cookies across SOAP method calls
+                if (StoreCookies)
+                    client.ChannelFactory.Endpoint.Behaviors.Add(new CookieManagerEndpointBehavior());
+                var response = client.Proxy.Send(message);
+                return response;
+            }
+        }
+
+        public static T GetBody<T>(Message message)
+        {
+            var buffer = message.CreateBufferedCopy(int.MaxValue);
+            try
+            {
+                return buffer.CreateMessage().GetBody<T>();
+            }
+            catch (Exception ex)
+            {
+                throw CreateException(ex, buffer.CreateMessage().GetReaderAtBodyContents());
+            }
+        }
+
+        public T Send<T>(object request)
+        {
+            try
+            {
+                var responseMsg = Send(request);
+                var response = responseMsg.GetBody<T>();
+                var responseStatus = GetResponseStatus(response);
+                if (responseStatus != null && !string.IsNullOrEmpty(responseStatus.ErrorCode))
+                {
+                    throw new WebServiceException(responseStatus.Message, null) {
+                        StatusCode = 500,
+                        ResponseDto = response,
+                        StatusDescription = responseStatus.Message,
+                    };
+                }
+                return response;
+            }
+            catch (WebServiceException webEx)
+            {
+                throw;
+            }
+            catch (Exception ex)
+            {
+                var webEx = ex as WebException ?? ex.InnerException as WebException;
+                if (webEx == null)
+                {
+                    throw new WebServiceException(ex.Message, ex) {
+                        StatusCode = 500,
+                    };
+                }
+
+                var httpEx = webEx.Response as HttpWebResponse;
+                throw new WebServiceException(webEx.Message, webEx) {
+                    StatusCode = httpEx != null ? (int)httpEx.StatusCode : 500
+                };
+            }
+        }
+
+        public ResponseStatus GetResponseStatus(object response)
+        {
+            if (response == null)
+                return null;
+
+            var hasResponseStatus = response as IHasResponseStatus;
+            if (hasResponseStatus != null)
+                return hasResponseStatus.ResponseStatus;
+
+            var propertyInfo = response.GetType().GetProperty("ResponseStatus");
+            if (propertyInfo == null)
+                return null;
+
+            return ReflectionUtils.GetProperty(response, propertyInfo) as ResponseStatus;
+        }
+
+        public TResponse PostFile<TResponse>(string relativeOrAbsoluteUrl, FileInfo fileToUpload, string mimeType)
+        {
+            throw new NotImplementedException();
+        }
+
+        public TResponse PostFile<TResponse>(string relativeOrAbsoluteUrl, Stream fileToUpload, string fileName, string mimeType)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void SendOneWay(object request)
+        {
+            SendOneWay(request, request.GetType().Name);
+        }
+
+        public void SendOneWay(string relativeOrAbsoluteUrl, object request)
+        {
+            SendOneWay(Message.CreateMessage(MessageVersion, relativeOrAbsoluteUrl, request));
+        }
+
+        public void SendOneWay(object request, string action)
+        {
+            SendOneWay(Message.CreateMessage(MessageVersion, action, request));
+        }
+
+        public void SendOneWay(XmlReader reader, string action)
+        {
+            SendOneWay(Message.CreateMessage(MessageVersion, action, reader));
+        }
+
+        public void SendOneWay(Message message)
+        {
+            using (var client = new GenericProxy<IOneWay>(SyncReply))
+            {
+                client.Proxy.SendOneWay(message);
+            }
+        }
+
+        public void SendAsync<TResponse>(object request, Action<TResponse> onSuccess, Action<TResponse, Exception> onError)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void SetCredentials(string userName, string password)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void GetAsync<TResponse>(string relativeOrAbsoluteUrl, Action<TResponse> onSuccess, Action<TResponse, Exception> onError)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void DeleteAsync<TResponse>(string relativeOrAbsoluteUrl, Action<TResponse> onSuccess, Action<TResponse, Exception> onError)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void PostAsync<TResponse>(string relativeOrAbsoluteUrl, object request, Action<TResponse> onSuccess, Action<TResponse, Exception> onError)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void PutAsync<TResponse>(string relativeOrAbsoluteUrl, object request, Action<TResponse> onSuccess, Action<TResponse, Exception> onError)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void Dispose()
+        {
+        }
+
+        public TResponse PostFileWithRequest<TResponse>(string relativeOrAbsoluteUrl, FileInfo fileToUpload, object request)
+        {
+            throw new NotImplementedException();
+        }
+
+        public TResponse PostFileWithRequest<TResponse>(string relativeOrAbsoluteUrl, Stream fileToUpload, string fileName, object request)
+        {
+            throw new NotImplementedException();
+        }
+    }
+}
+#endif
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/WebRequestExtensions.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/WebRequestExtensions.cs
new file mode 100644
index 0000000..8f98274
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/WebRequestExtensions.cs
@@ -0,0 +1,222 @@
+#if !SILVERLIGHT 
+using System;
+using System.IO;
+using System.Net;
+using System.Text;
+using ServiceStack.Common;
+using ServiceStack.Common.Web;
+using ServiceStack.Text;
+
+namespace ServiceStack.ServiceClient.Web
+{
+    public static class WebRequestExtensions
+    {
+        public static string DownloadJsonFromUrl(this string url)
+        {
+            return url.DownloadUrl(ContentType.Json);
+        }
+
+        public static string DownloadXmlFromUrl(this string url)
+        {
+            return url.DownloadUrl(ContentType.Xml);
+        }
+
+        public static string DownloadCsvFromUrl(this string url)
+        {
+            return url.DownloadUrl(ContentType.Csv);
+        }
+
+        public static string DownloadUrl(this string url, string acceptContentType)
+        {
+            var webReq = (HttpWebRequest)WebRequest.Create(url);
+            webReq.Accept = acceptContentType;
+            using (var webRes = webReq.GetResponse())
+                return DownloadText(webRes);
+        }
+
+        public static string DownloadUrl(this string url)
+        {
+            var webReq = WebRequest.Create(url);
+            using (var webRes = webReq.GetResponse())
+                return DownloadText(webRes);
+        }
+
+        public static byte[] DownloadBinaryFromUrl(this string url)
+        {
+            var webReq = WebRequest.Create(url);
+            using (var webRes = webReq.GetResponse())
+                return DownloadBinary(webRes);
+        }
+
+        public static string PostJsonToUrl(this string url, string data)
+        {
+            return SendToUrl(url, HttpMethod.Post, Encoding.UTF8.GetBytes(data), ContentType.Json, ContentType.Json);
+        }
+
+        public static string PostJsonToUrl(this string url, object data)
+        {
+            return SendToUrl(url, HttpMethod.Post, Encoding.UTF8.GetBytes(data.ToJson()), ContentType.Json, ContentType.Json);
+        }
+
+        public static string PostToUrl(this string url, string data, string requestContentType = null, string acceptContentType = null)
+        {
+            return SendToUrl(url, HttpMethod.Post, Encoding.UTF8.GetBytes(data), requestContentType, acceptContentType);
+        }
+
+        public static string PutToUrl(this string url, string data, string requestContentType = null, string acceptContentType = null)
+        {
+            return SendToUrl(url, HttpMethod.Put, Encoding.UTF8.GetBytes(data), requestContentType, acceptContentType);
+        }
+
+        public static string PostToUrl(this string url, byte[] data, string requestContentType = null, string acceptContentType = null)
+        {
+            return SendToUrl(url, HttpMethod.Post, data, requestContentType, acceptContentType);
+        }
+
+        public static string PutToUrl(this string url, byte[] data, string requestContentType = null, string acceptContentType = null)
+        {
+            return SendToUrl(url, HttpMethod.Put, data, requestContentType, acceptContentType);
+        }
+
+        private static string SendToUrl(string url, string httpMethod, byte[] data, string requestContentType = null, string acceptContentType = null)
+        {
+            var webReq = (HttpWebRequest) WebRequest.Create(url);
+            webReq.Method = httpMethod;
+
+            if (requestContentType != null)
+                webReq.ContentType = requestContentType;
+
+            if (acceptContentType != null)
+                webReq.Accept = acceptContentType;
+
+            try
+            {
+                using (var req = webReq.GetRequestStream())
+                    req.Write(data, 0, data.Length);
+            }
+            catch (Exception ex)
+            {
+                Console.WriteLine("Error sending Request: " + ex);
+                throw;
+            }
+
+            try
+            {
+                using (var webRes = webReq.GetResponse())
+                    return DownloadText(webRes);
+            }
+            catch (Exception ex)
+            {
+                Console.WriteLine("Error reading Response: " + ex);
+                throw;
+            }
+        }
+
+        public static string DownloadAsString(this string url)
+        {
+            var webReq = WebRequest.Create(url);
+            using (var webRes = webReq.GetResponse())
+                return DownloadText(webRes);
+        }
+
+        public static string DownloadText(this WebResponse webRes)
+        {
+            using (var stream = webRes.GetResponseStream())
+            using (var reader = new StreamReader(stream))
+            {
+                return reader.ReadToEnd();
+            }
+        }
+
+        public static byte[] DownloadBinary(this WebResponse webRes)
+        {
+            using (var stream = webRes.GetResponseStream())
+            {
+                return stream.ReadFully();
+            }
+        }
+
+        public static HttpWebResponse GetErrorResponse(this string url)
+        {
+            try
+            {
+                var webReq = WebRequest.Create(url);
+                var webRes = webReq.GetResponse();
+                var strRes = webRes.DownloadText();
+                Console.WriteLine("Expected error, got: " + strRes);
+                return null;
+            }
+            catch (WebException webEx)
+            {
+                return (HttpWebResponse)webEx.Response;
+            }
+        }
+
+        public static WebResponse UploadFile(this WebRequest webRequest,
+            FileInfo uploadFileInfo, string uploadFileMimeType)
+        {
+            using (var fileStream = uploadFileInfo.OpenRead())
+            {
+                var fileName = uploadFileInfo.Name;
+
+                webRequest.UploadFile(fileStream, fileName, uploadFileMimeType);
+            }
+
+            return webRequest.GetResponse();
+        }
+
+        public static void UploadFile(this WebRequest webRequest, Stream fileStream, string fileName, string mimeType)
+        {
+            var httpReq = (HttpWebRequest)webRequest;
+            httpReq.UserAgent = Env.ServerUserAgent;
+            httpReq.Method = "POST";
+            httpReq.AllowAutoRedirect = false;
+            httpReq.KeepAlive = false;
+
+            var boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
+
+            httpReq.ContentType = "multipart/form-data; boundary=" + boundary;
+
+            var boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
+
+            var headerTemplate = "\r\n--" + boundary +
+                                 "\r\nContent-Disposition: form-data; name=\"file\"; filename=\"{0}\"\r\nContent-Type: {1}\r\n\r\n";
+
+            var header = string.Format(headerTemplate, fileName, mimeType);
+
+            var headerbytes = System.Text.Encoding.ASCII.GetBytes(header);
+
+            httpReq.ContentLength = fileStream.Length + headerbytes.Length + boundarybytes.Length;
+
+            using (Stream outputStream = httpReq.GetRequestStream())
+            {
+                outputStream.Write(headerbytes, 0, headerbytes.Length);
+
+                byte[] buffer = new byte[4096];
+                int byteCount;
+
+                while ((byteCount = fileStream.Read(buffer, 0, 4096)) > 0)
+                {
+                    outputStream.Write(buffer, 0, byteCount);
+                }
+
+                outputStream.Write(boundarybytes, 0, boundarybytes.Length);
+
+                outputStream.Close();
+            }
+        }
+
+
+        public static void UploadFile(this WebRequest webRequest, Stream fileStream, string fileName)
+        {
+            fileName.ThrowIfNull("fileName");
+            var mimeType = MimeTypes.GetMimeType(fileName);
+            if (mimeType == null)
+                throw new ArgumentException("Mime-type not found for file: " + fileName);
+
+            UploadFile(webRequest, fileStream, fileName, mimeType);
+        }
+    }
+
+}
+#endif
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/WebRequestUtils.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/WebRequestUtils.cs
new file mode 100644
index 0000000..d358dc0
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/WebRequestUtils.cs
@@ -0,0 +1,54 @@
+using System;
+using System.Net;
+using System.Text;
+using ServiceStack.Common.Web;
+
+namespace ServiceStack.ServiceClient.Web
+{
+    public class AuthenticationException : Exception
+    {
+        public AuthenticationException()
+        {
+        }
+
+        public AuthenticationException(string message) : base(message)
+        {
+        }
+
+        public AuthenticationException(string message, Exception innerException) : base(message, innerException)
+        {
+        }
+    }
+
+    internal static class WebRequestUtils
+    {
+        internal static AuthenticationException CreateCustomException(string uri, AuthenticationException ex)
+        {
+            if (uri.StartsWith("https"))
+            {
+                return new AuthenticationException(
+                    string.Format("Invalid remote SSL certificate, overide with: \nServicePointManager.ServerCertificateValidationCallback += ((sender, certificate, chain, sslPolicyErrors) => isValidPolicy);"),
+                    ex);
+            }
+            return null;
+        }
+
+        internal static bool ShouldAuthenticate(Exception ex, string userName, string password)
+        {
+            var webEx = ex as WebException;
+            return (webEx != null
+                    && webEx.Response != null
+                    && ((HttpWebResponse) webEx.Response).StatusCode == HttpStatusCode.Unauthorized
+                    && !string.IsNullOrEmpty(userName)
+                    && !string.IsNullOrEmpty(password));
+        }
+
+        internal static void AddBasicAuth(this WebRequest client, string userName, string password)
+        {
+            client.Headers[HttpHeaders.Authorization]
+                = "basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(userName + ":" + password));
+        }
+
+    }
+
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/WebServiceException.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/WebServiceException.cs
new file mode 100644
index 0000000..911d380
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/WebServiceException.cs
@@ -0,0 +1,113 @@
+using System;
+using System.Collections.Generic;
+using ServiceStack.Common.Utils;
+using ServiceStack.ServiceInterface.ServiceModel;
+using ServiceStack.Text;
+
+namespace ServiceStack.ServiceClient.Web
+{
+    public class WebServiceException
+        : Exception
+    {
+        public WebServiceException() { }
+        public WebServiceException(string message) : base(message) { }
+        public WebServiceException(string message, Exception innerException) : base(message, innerException) { }
+
+        public int StatusCode { get; set; }
+
+        public string StatusDescription { get; set; }
+
+        public object ResponseDto { get; set; }
+        
+        public string ResponseBody { get; set; }
+
+        private string errorCode;
+
+        private void ParseResponseDto()
+        {
+            if (ResponseDto == null)
+            {
+                errorCode = StatusDescription;
+                return;
+            }
+            var jsv = TypeSerializer.SerializeToString(ResponseDto);
+            var map = TypeSerializer.DeserializeFromString<Dictionary<string, string>>(jsv);
+            map = new Dictionary<string, string>(map, StringComparer.InvariantCultureIgnoreCase);
+            string responseStatus;
+            if (!map.TryGetValue("ResponseStatus", out responseStatus)) return;
+
+            var rsMap = TypeSerializer.DeserializeFromString<Dictionary<string, string>>(responseStatus);
+            if (rsMap == null) return;
+            rsMap = new Dictionary<string, string>(rsMap, StringComparer.InvariantCultureIgnoreCase);
+            rsMap.TryGetValue("ErrorCode", out errorCode);
+            rsMap.TryGetValue("Message", out errorMessage);
+            rsMap.TryGetValue("StackTrace", out serverStackTrace);
+        }
+
+        public string ErrorCode
+        {
+            get
+            {
+                if (errorCode == null)
+                {
+                    ParseResponseDto();
+                }
+                return errorCode;
+            }
+        }
+
+        private string errorMessage;
+        public string ErrorMessage
+        {
+            get
+            {
+                if (errorMessage == null)
+                {
+                    ParseResponseDto();
+                }
+                return errorMessage;
+            }
+        }
+
+        private string serverStackTrace;
+        public string ServerStackTrace
+        {
+            get
+            {
+                if (serverStackTrace == null)
+                {
+                    ParseResponseDto();
+                }
+                return serverStackTrace;
+            }
+        }
+
+        public ResponseStatus ResponseStatus
+        {
+            get
+            {
+                if (this.ResponseDto == null)
+                    return null;
+
+                var hasResponseStatus = this.ResponseDto as IHasResponseStatus;
+                if (hasResponseStatus != null)
+                    return hasResponseStatus.ResponseStatus;
+
+                var propertyInfo = this.ResponseDto.GetType().GetProperty("ResponseStatus");
+                if (propertyInfo == null)
+                    return null;
+
+                return ReflectionUtils.GetProperty(this.ResponseDto, propertyInfo) as ResponseStatus;
+            }
+        }
+
+        public List<ResponseError> GetFieldErrors()
+        {
+            var responseStatus = ResponseStatus;
+            if (responseStatus != null)
+                return responseStatus.Errors ?? new List<ResponseError>();
+
+            return new List<ResponseError>();
+        }
+    }
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/XLinqExtensions.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/XLinqExtensions.cs
new file mode 100644
index 0000000..9b2da5a
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/XLinqExtensions.cs
@@ -0,0 +1,273 @@
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+//
+// ServiceStack: Useful extensions to simplify parsing xml with XLinq
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2010 Liquidbit Ltd.
+//
+// Licensed under the same terms of reddis and ServiceStack: new BSD license.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Xml;
+using System.Xml.Linq;
+
+namespace ServiceStack.ServiceModel.Extensions
+{
+    public static class XLinqExtensions
+    {
+        public static string GetString(this XElement el, string name)
+        {
+            return el == null ? null : GetElementValueOrDefault(el, name, x => x.Value);
+        }
+
+        public static bool GetBool(this XElement el, string name)
+        {
+            AssertElementHasValue(el, name);
+            return (bool)GetElement(el, name);
+        }
+
+        public static bool GetBoolOrDefault(this XElement el, string name)
+        {
+            return GetElementValueOrDefault(el, name, x => (bool)x);
+        }
+
+        public static bool? GetNullableBool(this XElement el, string name)
+        {
+            var childEl = GetElement(el, name);
+            return childEl == null || string.IsNullOrEmpty(childEl.Value) ? null : (bool?)childEl;
+        }
+
+        public static int GetInt(this XElement el, string name)
+        {
+            AssertElementHasValue(el, name);
+            return (int)GetElement(el, name);
+        }
+
+        public static int GetIntOrDefault(this XElement el, string name)
+        {
+            return GetElementValueOrDefault(el, name, x => (int) x);
+        }
+
+        public static int? GetNullableInt(this XElement el, string name)
+        {
+            var childEl = GetElement(el, name);
+            return childEl == null || string.IsNullOrEmpty(childEl.Value) ? null : (int?) childEl;
+        }
+
+        public static long GetLong(this XElement el, string name)
+        {
+            AssertElementHasValue(el, name);
+            return (long)GetElement(el, name);
+        }
+
+        public static long GetLongOrDefault(this XElement el, string name)
+        {
+            return GetElementValueOrDefault(el, name, x => (long)x);
+        }
+
+        public static long? GetNullableLong(this XElement el, string name)
+        {
+            var childEl = GetElement(el, name);
+            return childEl == null || string.IsNullOrEmpty(childEl.Value) ? null : (long?)childEl;
+        }
+
+        public static decimal GetDecimal(this XElement el, string name)
+        {
+            AssertElementHasValue(el, name);
+            return (decimal)GetElement(el, name);
+        }
+
+        public static decimal GetDecimalOrDefault(this XElement el, string name)
+        {
+            return GetElementValueOrDefault(el, name, x => (decimal)x);
+        }
+
+        public static decimal? GetNullableDecimal(this XElement el, string name)
+        {
+            var childEl = GetElement(el, name);
+            return childEl == null || string.IsNullOrEmpty(childEl.Value) ? null : (decimal?)childEl;
+        }
+
+        public static DateTime GetDateTime(this XElement el, string name)
+        {
+            AssertElementHasValue(el, name);
+            return (DateTime)GetElement(el, name);
+        }
+
+        public static DateTime GetDateTimeOrDefault(this XElement el, string name)
+        {
+            return GetElementValueOrDefault(el, name, x => (DateTime)x);
+        }
+
+        public static DateTime? GetNullableDateTime(this XElement el, string name)
+        {
+            var childEl = GetElement(el, name);
+            return childEl == null || string.IsNullOrEmpty(childEl.Value) ? null : (DateTime?)childEl;
+        }
+
+        public static TimeSpan GetTimeSpan(this XElement el, string name)
+        {
+            AssertElementHasValue(el, name);
+            return (TimeSpan)GetElement(el, name);
+        }
+
+        public static TimeSpan GetTimeSpanOrDefault(this XElement el, string name)
+        {
+            return GetElementValueOrDefault(el, name, x => (TimeSpan)x);
+        }
+
+        public static TimeSpan? GetNullableTimeSpan(this XElement el, string name)
+        {
+            var childEl = GetElement(el, name);
+            return childEl == null || string.IsNullOrEmpty(childEl.Value) ? null : (TimeSpan?)childEl;
+        }
+
+        public static Guid GetGuid(this XElement el, string name)
+        {
+            AssertElementHasValue(el, name);
+            return (Guid)GetElement(el, name);
+        }
+
+        public static Guid GetGuidOrDefault(this XElement el, string name)
+        {
+            return GetElementValueOrDefault(el, name, x => (Guid)x);
+        }
+
+        public static Guid? GetNullableGuid(this XElement el, string name)
+        {
+            var childEl = GetElement(el, name);
+            return childEl == null || string.IsNullOrEmpty(childEl.Value) ? null : (Guid?)childEl;
+        }
+
+        public static T GetElementValueOrDefault<T>(this XElement element, string name, Func<XElement, T> converter)
+        {
+            if (converter == null)
+            {
+                throw new ArgumentNullException("converter");
+            }
+            var el = GetElement(element, name);
+            return el == null || string.IsNullOrEmpty(el.Value) ? default(T) : converter(el);
+        }
+
+        public static XElement GetElement(this XElement element, string name)
+        {
+            if (element == null)
+            {
+                throw new ArgumentNullException("element");
+            }
+            if (name == null)
+            {
+                throw new ArgumentNullException("name");
+            }
+            return element.AnyElement(name);
+        }
+
+        public static void AssertElementHasValue(this XElement element, string name)
+        {
+            if (element == null)
+            {
+                throw new ArgumentNullException("element");
+            }
+            if (name == null)
+            {
+                throw new ArgumentNullException("name");
+            }
+            var childEl = element.AnyElement(name);
+            if (childEl == null || string.IsNullOrEmpty(childEl.Value))
+            {
+                throw new ArgumentNullException(name, string.Format("{0} is required", name));
+            }
+        }
+
+        public static List<string> GetValues(this IEnumerable<XElement> els)
+        {
+            var values = new List<string>();
+            foreach (var el in els)
+            {
+                values.Add(el.Value);
+            }
+            return values;
+        }
+
+        public static XAttribute AnyAttribute(this XElement element, string name)
+        {
+            if (element == null) return null;
+            foreach (var attribute in element.Attributes())
+            {
+                if (attribute.Name.LocalName == name)
+                {
+                    return attribute;
+                }
+            }
+            return null;
+        }
+
+        public static IEnumerable<XElement> AllElements(this XElement element, string name)
+        {
+            var els = new List<XElement>();
+            if (element == null) return els;
+            foreach (var node in element.Nodes())
+            {
+                if (node.NodeType != XmlNodeType.Element) continue;
+                var childEl = (XElement)node;
+                if (childEl.Name.LocalName == name)
+                {
+                    els.Add(childEl);
+                }
+            }
+            return els;
+        }
+
+        public static XElement AnyElement(this XElement element, string name)
+        {
+            if (element == null) return null;
+            foreach (var node in element.Nodes())
+            {
+                if (node.NodeType != XmlNodeType.Element) continue;
+                var childEl = (XElement)node;
+                if (childEl.Name.LocalName == name)
+                {
+                    return childEl;
+                }
+            }
+            return null;
+        }
+
+        public static XElement AnyElement(this IEnumerable<XElement> elements, string name)
+        {
+            foreach (var element in elements)
+            {
+                if (element.Name.LocalName == name)
+                {
+                    return element;
+                }
+            }
+            return null;
+        }
+
+        public static IEnumerable<XElement> AllElements(this IEnumerable<XElement> elements, string name)
+        {
+            var els = new List<XElement>();
+            foreach (var element in elements)
+            {
+                els.AddRange(AllElements(element, name));
+            }
+            return els;
+        }
+
+        public static XElement FirstElement(this XElement element)
+        {
+            if (element.FirstNode.NodeType == XmlNodeType.Element)
+            {
+                return (XElement) element.FirstNode;
+            }
+            return null;
+        }
+
+    }
+}
+#endif
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/XmlRestClientAsync.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/XmlRestClientAsync.cs
new file mode 100644
index 0000000..4a9e802
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/XmlRestClientAsync.cs
@@ -0,0 +1,81 @@
+using System;
+using System.IO;
+using ServiceStack.Service;
+using ServiceStack.ServiceHost;
+using ServiceStack.Text;
+
+namespace ServiceStack.ServiceClient.Web
+{
+    public class XmlRestClientAsync 
+        : IRestClientAsync
+    {
+        public const string ContentType = "application/xml";
+
+        public XmlRestClientAsync(string baseUri)
+            : this()
+        {
+            this.BaseUri = baseUri.WithTrailingSlash();
+        }
+
+        public XmlRestClientAsync()
+        {
+            this.client = new AsyncServiceClient {
+                ContentType = ContentType,
+                StreamSerializer = SerializeToStream,
+                StreamDeserializer = XmlSerializer.DeserializeFromStream
+            };
+        }
+
+        public TimeSpan? Timeout
+        {
+            get { return this.client.Timeout; }
+            set { this.client.Timeout = value; }
+        }
+
+        private static void SerializeToStream(IRequestContext requestContext, object dto, Stream stream)
+        {
+            XmlSerializer.SerializeToStream(dto, stream);
+        }
+
+        private readonly AsyncServiceClient client;
+
+        public string BaseUri { get; set; }
+
+        public void SetCredentials(string userName, string password)
+        {
+            this.client.SetCredentials(userName, password);
+        }
+
+        private string GetUrl(string relativeOrAbsoluteUrl)
+        {
+            return relativeOrAbsoluteUrl.StartsWith("http:")
+                || relativeOrAbsoluteUrl.StartsWith("https:")
+                     ? relativeOrAbsoluteUrl
+                     : this.BaseUri + relativeOrAbsoluteUrl;
+        }
+
+        public void GetAsync<TResponse>(string relativeOrAbsoluteUrl, Action<TResponse> onSuccess, Action<TResponse, Exception> onError)
+        {
+            this.client.SendAsync(HttpMethod.Get, GetUrl(relativeOrAbsoluteUrl), null, onSuccess, onError);
+        }
+
+        public void DeleteAsync<TResponse>(string relativeOrAbsoluteUrl, Action<TResponse> onSuccess, Action<TResponse, Exception> onError)
+        {
+            this.client.SendAsync(HttpMethod.Delete, GetUrl(relativeOrAbsoluteUrl), null, onSuccess, onError);
+        }
+
+        public void PostAsync<TResponse>(string relativeOrAbsoluteUrl, object request, Action<TResponse> onSuccess, Action<TResponse, Exception> onError)
+        {
+            this.client.SendAsync(HttpMethod.Post, GetUrl(relativeOrAbsoluteUrl), request, onSuccess, onError);
+        }
+
+        public void PutAsync<TResponse>(string relativeOrAbsoluteUrl, object request, Action<TResponse> onSuccess, Action<TResponse, Exception> onError)
+        {
+            this.client.SendAsync(HttpMethod.Put, GetUrl(relativeOrAbsoluteUrl), request, onSuccess, onError);
+        }
+
+        public void Dispose()
+        {
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/XmlServiceClient.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/XmlServiceClient.cs
new file mode 100644
index 0000000..98dea53
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceClient.Web/XmlServiceClient.cs
@@ -0,0 +1,49 @@
+using System.IO;
+using ServiceStack.ServiceHost;
+using ServiceStack.ServiceModel.Serialization;
+using ServiceStack.Text;
+using System;
+
+namespace ServiceStack.ServiceClient.Web
+{
+    public class XmlServiceClient
+        : ServiceClientBase
+    {
+        public override string Format
+        {
+            get { return "xml"; }
+        }
+
+        public XmlServiceClient()
+        {
+        }
+
+        public XmlServiceClient(string baseUri) 
+        {
+            SetBaseUri(baseUri);
+        }
+
+        public XmlServiceClient(string syncReplyBaseUri, string asyncOneWayBaseUri) 
+            : base(syncReplyBaseUri, asyncOneWayBaseUri) {}
+
+        public override string ContentType
+        {
+            get { return String.Format("application/{0}", Format); }
+        }
+
+        public override void SerializeToStream(IRequestContext requestContext, object request, Stream stream)
+        {
+            DataContractSerializer.Instance.SerializeToStream(request, stream);
+        }
+
+        public override T DeserializeFromStream<T>(Stream stream)
+        {
+            return DataContractDeserializer.Instance.DeserializeFromStream<T>(stream);
+        }
+
+        public override StreamDeserializerDelegate StreamDeserializer
+        {
+            get { return XmlSerializer.DeserializeFromStream; }
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/DictionaryExtensions.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/DictionaryExtensions.cs
new file mode 100644
index 0000000..3f41155
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/DictionaryExtensions.cs
@@ -0,0 +1,47 @@
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+
+using System.Collections.Generic;
+using System.Collections.Specialized;
+
+namespace ServiceStack.ServiceModel
+{
+    public static class DictionaryExtensions
+    {
+        public static Dictionary<string, string> ToDictionary(this NameValueCollection nameValues)
+        {
+            if (nameValues == null) return new Dictionary<string, string>();
+
+            var map = new Dictionary<string, string>();
+            foreach (var key in nameValues.AllKeys)
+            {
+                if (key == null)
+                {
+                    //occurs when no value is specified, e.g. 'path/to/page?debug'
+                    //throw new ArgumentNullException("key", "nameValues: " + nameValues);
+                    continue;
+                }
+
+                var values = nameValues.GetValues(key);
+                if (values != null && values.Length > 0)
+                {
+                    map[key] = values[0];
+                }
+            }
+            return map;
+        }
+
+        public static NameValueCollection ToNameValueCollection(this Dictionary<string, string> map)
+        {
+            if (map == null) return new NameValueCollection();
+
+            var nameValues = new NameValueCollection();
+            foreach (var item in map)
+            {
+                nameValues.Add(item.Key, item.Value);
+            }
+            return nameValues;
+        }
+    }
+
+}
+#endif
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Serialization/DataContractDeserializer.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Serialization/DataContractDeserializer.cs
new file mode 100644
index 0000000..10bb058
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Serialization/DataContractDeserializer.cs
@@ -0,0 +1,78 @@
+using System;
+using System.IO;
+using System.Text;
+using System.Runtime.Serialization;
+using System.Xml;
+using ServiceStack.DesignPatterns.Serialization;
+
+namespace ServiceStack.ServiceModel.Serialization
+{
+
+    public class DataContractDeserializer : IStringDeserializer
+    {
+
+        /// <summary>
+        /// Default MaxStringContentLength is 8k, and throws an exception when reached
+        /// </summary>
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+        private readonly XmlDictionaryReaderQuotas quotas;
+#endif
+
+        public static DataContractDeserializer Instance 
+            = new DataContractDeserializer(
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+                new XmlDictionaryReaderQuotas { MaxStringContentLength = 1024 * 1024, }
+#endif
+                );
+
+        public DataContractDeserializer(
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+            XmlDictionaryReaderQuotas quotas=null
+#endif
+            )
+        {
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+            this.quotas = quotas;
+#endif
+        }
+
+        public object Parse(string xml, Type type)
+        {
+            try
+            {
+                var bytes = Encoding.UTF8.GetBytes(xml);
+
+#if MONOTOUCH				
+                using (var reader = XmlDictionaryReader.CreateTextReader(bytes, null))
+#elif SILVERLIGHT
+                using (var reader = XmlDictionaryReader.CreateTextReader(bytes, XmlDictionaryReaderQuotas.Max))
+#else
+                using (var reader = XmlDictionaryReader.CreateTextReader(bytes, this.quotas))
+#endif
+                {
+                    var serializer = new System.Runtime.Serialization.DataContractSerializer(type);
+                    return serializer.ReadObject(reader);
+                }
+            }
+            catch (Exception ex)
+            {
+                throw new SerializationException("DeserializeDataContract: Error converting type: " + ex.Message, ex);
+            }
+        }
+
+        public T Parse<T>(string xml)
+        {
+            var type = typeof(T);
+            return (T)Parse(xml, type);
+        }
+
+        public T DeserializeFromStream<T>(Stream stream)
+        {
+            var serializer = new System.Runtime.Serialization.DataContractSerializer(typeof(T));
+            return (T)serializer.ReadObject(stream);
+        }
+
+    }
+
+
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Serialization/DataContractSerializer.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Serialization/DataContractSerializer.cs
new file mode 100644
index 0000000..adeb048
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Serialization/DataContractSerializer.cs
@@ -0,0 +1,101 @@
+using System;
+using System.IO;
+using System.Runtime.Serialization;
+using System.Text;
+using System.Xml;
+using ServiceStack.DesignPatterns.Serialization;
+
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+using System.IO.Compression;
+#endif
+
+namespace ServiceStack.ServiceModel.Serialization
+{
+    public class DataContractSerializer : IStringSerializer 
+    {
+        private static readonly Encoding Encoding = Encoding.UTF8;// new UTF8Encoding(true);
+        public static DataContractSerializer Instance = new DataContractSerializer();
+
+        public string Parse<XmlDto>(XmlDto from, bool indentXml)
+        {
+            try
+            {
+                using (var ms = new MemoryStream())
+                {
+                    var serializer = new System.Runtime.Serialization.DataContractSerializer(from.GetType());
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+                    using (var xw = new XmlTextWriter(ms, Encoding)) 
+                    {
+                        if (indentXml)
+                        {
+                            xw.Formatting = Formatting.Indented;	
+                        }
+
+                        serializer.WriteObject(xw, from);
+                        xw.Flush();
+#else
+                        serializer.WriteObject(ms, from);
+#endif
+
+                        ms.Seek(0, SeekOrigin.Begin);
+                        using (var reader = new StreamReader(ms))
+                        {
+                            return reader.ReadToEnd();
+                        }
+
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+                    }
+#endif
+                }
+            }
+            catch (Exception ex)
+            {
+                throw new SerializationException(string.Format("Error serializing object of type {0}", from.GetType().FullName), ex);
+            }
+        }
+
+        public string Parse<XmlDto>(XmlDto from)
+        {
+            return Parse(from, false);
+        }
+
+
+        public void SerializeToStream(object obj, Stream stream)
+        {
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+            using (var xw = new XmlTextWriter(stream, Encoding))
+            {
+                var serializer = new System.Runtime.Serialization.DataContractSerializer(obj.GetType());
+                serializer.WriteObject(xw, obj);
+            }
+#else
+            var serializer = new System.Runtime.Serialization.DataContractSerializer(obj.GetType());
+            serializer.WriteObject(stream, obj);
+#endif
+        }
+
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+        public void CompressToStream<XmlDto>(XmlDto from, Stream stream)
+        {
+            using (var deflateStream = new DeflateStream(stream, CompressionMode.Compress))
+            using (var xw = new XmlTextWriter(deflateStream, Encoding))
+            {
+                var serializer = new System.Runtime.Serialization.DataContractSerializer(from.GetType());
+                serializer.WriteObject(xw, from);
+                xw.Flush();
+            }
+        }
+
+        public byte[] Compress<XmlDto>(XmlDto from)
+        {
+            using (var ms = new MemoryStream())
+            {
+                CompressToStream(from, ms);
+                
+                return ms.ToArray();
+            }
+        }
+#endif
+
+    }
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Serialization/JsonDataContractDeserializer.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Serialization/JsonDataContractDeserializer.cs
new file mode 100644
index 0000000..270f2d0
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Serialization/JsonDataContractDeserializer.cs
@@ -0,0 +1,89 @@
+using System;
+using System.IO;
+using System.Runtime.Serialization;
+using System.Text;
+using ServiceStack.DesignPatterns.Serialization;
+using ServiceStack.Text;
+
+namespace ServiceStack.ServiceModel.Serialization
+{
+    public class JsonDataContractDeserializer 
+    {
+        public static JsonDataContractDeserializer Instance = new JsonDataContractDeserializer();
+
+        public ITextSerializer TextSerializer { get; set; }
+
+        public bool UseBcl { get; set; }
+
+        public object DeserializeFromString(string json, Type returnType)
+        {
+            if (TextSerializer != null)
+                return TextSerializer.DeserializeFromString(json, returnType);
+
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+            if (!UseBcl)
+                return JsonSerializer.DeserializeFromString(json, returnType);
+
+            try
+            {
+                using (var ms = new MemoryStream())
+                {
+                    var bytes = Encoding.UTF8.GetBytes(json);
+                    ms.Write(bytes, 0, bytes.Length);
+                    ms.Position = 0;
+                    var serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(returnType);
+                    return serializer.ReadObject(ms);
+                }
+            }
+            catch (Exception ex)
+            {
+                throw new SerializationException("JsonDataContractDeserializer: Error converting to type: " + ex.Message, ex);
+            }
+#else
+                return JsonSerializer.DeserializeFromString(json, returnType);
+#endif
+        }
+
+        public T DeserializeFromString<T>(string json)
+        {
+            if (TextSerializer != null)
+                return TextSerializer.DeserializeFromString<T>(json);
+
+            if (UseBcl)
+                return (T)DeserializeFromString(json, typeof(T));
+
+            return JsonSerializer.DeserializeFromString<T>(json);
+        }
+
+        public T DeserializeFromStream<T>(Stream stream)
+        {
+            if (TextSerializer != null)
+                return TextSerializer.DeserializeFromStream<T>(stream);
+
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+            if (UseBcl)
+            {
+                var serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(T));
+                return (T)serializer.ReadObject(stream);				
+            }
+#endif
+            return JsonSerializer.DeserializeFromStream<T>(stream);
+        }
+
+        public object DeserializeFromStream(Type type, Stream stream)
+        {
+            if (TextSerializer != null)
+                return TextSerializer.DeserializeFromStream(type, stream);
+
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+            if (UseBcl)
+            {
+                var serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(type);
+                return serializer.ReadObject(stream);
+            }
+#endif
+
+            return JsonSerializer.DeserializeFromStream(type, stream);
+        }
+    }
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Serialization/JsonDataContractSerializer.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Serialization/JsonDataContractSerializer.cs
new file mode 100644
index 0000000..aecdd43
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Serialization/JsonDataContractSerializer.cs
@@ -0,0 +1,75 @@
+using System;
+using System.IO;
+using System.Runtime.Serialization;
+using ServiceStack.DesignPatterns.Serialization;
+using ServiceStack.Text;
+
+namespace ServiceStack.ServiceModel.Serialization
+{
+    public class JsonDataContractSerializer 
+    {
+        public static JsonDataContractSerializer Instance = new JsonDataContractSerializer();
+
+        public ITextSerializer TextSerializer { get; set; }
+
+        public static void UseSerializer(ITextSerializer textSerializer)
+        {
+            Instance.TextSerializer = textSerializer;
+            JsonDataContractDeserializer.Instance.TextSerializer = textSerializer;
+        }
+
+        public bool UseBcl { get; set; }
+
+        public string SerializeToString<T>(T obj)
+        {
+            if (TextSerializer != null)
+                return TextSerializer.SerializeToString(obj);
+
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+            if (!UseBcl)
+                return JsonSerializer.SerializeToString(obj);
+
+            if (obj == null) return null;
+            var type = obj.GetType();
+            try
+            {
+                using (var ms = new MemoryStream())
+                {
+                    var serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(type);
+                    serializer.WriteObject(ms, obj);
+                    ms.Position = 0;
+                    using (var sr = new StreamReader(ms))
+                    {
+                        return sr.ReadToEnd();
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                throw new SerializationException("JsonDataContractSerializer: Error converting type: " + ex.Message, ex);
+            }
+#else
+                return JsonSerializer.SerializeToString(obj);
+#endif
+        }
+
+        public void SerializeToStream<T>(T obj, Stream stream)
+        {
+            if (TextSerializer != null)
+            {
+                TextSerializer.SerializeToStream(obj, stream);
+            }
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+            else if (UseBcl)
+            {
+                var serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(obj.GetType());
+                serializer.WriteObject(stream, obj);
+            }
+#endif
+            else
+            {
+                JsonSerializer.SerializeToStream(obj, stream);
+            }
+        }
+    }
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Serialization/KeyValueDataContractDeserializer.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Serialization/KeyValueDataContractDeserializer.cs
new file mode 100644
index 0000000..4b8cc4f
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Serialization/KeyValueDataContractDeserializer.cs
@@ -0,0 +1,41 @@
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+
+namespace ServiceStack.ServiceModel.Serialization
+{
+    public class KeyValueDataContractDeserializer
+    {
+        public static KeyValueDataContractDeserializer Instance = new KeyValueDataContractDeserializer();
+
+        public object Parse(NameValueCollection nameValues, Type returnType)
+        {
+            return Parse(nameValues.ToDictionary(), returnType);
+        }
+
+        readonly Dictionary<Type, StringMapTypeDeserializer> typeStringMapSerializerMap
+            = new Dictionary<Type, StringMapTypeDeserializer>();
+
+        public object Parse(IDictionary<string, string> keyValuePairs, Type returnType)
+        {
+            StringMapTypeDeserializer stringMapTypeDeserializer;
+            lock (typeStringMapSerializerMap)
+            {
+                if (!typeStringMapSerializerMap.TryGetValue(returnType, out stringMapTypeDeserializer))
+                {
+                    stringMapTypeDeserializer = new StringMapTypeDeserializer(returnType);
+                    typeStringMapSerializerMap.Add(returnType, stringMapTypeDeserializer);
+                }
+            }
+
+            return stringMapTypeDeserializer.CreateFromMap(keyValuePairs);
+        }
+
+        public To Parse<To>(IDictionary<string, string> keyValuePairs)
+        {
+            return (To)Parse(keyValuePairs, typeof(To));
+        }
+    }
+}
+#endif
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Serialization/StringMapTypeDeserializer.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Serialization/StringMapTypeDeserializer.cs
new file mode 100644
index 0000000..9a8ec0d
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Serialization/StringMapTypeDeserializer.cs
@@ -0,0 +1,117 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using ServiceStack.Common;
+using ServiceStack.Common.Utils;
+using ServiceStack.Logging;
+using ServiceStack.Text;
+using ServiceStack.Text.Common;
+using ServiceStack.Text.Jsv;
+
+namespace ServiceStack.ServiceModel.Serialization
+{
+    /// <summary>
+    /// Serializer cache of delegates required to create a type from a string map (e.g. for REST urls)
+    /// </summary>
+    public class StringMapTypeDeserializer
+    {
+        private static readonly ILog Log = LogManager.GetLogger(typeof(StringMapTypeDeserializer));
+
+        internal class PropertySerializerEntry
+        {
+            public PropertySerializerEntry(SetPropertyDelegate propertySetFn, ParseStringDelegate propertyParseStringFn)
+            {
+                PropertySetFn = propertySetFn;
+                PropertyParseStringFn = propertyParseStringFn;
+            }
+
+            public SetPropertyDelegate PropertySetFn;
+            public ParseStringDelegate PropertyParseStringFn;
+            public Type PropertyType;
+        }
+
+        private readonly Type type;
+        private readonly Dictionary<string, PropertySerializerEntry> propertySetterMap
+            = new Dictionary<string, PropertySerializerEntry>(StringComparer.InvariantCultureIgnoreCase);
+
+        public StringMapTypeDeserializer(Type type)
+        {
+            this.type = type;
+
+            if (type.IsOrHasGenericInterfaceTypeOf(typeof(IEnumerable<>)))
+                return;
+
+            foreach (var propertyInfo in type.GetProperties())
+            {
+                var propertySetFn = JsvDeserializeType.GetSetPropertyMethod(type, propertyInfo);
+			    var propertyType = propertyInfo.PropertyType;
+				var propertyParseStringFn = JsvReader.GetParseFn(propertyType);
+				var propertySerializer = new PropertySerializerEntry(propertySetFn, propertyParseStringFn) { PropertyType = propertyType };
+
+                var attr = propertyInfo.FirstAttribute<DataMemberAttribute>();
+                if (attr != null && attr.Name != null)
+                {
+                    propertySetterMap[attr.Name] = propertySerializer;                    
+                }
+                propertySetterMap[propertyInfo.Name] = propertySerializer;
+            }
+        }
+
+        public object PopulateFromMap(object instance, IDictionary<string, string> keyValuePairs)
+        {
+            string propertyName = null;
+		    string propertyTextValue = null;
+		    PropertySerializerEntry propertySerializerEntry = null;
+
+            try
+            {
+                if (instance == null) instance = ReflectionUtils.CreateInstance(type);
+
+                foreach (var pair in keyValuePairs)
+                {
+					propertyName = pair.Key;
+					propertyTextValue = pair.Value;
+
+                    if (!propertySetterMap.TryGetValue(propertyName, out propertySerializerEntry))
+                    {
+                        if (propertyName != "format" && propertyName != "callback" && propertyName != "debug")
+                        {
+                            Log.WarnFormat("Property '{0}' does not exist on type '{1}'", propertyName, type.FullName);
+                        }
+                        continue;
+                    }
+
+                    var value = propertySerializerEntry.PropertyParseStringFn(propertyTextValue);
+                    if (value == null)
+                    {
+                        Log.WarnFormat("Could not create instance on '{0}' for property '{1}' with text value '{2}'",
+                                       instance, propertyName, propertyTextValue);
+                        continue;
+                    }
+                    propertySerializerEntry.PropertySetFn(instance, value);
+                }
+                return instance;
+
+            }
+            catch (Exception ex)
+            {
+                var serializationException = new SerializationException("KeyValueDataContractDeserializer: Error converting to type: " + ex.Message, ex);
+                if (propertyName != null) {
+                    serializationException.Data.Add("propertyName", propertyName);
+                }
+                if (propertyTextValue != null) {
+                    serializationException.Data.Add("propertyValueString", propertyTextValue);
+                }
+                if (propertySerializerEntry != null && propertySerializerEntry.PropertyType != null) {
+                    serializationException.Data.Add("propertyType", propertySerializerEntry.PropertyType);
+                }
+			    throw serializationException;
+            }
+        }
+
+        public object CreateFromMap(IDictionary<string, string> keyValuePairs)
+        {
+            return PopulateFromMap(null, keyValuePairs);
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Serialization/XmlSerializableDeserializer.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Serialization/XmlSerializableDeserializer.cs
new file mode 100644
index 0000000..7867ed3
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Serialization/XmlSerializableDeserializer.cs
@@ -0,0 +1,73 @@
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+using System;
+using System.IO;
+using System.Text;
+using System.Xml;
+using System.Runtime.Serialization;
+using ServiceStack.DesignPatterns.Serialization;
+
+namespace ServiceStack.ServiceModel.Serialization
+{
+    public class XmlSerializableDeserializer : IStringDeserializer
+    {
+        public static XmlSerializableDeserializer Instance = new XmlSerializableDeserializer();
+
+        public To Parse<To>(string xml)
+        {
+            var type = typeof(To);
+            return (To)Parse(xml, type);
+        }
+
+        public object Parse(string xml, Type type)
+        {
+            try
+            {
+                var bytes = Encoding.UTF8.GetBytes(xml);
+                using (var reader = XmlDictionaryReader.CreateTextReader(bytes, new XmlDictionaryReaderQuotas()))
+                {
+                    var serializer = new System.Xml.Serialization.XmlSerializer(type);
+                    return serializer.Deserialize(reader);
+                }
+            }
+            catch (Exception ex)
+            {
+                throw new SerializationException(string.Format("Error serializing object of type {0}", type.FullName), ex);
+            }
+        }
+
+        public To Parse<To>(TextReader from)
+        {
+            var type = typeof(To);
+            try
+            {
+                using (from)
+                {
+                    var serializer = new System.Xml.Serialization.XmlSerializer(type);
+                    return (To)serializer.Deserialize(from);
+                }
+            }
+            catch (Exception ex)
+            {
+                throw new SerializationException(string.Format("Error serializing object of type {0}", type.FullName), ex);
+            }
+        }
+
+        public To Parse<To>(Stream from)
+        {
+            var type = typeof(To);
+            try
+            {
+                using (var reader = XmlDictionaryReader.CreateTextReader(from, new XmlDictionaryReaderQuotas()))
+                {
+                    var serializer = new System.Xml.Serialization.XmlSerializer(type);
+                    return (To)serializer.Deserialize(reader);
+                }
+            }
+            catch (Exception ex)
+            {
+                throw new SerializationException(string.Format("Error serializing object of type {0}", type.FullName), ex);
+            }
+        }
+    }
+}
+#endif
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Serialization/XmlSerializableSerializer.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Serialization/XmlSerializableSerializer.cs
new file mode 100644
index 0000000..1f4c862
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Serialization/XmlSerializableSerializer.cs
@@ -0,0 +1,42 @@
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+using System;
+using System.IO;
+using System.Runtime.Serialization;
+using System.Text;
+using System.Xml;
+using ServiceStack.DesignPatterns.Serialization;
+using ServiceStack.ServiceModel.Support;
+
+namespace ServiceStack.ServiceModel.Serialization
+{
+    public class XmlSerializableSerializer : IStringSerializer 
+    {
+        public static XmlSerializableSerializer Instance = new XmlSerializableSerializer();
+
+        public string Parse<XmlDto>(XmlDto from)
+        {
+            try
+            {
+                using (var ms = new MemoryStream())
+                {
+                    using (XmlWriter xw = new XmlTextWriter(ms, Encoding.UTF8))
+                    {
+                        var ser = new XmlSerializerWrapper(from.GetType());
+                        ser.WriteObject(xw, from);
+                        xw.Flush();
+                        ms.Seek(0, SeekOrigin.Begin);
+                        using (var reader = new StreamReader(ms))
+                        {
+                            return reader.ReadToEnd();
+                        }
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                throw new SerializationException(string.Format("Error serializing object of type {0}", from.GetType().FullName), ex);
+            }
+        }
+    }
+}
+#endif
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Support/XmlSerializableWrapper.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Support/XmlSerializableWrapper.cs
new file mode 100644
index 0000000..ec2831a
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Support/XmlSerializableWrapper.cs
@@ -0,0 +1,114 @@
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+using System;
+using System.Runtime.Serialization;
+using System.Xml;
+using System.Xml.Serialization;
+
+namespace ServiceStack.ServiceModel.Support
+{
+    public sealed class XmlSerializerWrapper : XmlObjectSerializer
+    {
+        System.Xml.Serialization.XmlSerializer serializer;
+        string defaultNS;
+        readonly Type objectType;
+
+        public XmlSerializerWrapper(Type type)
+            : this(type, null, null)
+        {
+
+        }
+
+        public XmlSerializerWrapper(Type type, string name, string ns)
+        {
+            this.objectType = type;
+            if (!String.IsNullOrEmpty(ns))
+            {
+                this.defaultNS = ns;
+                this.serializer = new System.Xml.Serialization.XmlSerializer(type, ns);
+            }
+            else
+            {
+                this.defaultNS = GetNamespace(type);
+                this.serializer = new System.Xml.Serialization.XmlSerializer(type);
+            }
+        }
+
+        public override bool IsStartObject(XmlDictionaryReader reader)
+        {
+            throw new NotImplementedException();
+        }
+
+        public override object ReadObject(XmlDictionaryReader reader, bool verifyObjectName)
+        {
+            throw new NotImplementedException();
+        }
+        public override void WriteEndObject(XmlDictionaryWriter writer)
+        {
+            throw new NotImplementedException();
+        }
+
+        public override void WriteObjectContent(XmlDictionaryWriter writer, object graph)
+        {
+            throw new NotImplementedException();
+        }
+
+        public override void WriteStartObject(XmlDictionaryWriter writer, object graph)
+        {
+            throw new NotImplementedException();
+        }
+
+        public override void WriteObject(XmlDictionaryWriter writer, object graph)
+        {
+            this.serializer.Serialize(writer, graph);
+        }
+
+        public override object ReadObject(XmlDictionaryReader reader)
+        {
+            string readersNS;
+
+            readersNS = (String.IsNullOrEmpty(reader.NamespaceURI)) ? "" : reader.NamespaceURI;
+            if (String.Compare(this.defaultNS, readersNS) != 0)
+            {
+                this.serializer = new System.Xml.Serialization.XmlSerializer(this.objectType, readersNS);
+                this.defaultNS = readersNS;
+            }
+
+            return (this.serializer.Deserialize(reader));
+        }
+
+        /// <summary>
+        /// Gets the namespace from an attribute marked on the type's definition
+        /// </summary>
+        /// <param name="type"></param>
+        /// <returns>Namespace of type</returns>
+        public static string GetNamespace(Type type)
+        {
+            Attribute[] attrs = (Attribute[])type.GetCustomAttributes(typeof(DataContractAttribute), true);
+            if (attrs.Length > 0)
+            {
+                DataContractAttribute dcAttr = (DataContractAttribute)attrs[0];
+                return dcAttr.Namespace;
+            }
+            attrs = (Attribute[])type.GetCustomAttributes(typeof(XmlRootAttribute), true);
+            if (attrs.Length > 0)
+            {
+                XmlRootAttribute xmlAttr = (XmlRootAttribute)attrs[0];
+                return xmlAttr.Namespace;
+            }
+            attrs = (Attribute[])type.GetCustomAttributes(typeof(XmlTypeAttribute), true);
+            if (attrs.Length > 0)
+            {
+                XmlTypeAttribute xmlAttr = (XmlTypeAttribute)attrs[0];
+                return xmlAttr.Namespace;
+            }
+            attrs = (Attribute[])type.GetCustomAttributes(typeof(XmlElementAttribute), true);
+            if (attrs.Length > 0)
+            {
+                XmlElementAttribute xmlAttr = (XmlElementAttribute)attrs[0];
+                return xmlAttr.Namespace;
+            }
+            return null;
+        }
+    }
+}
+#endif
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Validation/ValidationError.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Validation/ValidationError.cs
new file mode 100644
index 0000000..d6b1caf
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Validation/ValidationError.cs
@@ -0,0 +1,151 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using ServiceStack.Common.Extensions;
+
+namespace ServiceStack.Validation
+{
+    /// <summary>
+    /// The exception which is thrown when a validation error occured.
+    /// This validation is serialized in a extra clean and human-readable way by ServiceStack.
+    /// </summary>
+    public class ValidationError : ArgumentException
+    {
+        private readonly string errorCode;
+        public string ErrorMessage { get; private set; }
+
+        public ValidationError(string errorCode)
+            : this(errorCode, errorCode.SplitCamelCase())
+        {
+        }
+
+        public ValidationError(ValidationErrorResult validationResult)
+            : base(validationResult.ErrorMessage)
+        {
+            this.errorCode = validationResult.ErrorCode;
+            this.ErrorMessage = validationResult.ErrorMessage;
+            this.Violations = validationResult.Errors;
+        }
+
+        public ValidationError(ValidationErrorField validationError)
+            : this(validationError.ErrorCode, validationError.ErrorMessage)
+        {
+            this.Violations.Add(validationError);
+        }
+
+        public ValidationError(string errorCode, string errorMessage)
+            : base(errorMessage)
+        {
+            this.errorCode = errorCode;
+            this.ErrorMessage = errorMessage;
+            this.Violations = new List<ValidationErrorField>();
+        }
+
+        /// <summary>
+        /// Returns the first error code
+        /// </summary>
+        /// <value>The error code.</value>
+        public string ErrorCode
+        {
+            get
+            {
+                return this.errorCode;
+            }
+        }
+
+        public override string Message
+        {
+            get
+            {
+                //If there is only 1 validation error than we just show the error message
+                if (this.Violations.Count == 0)
+                    return this.ErrorMessage;
+
+                if (this.Violations.Count == 1)
+                    return this.ErrorMessage ?? this.Violations[0].ErrorMessage;
+
+                var sb = new StringBuilder(this.ErrorMessage).AppendLine();
+                foreach (var error in this.Violations)
+                {
+                    if (!string.IsNullOrEmpty(error.ErrorMessage))
+                    {
+                        var fieldLabel = error.FieldName != null ? string.Format(" [{0}]", error.FieldName) : null;
+                        sb.AppendFormat("\n  - {0}{1}", error.ErrorMessage, fieldLabel);
+                    }
+                    else
+                    {
+                        var fieldLabel = error.FieldName != null ? ": " + error.FieldName : null;
+                        sb.AppendFormat("\n  - {0}{1}", error.ErrorCode, fieldLabel);
+                    }
+                }
+                return sb.ToString();
+            }
+        }
+
+        public IList<ValidationErrorField> Violations { get; private set; }
+
+        /// <summary>
+        /// Used if we need to serialize this exception to XML
+        /// </summary>
+        /// <returns></returns>
+        public string ToXml()
+        {
+            var sb = new StringBuilder();
+            sb.Append("<ValidationException>");
+            foreach (ValidationErrorField error in this.Violations)
+            {
+                sb.Append("<ValidationError>")
+                    .AppendFormat("<Code>{0}</Code>", error.ErrorCode)
+                    .AppendFormat("<Field>{0}</Field>", error.FieldName)
+                    .AppendFormat("<Message>{0}</Message>", error.ErrorMessage)
+                    .Append("</ValidationError>");
+            }
+            sb.Append("</ValidationException>");
+            return sb.ToString();
+        }
+
+        public static ValidationError CreateException(Enum errorCode)
+        {
+            return new ValidationError(errorCode.ToString());
+        }
+
+        public static ValidationError CreateException(Enum errorCode, string errorMessage)
+        {
+            return new ValidationError(errorCode.ToString(), errorMessage);
+        }
+
+        public static ValidationError CreateException(Enum errorCode, string errorMessage, string fieldName)
+        {
+            return CreateException(errorCode.ToString(), errorMessage, fieldName);
+        }
+
+        public static ValidationError CreateException(string errorCode)
+        {
+            return new ValidationError(errorCode);
+        }
+
+        public static ValidationError CreateException(string errorCode, string errorMessage)
+        {
+            return new ValidationError(errorCode, errorMessage);
+        }
+
+        public static ValidationError CreateException(string errorCode, string errorMessage, string fieldName)
+        {
+            var error = new ValidationErrorField(errorCode, fieldName, errorMessage);
+            return new ValidationError(new ValidationErrorResult(new List<ValidationErrorField> { error }));
+        }
+
+        public static ValidationError CreateException(ValidationErrorField error)
+        {
+            return new ValidationError(error);
+        }
+
+        public static void ThrowIfNotValid(ValidationErrorResult validationResult)
+        {
+            if (!validationResult.IsValid)
+            {
+                throw new ValidationError(validationResult);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Validation/ValidationErrorField.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Validation/ValidationErrorField.cs
new file mode 100644
index 0000000..c329c73
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Validation/ValidationErrorField.cs
@@ -0,0 +1,34 @@
+using System;
+using ServiceStack.Common.Extensions;
+
+namespace ServiceStack.Validation
+{
+    public class ValidationErrorField
+    {
+        public ValidationErrorField(string errorCode, string fieldName) 
+            : this(errorCode, fieldName, null) {}
+
+        public ValidationErrorField(string errorCode)
+            : this(errorCode, null, null) { }
+
+        public ValidationErrorField(Enum errorCode)
+            : this(errorCode.ToString(), null, null) { }
+
+        public ValidationErrorField(Enum errorCode, string fieldName)
+            : this(errorCode.ToString(), fieldName, null) { }
+
+        public ValidationErrorField(Enum errorCode, string fieldName, string errorMessage)
+            : this(errorCode.ToString(), fieldName, errorMessage) { }
+
+        public ValidationErrorField(string errorCode, string fieldName, string errorMessage)
+        {
+            this.ErrorCode = errorCode;
+            this.FieldName = fieldName;
+            this.ErrorMessage = errorMessage ?? errorCode.ToEnglish();
+        }
+
+        public string ErrorCode { get; set; }
+        public string ErrorMessage { get; set; }
+        public string FieldName { get; set; }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Validation/ValidationErrorResult.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Validation/ValidationErrorResult.cs
new file mode 100644
index 0000000..a4c1905
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/Validation/ValidationErrorResult.cs
@@ -0,0 +1,128 @@
+using System;
+using System.Collections.Generic;
+using ServiceStack.Common.Extensions;
+
+namespace ServiceStack.Validation
+{
+    /// <summary>
+    /// Encapsulates a validation result.
+    /// </summary>
+    public class ValidationErrorResult
+    {
+        public static ValidationErrorResult Success
+        {
+            get
+            {
+                return new ValidationErrorResult();
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets the success code.
+        /// </summary>
+        /// <value>The success code.</value>
+        public string SuccessCode
+        {
+            get;
+            protected set;
+        }
+
+        /// <summary>
+        /// Gets or sets the error code.
+        /// </summary>
+        /// <value>The error code.</value>
+        public string ErrorCode
+        {
+            get;
+            set;
+        }
+
+        /// <summary>
+        /// Gets or sets the success message.
+        /// </summary>
+        /// <value>The success message.</value>
+        public string SuccessMessage { get; set; }
+
+        /// <summary>
+        /// Gets or sets the error message.
+        /// </summary>
+        /// <value>The error message.</value>
+        public string ErrorMessage { get; set; }
+
+        public virtual string Message
+        {
+            get
+            {
+                return Errors.Count > 0 ? ErrorMessage : SuccessMessage;
+            }
+        }
+
+
+        /// <summary>
+        /// The errors generated by the validation.
+        /// </summary>
+        public IList<ValidationErrorField> Errors
+        {
+            get;
+            protected set;
+        }
+
+        /// <summary>
+        /// Returns True if the validation was successful (errors list is empty).
+        /// </summary>
+        public virtual bool IsValid
+        {
+            get
+            {
+                return this.Errors.Count == 0;
+            }
+        }
+
+        /// <summary>
+        /// Constructs a new ValidationResult
+        /// </summary>
+        public ValidationErrorResult()
+            : this(new List<ValidationErrorField>())
+        {
+        }
+
+        /// <summary>
+        /// Constructs a new ValidationResult
+        /// </summary>
+        /// <param name="errors">A list of validation results</param>
+        public ValidationErrorResult(IList<ValidationErrorField> errors) : this(errors, null, null) { }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ValidationErrorResult"/> class.
+        /// </summary>
+        /// <param name="errors">The errors.</param>
+        /// <param name="successCode">The success code.</param>
+        /// <param name="errorCode">The error code.</param>
+        public ValidationErrorResult(IList<ValidationErrorField> errors, string successCode, string errorCode)
+        {
+            this.Errors = errors ?? new List<ValidationErrorField>();
+            if (successCode != null)
+            {
+                this.SuccessCode = successCode;
+                this.SuccessMessage = successCode.SplitCamelCase();
+            }
+            if (errorCode != null)
+            {
+                this.ErrorCode = errorCode;
+            }
+            else
+            {
+                if (this.Errors.Count > 0)
+                {
+                    this.ErrorCode = this.Errors[0].ErrorCode;
+                    this.ErrorMessage = this.Errors[0].ErrorMessage;
+                }
+            }
+            
+            if (this.ErrorMessage == null && this.ErrorCode != null)
+            {
+                this.ErrorMessage = this.ErrorCode.ToEnglish();
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/XLinqExtensions.cs b/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/XLinqExtensions.cs
new file mode 100644
index 0000000..9b2addc
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceModel/XLinqExtensions.cs
@@ -0,0 +1,298 @@
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+//
+// ServiceStack: Useful extensions to simplify parsing xml with XLinq
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2012 ServiceStack
+//
+// Licensed under the new BSD license.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Xml;
+using System.Xml.Linq;
+
+namespace ServiceStack.ServiceModel
+{
+    public static class XLinqExtensions
+    {
+        public static string GetString(this XElement el, string name)
+        {
+            return el == null ? null : GetElementValueOrDefault(el, name, x => x.Value);
+        }
+
+        public static string GetStringAttributeOrDefault(this XElement element, string name)
+        {
+            var attr = AnyAttribute(element, name);
+            return attr == null ? null : GetAttributeValueOrDefault(attr, name, x => x.Value);
+        }
+
+        public static bool GetBool(this XElement el, string name)
+        {
+            AssertElementHasValue(el, name);
+            return (bool)GetElement(el, name);
+        }
+
+        public static bool GetBoolOrDefault(this XElement el, string name)
+        {
+            return GetElementValueOrDefault(el, name, x => (bool)x);
+        }
+
+        public static bool? GetNullableBool(this XElement el, string name)
+        {
+            var childEl = GetElement(el, name);
+            return childEl == null || string.IsNullOrEmpty(childEl.Value) ? null : (bool?)childEl;
+        }
+
+        public static int GetInt(this XElement el, string name)
+        {
+            AssertElementHasValue(el, name);
+            return (int)GetElement(el, name);
+        }
+
+        public static int GetIntOrDefault(this XElement el, string name)
+        {
+            return GetElementValueOrDefault(el, name, x => (int)x);
+        }
+
+        public static int? GetNullableInt(this XElement el, string name)
+        {
+            var childEl = GetElement(el, name);
+            return childEl == null || string.IsNullOrEmpty(childEl.Value) ? null : (int?)childEl;
+        }
+
+        public static long GetLong(this XElement el, string name)
+        {
+            AssertElementHasValue(el, name);
+            return (long)GetElement(el, name);
+        }
+
+        public static long GetLongOrDefault(this XElement el, string name)
+        {
+            return GetElementValueOrDefault(el, name, x => (long)x);
+        }
+
+        public static long? GetNullableLong(this XElement el, string name)
+        {
+            var childEl = GetElement(el, name);
+            return childEl == null || string.IsNullOrEmpty(childEl.Value) ? null : (long?)childEl;
+        }
+
+        public static decimal GetDecimal(this XElement el, string name)
+        {
+            AssertElementHasValue(el, name);
+            return (decimal)GetElement(el, name);
+        }
+
+        public static decimal GetDecimalOrDefault(this XElement el, string name)
+        {
+            return GetElementValueOrDefault(el, name, x => (decimal)x);
+        }
+
+        public static decimal? GetNullableDecimal(this XElement el, string name)
+        {
+            var childEl = GetElement(el, name);
+            return childEl == null || string.IsNullOrEmpty(childEl.Value) ? null : (decimal?)childEl;
+        }
+
+        public static DateTime GetDateTime(this XElement el, string name)
+        {
+            AssertElementHasValue(el, name);
+            return (DateTime)GetElement(el, name);
+        }
+
+        public static DateTime GetDateTimeOrDefault(this XElement el, string name)
+        {
+            return GetElementValueOrDefault(el, name, x => (DateTime)x);
+        }
+
+        public static DateTime? GetNullableDateTime(this XElement el, string name)
+        {
+            var childEl = GetElement(el, name);
+            return childEl == null || string.IsNullOrEmpty(childEl.Value) ? null : (DateTime?)childEl;
+        }
+
+        public static TimeSpan GetTimeSpan(this XElement el, string name)
+        {
+            AssertElementHasValue(el, name);
+            return (TimeSpan)GetElement(el, name);
+        }
+
+        public static TimeSpan GetTimeSpanOrDefault(this XElement el, string name)
+        {
+            return GetElementValueOrDefault(el, name, x => (TimeSpan)x);
+        }
+
+        public static TimeSpan? GetNullableTimeSpan(this XElement el, string name)
+        {
+            var childEl = GetElement(el, name);
+            return childEl == null || string.IsNullOrEmpty(childEl.Value) ? null : (TimeSpan?)childEl;
+        }
+
+        public static Guid GetGuid(this XElement el, string name)
+        {
+            AssertElementHasValue(el, name);
+            return (Guid)GetElement(el, name);
+        }
+
+        public static Guid GetGuidOrDefault(this XElement el, string name)
+        {
+            return GetElementValueOrDefault(el, name, x => (Guid)x);
+        }
+
+        public static Guid? GetNullableGuid(this XElement el, string name)
+        {
+            var childEl = GetElement(el, name);
+            return childEl == null || string.IsNullOrEmpty(childEl.Value) ? null : (Guid?)childEl;
+        }
+
+        public static T GetElementValueOrDefault<T>(this XElement element, string name, Func<XElement, T> converter)
+        {
+            if (converter == null)
+            {
+                throw new ArgumentNullException("converter");
+            }
+            var el = GetElement(element, name);
+            return el == null || string.IsNullOrEmpty(el.Value) ? default(T) : converter(el);
+        }
+
+        public static XElement GetElement(this XElement element, string name)
+        {
+            if (element == null)
+            {
+                throw new ArgumentNullException("element");
+            }
+            if (name == null)
+            {
+                throw new ArgumentNullException("name");
+            }
+            return element.AnyElement(name);
+        }
+
+        public static T GetAttributeValueOrDefault<T>(this XAttribute attr, string name, Func<XAttribute, T> converter)
+        {
+            if (converter == null)
+            {
+                throw new ArgumentNullException("converter");
+            }
+            return attr == null || string.IsNullOrEmpty(attr.Value) ? default(T) : converter(attr);
+        }
+
+        public static void AssertExactlyOneResult(this XElement queryListItems, string referenceNumber, string formType)
+        {
+            int count = Convert.ToInt32(queryListItems.AnyAttribute("ItemCount").Value);
+            if (count == 0)
+                throw new InvalidOperationException(string.Format("There is no {0} for with a deal reference number {1}", formType, referenceNumber));
+            if (count > 1)
+                throw new InvalidOperationException(
+                    string.Format("There are more than one {0}s with deal reference number {1}", formType, referenceNumber));
+        }
+
+        public static void AssertElementHasValue(this XElement element, string name)
+        {
+            if (element == null)
+            {
+                throw new ArgumentNullException("element");
+            }
+            if (name == null)
+            {
+                throw new ArgumentNullException("name");
+            }
+            var childEl = element.AnyElement(name);
+            if (childEl == null || string.IsNullOrEmpty(childEl.Value))
+            {
+                throw new ArgumentNullException(name, string.Format("{0} is required", name));
+            }
+        }
+
+        public static List<string> GetValues(this IEnumerable<XElement> els)
+        {
+            var values = new List<string>();
+            foreach (var el in els)
+            {
+                values.Add(el.Value);
+            }
+            return values;
+        }
+
+        public static XAttribute AnyAttribute(this XElement element, string name)
+        {
+            if (element == null) return null;
+            foreach (var attribute in element.Attributes())
+            {
+                if (attribute.Name.LocalName == name)
+                {
+                    return attribute;
+                }
+            }
+            return null;
+        }
+
+        public static IEnumerable<XElement> AllElements(this XElement element, string name)
+        {
+            var els = new List<XElement>();
+            if (element == null) return els;
+            foreach (var node in element.Nodes())
+            {
+                if (node.NodeType != XmlNodeType.Element) continue;
+                var childEl = (XElement)node;
+                if (childEl.Name.LocalName == name)
+                {
+                    els.Add(childEl);
+                }
+            }
+            return els;
+        }
+
+        public static XElement AnyElement(this XElement element, string name)
+        {
+            if (element == null) return null;
+            foreach (var node in element.Nodes())
+            {
+                if (node.NodeType != XmlNodeType.Element) continue;
+                var childEl = (XElement)node;
+                if (childEl.Name.LocalName == name)
+                {
+                    return childEl;
+                }
+            }
+            return null;
+        }
+
+        public static XElement AnyElement(this IEnumerable<XElement> elements, string name)
+        {
+            foreach (var element in elements)
+            {
+                if (element.Name.LocalName == name)
+                {
+                    return element;
+                }
+            }
+            return null;
+        }
+
+        public static IEnumerable<XElement> AllElements(this IEnumerable<XElement> elements, string name)
+        {
+            var els = new List<XElement>();
+            foreach (var element in elements)
+            {
+                els.AddRange(AllElements(element, name));
+            }
+            return els;
+        }
+
+        public static XElement FirstElement(this XElement element)
+        {
+            if (element.FirstNode.NodeType == XmlNodeType.Element)
+            {
+                return (XElement)element.FirstNode;
+            }
+            return null;
+        }
+    }
+
+}
+#endif
diff --git a/lib/ServiceStack/src/ServiceStack.Common/ServiceStack.Common.csproj b/lib/ServiceStack/src/ServiceStack.Common/ServiceStack.Common.csproj
new file mode 100644
index 0000000..f84c837
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/ServiceStack.Common.csproj
@@ -0,0 +1,495 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{982416DB-C143-4028-A0C3-CF41892D18D3}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>ServiceStack.Common</RootNamespace>
+    <AssemblyName>ServiceStack.Common</AssemblyName>
+    <FileAlignment>512</FileAlignment>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation />
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+  </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>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>True</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <DocumentationFile>bin\Release\ServiceStack.Common.XML</DocumentationFile>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'STATIC_ONLY NO_EXPRESSIONS|AnyCPU' ">
+    <DebugSymbols>True</DebugSymbols>
+    <OutputPath>bin\MonoTouch\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Optimize>False</Optimize>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'MonoTouch|AnyCPU' ">
+    <DebugSymbols>True</DebugSymbols>
+    <OutputPath>bin\MonoTouch\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;MONOTOUCH</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Optimize>False</Optimize>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Runtime.Serialization" />
+    <Reference Include="System.ServiceModel" />
+    <Reference Include="System.ServiceModel.Web" />
+    <Reference Include="System.Web" />
+    <Reference Include="System.Xml" />
+    <Reference Include="System.Xml.Linq" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="ActionExecExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="AssertExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ByteArrayExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DictionaryExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DirectoryInfoExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DisposableExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="EnumerableExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="EnumExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ExecExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Expressions\DelegateFactory.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Extensions\ActionExecExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Extensions\AssertExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Extensions\ByteArrayExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Extensions\CollectionExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Extensions\DictionaryExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Extensions\EnumerableExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Extensions\IntExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Extensions\ITranslatorExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Extensions\ReflectionExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Extensions\StringExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="HostContext.cs" />
+    <Compile Include="IntExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="IPAddressExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Messaging\ClientFactory.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Messaging\IMessageHandler.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Messaging\IMessageHandlerDisposer.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Messaging\IMessageHandlerFactory.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Messaging\InMemoryMessageQueueClient.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Messaging\InMemoryTransientMessageFactory.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Messaging\InMemoryTransientMessageService.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Messaging\MessageExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Messaging\MessageHandler.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Messaging\MessageHandlerFactory.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Messaging\MessageQueueClientFactory.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Messaging\Rcon\Client.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Messaging\Rcon\Packet.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Messaging\Rcon\PacketCodec.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Messaging\Rcon\PacketProcessingClient.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Messaging\Rcon\Server.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Messaging\TransientMessageServiceBase.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Model.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ModelConfig.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Net30\ConcurrentDictionary.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Net30\ConcurrentQueue.cs" />
+    <Compile Include="Net30\ObjectPool.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Net30\SplitOrderedList.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Net30\Tuple.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="ReflectionExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Reflection\PropertyAccessor.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Reflection\StaticAccessors.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceClient.Web\AsyncServiceClient.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceClient.Web\AuthDtos.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceClient.Web\DictionaryExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceClient.Web\GenericProxy.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceClient.Web\HttpMethod.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceClient.Web\IDuplex.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceClient.Web\IDuplexCallback.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceClient.Web\IOneWay.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceClient.Web\ISyncReply.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceClient.Web\IWcfServiceClient.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceClient.Web\JsonRestClientAsync.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceClient.Web\JsonServiceClient.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceClient.Web\JsvRestClientAsync.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceClient.Web\JsvServiceClient.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceClient.Web\ServiceClientBase.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceClient.Web\Soap11ServiceClient.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceClient.Web\Soap12ServiceClient.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceClient.Web\WcfServiceClient.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceClient.Web\WebRequestExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceClient.Web\WebRequestUtils.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceClient.Web\WebServiceException.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceClient.Web\XLinqExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceClient.Web\XmlRestClientAsync.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceClient.Web\XmlServiceClient.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceModel\DictionaryExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceModel\Serialization\DataContractDeserializer.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceModel\Serialization\DataContractSerializer.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceModel\Serialization\JsonDataContractDeserializer.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceModel\Serialization\JsonDataContractSerializer.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceModel\Serialization\KeyValueDataContractDeserializer.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceModel\Serialization\StringMapTypeDeserializer.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceModel\Serialization\XmlSerializableDeserializer.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceModel\Serialization\XmlSerializableSerializer.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceModel\Support\XmlSerializableWrapper.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceModel\Validation\ValidationError.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceModel\Validation\ValidationErrorField.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceModel\Validation\ValidationErrorResult.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceModel\XLinqExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="StreamExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="StringExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Support\ActionExecHandler.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Support\AdapterBase.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Support\AssignmentDefinition.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Support\CommandExecsHandler.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Support\CommandResultsHandler.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Support\InMemoryLogFactory.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Support\LogicFacadeBase.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Support\NetDeflateProvider.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Support\NetGZipProvider.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Support\PropertyInvoker.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="TypeExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="UrnId.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Utils\AssertUtils.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Utils\CommandsUtils.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Utils\FuncUtils.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Utils\IdUtils.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Utils\PathUtils.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Utils\PerfUtils.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Utils\ReflectionUtils.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Web\CompressedFileResult.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Web\CompressedResult.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Web\CompressionTypes.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Web\ContentType.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Web\EndPoint.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Web\EndpointType.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Web\HttpError.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Web\HttpHeaders.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Web\HttpMethods.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Web\HttpResponseFilter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Web\HttpResponseStreamWrapper.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Web\HttpResult.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Web\HttpResultExtensions.cs" />
+    <Compile Include="Web\MimeTypes.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="RequestContextExtensions.cs" />
+    <Compile Include="Web\SerializationContext.cs">
+      <SubType>Code</SubType>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+      <Visible>False</Visible>
+      <ProductName>Windows Installer 3.1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="README.md" />
+  </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>
+  -->
+  <ItemGroup>
+    <ProjectReference Include="..\..\..\ServiceStack.Text\src\ServiceStack.Text\ServiceStack.Text.csproj">
+      <Project>{579B3FDB-CDAD-44E1-8417-885C38E49A0E}</Project>
+      <Name>ServiceStack.Text</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\ServiceStack.Interfaces\ServiceStack.Interfaces.csproj">
+      <Project>{42E1C8C0-A163-44CC-92B1-8F416F2C0B01}</Project>
+      <Name>ServiceStack.Interfaces</Name>
+    </ProjectReference>
+  </ItemGroup>
+</Project>
diff --git a/lib/ServiceStack/src/ServiceStack.Common/StreamExtensions.cs b/lib/ServiceStack/src/ServiceStack.Common/StreamExtensions.cs
new file mode 100644
index 0000000..aa9e3dc
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/StreamExtensions.cs
@@ -0,0 +1,100 @@
+#if !SILVERLIGHT && !XBOX
+using System;
+using System.IO;
+using System.Text;
+using ServiceStack.CacheAccess;
+using ServiceStack.Common.Support;
+using ServiceStack.Common.Web;
+using ServiceStack.Text;
+
+namespace ServiceStack.Common
+{
+    public static class StreamExtensions
+    {
+#if !MONOTOUCH
+        /// <summary>
+        /// Compresses the specified text using the default compression method: Deflate
+        /// </summary>
+        /// <param name="text">The text.</param>
+        /// <param name="compressionType">Type of the compression.</param>
+        /// <returns></returns>
+        public static byte[] Compress(this string text, string compressionType)
+        {
+            if (compressionType == CompressionTypes.Deflate)
+                return Deflate(text);
+
+            if (compressionType == CompressionTypes.GZip)
+                return GZip(text);
+
+            throw new NotSupportedException(compressionType);
+        }
+
+        public static IDeflateProvider DeflateProvider = new NetDeflateProvider();
+
+        public static IGZipProvider GZipProvider = new NetGZipProvider();
+
+        /// <summary>
+        /// Decompresses the specified gz buffer using the default compression method: Inflate
+        /// </summary>
+        /// <param name="gzBuffer">The gz buffer.</param>
+        /// <param name="compressionType">Type of the compression.</param>
+        /// <returns></returns>
+        public static string Decompress(this byte[] gzBuffer, string compressionType)
+        {
+            if (compressionType == CompressionTypes.Deflate)
+                return Inflate(gzBuffer);
+
+            if (compressionType == CompressionTypes.GZip)
+                return GUnzip(gzBuffer);
+
+            throw new NotSupportedException(compressionType);
+        }
+
+        public static byte[] Deflate(this string text)
+        {
+            return DeflateProvider.Deflate(text);
+        }
+
+        public static string Inflate(this byte[] gzBuffer)
+        {
+            return DeflateProvider.Inflate(gzBuffer);
+        }
+
+        public static byte[] GZip(this string text)
+        {
+            return GZipProvider.GZip(text);
+        }
+
+        public static string GUnzip(this byte[] gzBuffer)
+        {
+            return GZipProvider.GUnzip(gzBuffer);
+        }
+#endif
+
+        public static string ToUtf8String(this Stream stream)
+        {
+            if (stream == null) throw new ArgumentNullException("stream");
+
+            using (var reader = new StreamReader(stream, Encoding.UTF8))
+            {
+                return reader.ReadToEnd();
+            }
+        }
+
+        public static byte[] ToBytes(this Stream stream)
+        {
+            if (stream == null) throw new ArgumentNullException("stream");
+
+            return stream.ReadFully();
+        }
+
+        public static void Write(this Stream stream, string text)
+        {
+            var bytes = Encoding.ASCII.GetBytes(text);
+            stream.Write(bytes, 0, bytes.Length);
+        }
+
+    }
+
+}
+#endif
diff --git a/lib/ServiceStack/src/ServiceStack.Common/StringExtensions.cs b/lib/ServiceStack/src/ServiceStack.Common/StringExtensions.cs
new file mode 100644
index 0000000..37fdaeb
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/StringExtensions.cs
@@ -0,0 +1,192 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Text;
+using System.Text.RegularExpressions;
+using ServiceStack.Common.Utils;
+using ServiceStack.Text;
+using ServiceStack.Text.Common;
+
+namespace ServiceStack.Common
+{
+    public static class StringExtensions
+    {
+        static readonly Regex RegexSplitCamelCase = new Regex("([A-Z]|[0-9]+)", 
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+            RegexOptions.Compiled
+#else
+            RegexOptions.None
+#endif
+        );
+
+        public static T ToEnum<T>(this string value)
+        {
+            return (T)Enum.Parse(typeof(T), value, true);
+        }
+
+        public static T ToEnumOrDefault<T>(this string value, T defaultValue)
+        {
+            if (String.IsNullOrEmpty(value)) return defaultValue;
+            return (T)Enum.Parse(typeof(T), value, true);
+        }
+
+        public static string SplitCamelCase(this string value)
+        {
+            return RegexSplitCamelCase.Replace(value, " $1").TrimStart();
+        }
+
+        public static string ToEnglish(this string camelCase)
+        {
+            var ucWords = camelCase.SplitCamelCase().ToLower();
+            return ucWords[0].ToString(CultureInfo.InvariantCulture).ToUpper() + ucWords.Substring(1);
+        }
+
+        public static bool IsEmpty(this string value)
+        {
+            return String.IsNullOrEmpty(value);
+        }
+
+        public static bool IsNullOrEmpty(this string value)
+        {
+            return String.IsNullOrEmpty(value);
+        }
+
+        public static bool EqualsIgnoreCase(this string value, string other)
+        {
+            return String.Equals(value, other, StringComparison.CurrentCultureIgnoreCase);
+        }
+
+        public static string ReplaceFirst(this string haystack, string needle, string replacement)
+        {
+            var pos = haystack.IndexOf(needle);
+            if (pos < 0) return haystack;
+
+            return haystack.Substring(0, pos) + replacement + haystack.Substring(pos + needle.Length);
+        }
+
+        public static string ReplaceAll(this string haystack, string needle, string replacement)
+        {
+            int pos;
+            // Avoid a possible infinite loop
+            if (needle == replacement) return haystack;
+            while ((pos = haystack.IndexOf(needle)) > 0)
+            {
+                haystack = haystack.Substring(0, pos) 
+                    + replacement 
+                    + haystack.Substring(pos + needle.Length);
+            }
+            return haystack;
+        }
+
+        public static bool ContainsAny(this string text, params string[] testMatches)
+        {	
+            foreach (var testMatch in testMatches)
+            {
+                if (text.Contains(testMatch)) return true;
+            }
+            return false;
+        }
+
+        private static readonly Regex InvalidVarCharsRegEx = new Regex(@"[^A-Za-z0-9]",
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+            RegexOptions.Compiled
+#else
+ RegexOptions.None
+#endif
+        );
+
+        public static string SafeVarName(this string text)
+        {
+            if (String.IsNullOrEmpty(text)) return null;
+            return InvalidVarCharsRegEx.Replace(text, "_");
+        }
+
+        public static string Join(this List<string> items)
+        {
+            return String.Join(JsWriter.ItemSeperatorString, items.ToArray());
+        }
+
+        public static string Join(this List<string> items, string delimeter)
+        {
+            return String.Join(delimeter, items.ToArray());
+        }
+
+        public static string CombineWith(this string path, params string[] thesePaths)
+        {
+            if (thesePaths.Length == 1 && thesePaths[0] == null) return path;
+            return PathUtils.CombinePaths(new StringBuilder(path.TrimEnd('/','\\')), thesePaths);
+        }
+
+        public static string ToParentPath(this string path)
+        {
+            var pos = path.LastIndexOf('/');
+            if (pos == -1) return "/";
+
+            var parentPath = path.Substring(0, pos);
+            return parentPath;
+        }
+
+        public static string RemoveCharFlags(this string text, bool[] charFlags)
+        {
+            if (text == null) return null;
+
+            var copy = text.ToCharArray();
+            var nonWsPos = 0;
+
+            for (var i = 0; i < text.Length; i++)
+            {
+                var @char = text[i];
+                if (@char < charFlags.Length && charFlags[@char]) continue;
+                copy[nonWsPos++] = @char;
+            }
+
+            return new String(copy, 0, nonWsPos);
+        }
+
+        public static string ToNullIfEmpty(this string text)
+        {
+            return String.IsNullOrEmpty(text) ? null : text;
+        }
+
+
+        private static char[] SystemTypeChars = new[] { '<', '>', '+' };
+
+        public static bool IsUserType(this Type type)
+        {
+            return type.IsClass
+                && type.Namespace != null
+                && !type.Namespace.StartsWith("System.")
+                && type.Name.IndexOfAny(SystemTypeChars) == -1;
+        }
+
+        public static bool IsInt(this string text)
+        {
+            if (string.IsNullOrEmpty(text)) return false;
+            int ret;
+            return int.TryParse(text, out ret);
+        }
+
+        public static int ToInt(this string text)
+        {
+            return int.Parse(text);
+        }
+
+        public static int ToInt(this string text, int defaultValue)
+        {
+            int ret;
+            return int.TryParse(text, out ret) ? ret : defaultValue;
+        }
+
+        public static long ToInt64(this string text)
+        {
+            return long.Parse(text);
+        }
+
+        public static long ToInt64(this string text, long defaultValue)
+        {
+            long ret;
+            return long.TryParse(text, out ret) ? ret : defaultValue;
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Support/ActionExecHandler.cs b/lib/ServiceStack/src/ServiceStack.Common/Support/ActionExecHandler.cs
new file mode 100644
index 0000000..61c4171
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Support/ActionExecHandler.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Threading;
+using ServiceStack.DesignPatterns.Command;
+
+namespace ServiceStack.Common.Support
+{
+    public class ActionExecHandler : ICommandExec
+    {
+        private readonly Action action;
+        private readonly AutoResetEvent waitHandle;
+
+        public ActionExecHandler(Action action, AutoResetEvent waitHandle)
+        {
+            this.action = action;
+            this.waitHandle = waitHandle;
+        }
+
+        public bool Execute()
+        {
+            action();
+            waitHandle.Set();
+            return true;
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Support/AdapterBase.cs b/lib/ServiceStack/src/ServiceStack.Common/Support/AdapterBase.cs
new file mode 100644
index 0000000..0b3472f
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Support/AdapterBase.cs
@@ -0,0 +1,58 @@
+using System;
+using ServiceStack.Logging;
+
+namespace ServiceStack.Common.Support
+{
+    /// <summary>
+    /// Common functionality when creating adapters
+    /// </summary>
+    public abstract class AdapterBase
+    {
+        protected abstract ILog Log { get; }
+
+        /// <summary>
+        /// Executes the specified expression. 
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="action">The action.</param>
+        /// <returns></returns>
+        protected T Execute<T>(Func<T> action)
+        {
+            DateTime before = DateTime.Now;
+            this.Log.DebugFormat("Executing action '{0}'", action.Method.Name);
+            try
+            {
+                T result = action();
+                TimeSpan timeTaken = DateTime.Now - before;
+                this.Log.DebugFormat("Action '{0}' executed. Took {1} ms.", action.Method.Name, timeTaken.TotalMilliseconds);
+                return result;
+            }
+            catch (Exception ex)
+            {
+                this.Log.ErrorFormat("There was an error executing Action '{0}'. Message: {1}", action.Method.Name, ex.Message);
+                throw;
+            }
+        }
+
+        /// <summary>
+        /// Executes the specified action (for void methods).
+        /// </summary>
+        /// <param name="action">The action.</param>
+        protected void Execute(Action action)
+        {
+            DateTime before = DateTime.Now;
+            this.Log.DebugFormat("Executing action '{0}'", action.Method.Name);
+            try
+            {
+                action();
+                TimeSpan timeTaken = DateTime.Now - before;
+                this.Log.DebugFormat("Action '{0}' executed. Took {1} ms.", action.Method.Name, timeTaken.TotalMilliseconds);
+            }
+            catch (Exception ex)
+            {
+                this.Log.ErrorFormat("There was an error executing Action '{0}'. Message: {1}", action.Method.Name, ex.Message);
+                throw;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Support/AssignmentDefinition.cs b/lib/ServiceStack/src/ServiceStack.Common/Support/AssignmentDefinition.cs
new file mode 100644
index 0000000..300fbdb
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Support/AssignmentDefinition.cs
@@ -0,0 +1,147 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Reflection;
+using ServiceStack.Common.Utils;
+using ServiceStack.Logging;
+using ServiceStack.Net30.Collections.Concurrent;
+using ServiceStack.Text;
+
+namespace ServiceStack.Common.Support
+{
+    public class AssignmentDefinition
+    {
+        private static readonly ILog Log = LogManager.GetLogger(typeof(AssignmentDefinition));
+
+        private ConcurrentDictionary<string, PropertySetterDelegate> PropertySetters = 
+            new ConcurrentDictionary<string, PropertySetterDelegate>();
+
+        private ConcurrentDictionary<string, PropertyGetterDelegate> PropertyGetters = 
+            new ConcurrentDictionary<string, PropertyGetterDelegate>();
+
+        public AssignmentDefinition()
+        {
+            this.PropertyInfoMap = new Dictionary<PropertyInfo, PropertyInfo>();
+            this.FieldInfoMap = new Dictionary<FieldInfo, FieldInfo>();
+        }
+
+        public Type FromType { get; set; }
+        public Type ToType { get; set; }
+
+        //from => to
+        public Dictionary<PropertyInfo, PropertyInfo> PropertyInfoMap { get; set; }
+        public Dictionary<FieldInfo, FieldInfo> FieldInfoMap { get; set; }
+
+        public void AddMatch(PropertyInfo fromPropertyInfo, PropertyInfo toPropertyInfo)
+        {
+            this.PropertyInfoMap[fromPropertyInfo] = toPropertyInfo;
+        }
+
+        public void AddMatch(FieldInfo fromFieldInfo, FieldInfo toFieldInfo)
+        {
+            this.FieldInfoMap[fromFieldInfo] = toFieldInfo;
+        }
+
+        public void PopulateFromPropertiesWithAttribute(object to, object from, Type attributeType)
+        {
+            var hasAttributePredicate = (Func<PropertyInfo, bool>)
+                (x => x.GetCustomAttributes(attributeType, true).Length > 0);
+
+            Populate(to, from, hasAttributePredicate, null);
+        }
+
+        public void PopulateWithNonDefaultValues(object to, object from)
+        {
+            var nonDefaultPredicate = (Func<object, bool>) (x => 
+                    x != null && !Equals( x, ReflectionUtils.GetDefaultValue(x.GetType()) )
+                );
+    
+            Populate(to, from, null, nonDefaultPredicate);
+        }
+
+        public void Populate(object to, object from)
+        {
+            Populate(to, from, null, null);
+        }
+
+        public void Populate(object to, object from,
+            Func<PropertyInfo, bool> propertyInfoPredicate,
+            Func<object, bool> valuePredicate)
+        {
+            foreach (var propertyEntry in PropertyInfoMap)
+            {
+                var fromPropertyInfo = propertyEntry.Key;
+                var toPropertyInfo = propertyEntry.Value;
+
+                if (propertyInfoPredicate != null)
+                {
+                    if (!propertyInfoPredicate(fromPropertyInfo)) continue;
+                }
+
+                try
+                {
+                    var getterFn = PropertyGetters.GetOrAdd(fromPropertyInfo.Name,
+                        fromPropertyInfo.GetPropertyGetterFn());
+                    var fromValue = getterFn(from);
+
+                    if (valuePredicate != null)
+                    {
+                        if (!valuePredicate(fromValue)) continue;
+                    }
+
+                    if (fromPropertyInfo.PropertyType != toPropertyInfo.PropertyType)
+                    {
+                        if (fromPropertyInfo.PropertyType == typeof(string))
+                        {
+                            fromValue = TypeSerializer.DeserializeFromString((string)fromValue,
+                                toPropertyInfo.PropertyType);
+                        }
+                        else if (toPropertyInfo.PropertyType == typeof(string))
+                        {
+                            fromValue = TypeSerializer.SerializeToString(fromValue);
+                        }
+                        else
+                        {
+                            var listResult = TranslateListWithElements.TryTranslateToGenericICollection(
+                                fromPropertyInfo.PropertyType, toPropertyInfo.PropertyType, fromValue);
+
+                            if (listResult != null)
+                            {
+                                fromValue = listResult;
+                            }
+                        }
+                    }
+
+                    var setterFn = PropertySetters.GetOrAdd(toPropertyInfo.Name,
+                        toPropertyInfo.GetPropertySetterFn());
+
+                    setterFn(to, fromValue);
+                }
+                catch (Exception ex)
+                {
+                    Log.Warn(string.Format("Error trying to set properties {0}.{1} > {2}.{3}",
+                        FromType.FullName, fromPropertyInfo.Name,
+                        ToType.FullName, toPropertyInfo.Name), ex);
+                }
+            }
+
+            foreach (var fieldEntry in FieldInfoMap)
+            {
+                var fromFieldInfo = fieldEntry.Key;
+                var toFieldInfo = fieldEntry.Value;
+
+                try
+                {
+                    var fromValue = fromFieldInfo.GetValue(from);
+                    toFieldInfo.SetValue(to, fromValue);
+                }
+                catch (Exception ex)
+                {
+                    Log.Warn(string.Format("Error trying to set fields {0}.{1} > {2}.{3}",
+                        FromType.FullName, fromFieldInfo.Name,
+                        ToType.FullName, toFieldInfo.Name), ex);
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Support/CommandExecsHandler.cs b/lib/ServiceStack/src/ServiceStack.Common/Support/CommandExecsHandler.cs
new file mode 100644
index 0000000..c52fb58
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Support/CommandExecsHandler.cs
@@ -0,0 +1,24 @@
+using System.Threading;
+using ServiceStack.DesignPatterns.Command;
+
+namespace ServiceStack.Common.Support
+{
+    public class CommandExecsHandler : ICommandExec
+    {
+        private readonly ICommandExec command;
+        private readonly AutoResetEvent waitHandle;
+
+        public CommandExecsHandler(ICommandExec command, AutoResetEvent waitHandle)
+        {
+            this.command = command;
+            this.waitHandle = waitHandle;
+        }
+
+        public bool Execute()
+        {
+            command.Execute();
+            waitHandle.Set();
+            return true;
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Support/CommandResultsHandler.cs b/lib/ServiceStack/src/ServiceStack.Common/Support/CommandResultsHandler.cs
new file mode 100644
index 0000000..200bdb3
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Support/CommandResultsHandler.cs
@@ -0,0 +1,27 @@
+using System.Collections.Generic;
+using System.Threading;
+using ServiceStack.DesignPatterns.Command;
+
+namespace ServiceStack.Common.Support
+{
+    public class CommandResultsHandler<T> : ICommandExec
+    {
+        private readonly List<T> results;
+        private readonly ICommandList<T> command;
+        private readonly AutoResetEvent waitHandle;
+
+        public CommandResultsHandler(List<T> results, ICommandList<T> command, AutoResetEvent waitHandle)
+        {
+            this.results = results;
+            this.command = command;
+            this.waitHandle = waitHandle;
+        }
+
+        public bool Execute()
+        {
+            results.AddRange(command.Execute());
+            waitHandle.Set();
+            return true;
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Support/InMemoryLogFactory.cs b/lib/ServiceStack/src/ServiceStack.Common/Support/InMemoryLogFactory.cs
new file mode 100644
index 0000000..21d8c40
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Support/InMemoryLogFactory.cs
@@ -0,0 +1,191 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using ServiceStack.Logging;
+
+namespace ServiceStack.Common.Support
+{
+    /// <summary>
+    /// Note: InMemoryLog keeps all logs in memory, so don't use it long running exceptions
+    /// 
+    /// Returns a thread-safe InMemoryLog which you can use while *TESTING*
+    /// to provide a detailed analysis of your logs.
+    /// </summary>
+    public class InMemoryLogFactory
+        : ILogFactory
+    {
+        public ILog GetLogger(Type type)
+        {
+            return new InMemoryLog(type.Name);
+        }
+
+        public ILog GetLogger(string typeName)
+        {
+            return new InMemoryLog(typeName);
+        }
+    }
+
+    public class InMemoryLog
+        : ILog
+    {
+        private readonly object syncLock = new object();
+        public string LoggerName { get; private set; }
+        public StringBuilder CombinedLog { get; private set; }
+        public List<string> DebugEntries { get; set; }
+        public List<Exception> DebugExceptions { get; set; }
+        public List<string> InfoEntries { get; set; }
+        public List<Exception> InfoExceptions { get; set; }
+        public List<string> WarnEntries { get; set; }
+        public List<Exception> WarnExceptions { get; set; }
+        public List<string> ErrorEntries { get; set; }
+        public List<Exception> ErrorExceptions { get; set; }
+        public List<string> FatalEntries { get; set; }
+        public List<Exception> FatalExceptions { get; set; }
+
+        public InMemoryLog(string loggerName)
+        {
+            this.LoggerName = loggerName;
+            this.CombinedLog = new StringBuilder();
+
+            this.DebugEntries = new List<string>();
+            this.DebugExceptions = new List<Exception>();
+            this.InfoEntries = new List<string>();
+            this.InfoExceptions = new List<Exception>();
+            this.WarnEntries = new List<string>();
+            this.WarnExceptions = new List<Exception>();
+            this.ErrorEntries = new List<string>();
+            this.ErrorExceptions = new List<Exception>();
+            this.FatalEntries = new List<string>();
+            this.FatalExceptions = new List<Exception>();
+        }
+
+        public bool HasExceptions
+        {
+            get
+            {
+                return this.DebugExceptions.Count > 0
+                       || this.InfoExceptions.Count > 0
+                       || this.WarnExceptions.Count > 0
+                       || this.ErrorExceptions.Count > 0
+                       || this.FatalExceptions.Count > 0;
+            }
+        }
+
+        private void AppendToLog(ICollection<string> logEntries, string format, params object[] args)
+        {
+            if (format == null) return;
+            AppendToLog(logEntries, string.Format(format, args));
+        }
+
+        private void AppendToLog(ICollection<string> logEntries, object message)
+        {
+            if (message == null) return;
+            AppendToLog(logEntries, message.ToString());
+        }
+
+        private void AppendToLog(
+            ICollection<string> logEntries, 
+            ICollection<Exception> logExceptions, 
+            object message, Exception ex)
+        {
+            if (ex != null)
+            {
+                lock (syncLock)
+                {
+                    logExceptions.Add(ex);
+                }
+            }
+            if (message == null) return;
+            AppendToLog(logEntries, message.ToString());
+        }
+
+        private void AppendToLog(ICollection<string> logEntries, string message)
+        {
+            lock (this)
+            {
+                logEntries.Add(message);
+                CombinedLog.AppendLine(message);
+            }
+        }
+
+        public void Debug(object message)
+        {
+            AppendToLog(DebugEntries, message);
+        }
+
+        public void Debug(object message, Exception exception)
+        {
+            AppendToLog(DebugEntries, DebugExceptions, message, exception);
+        }
+
+        public void DebugFormat(string format, params object[] args)
+        {
+            AppendToLog(DebugEntries, format, args);
+        }
+
+        public void Error(object message)
+        {
+            AppendToLog(ErrorEntries, message);
+        }
+
+        public void Error(object message, Exception exception)
+        {
+            AppendToLog(ErrorEntries, ErrorExceptions, message, exception);
+        }
+
+        public void ErrorFormat(string format, params object[] args)
+        {
+            AppendToLog(ErrorEntries, format, args);
+        }
+
+        public void Fatal(object message)
+        {
+            AppendToLog(FatalEntries, message);
+        }
+
+        public void Fatal(object message, Exception exception)
+        {
+            AppendToLog(FatalEntries, FatalExceptions, message, exception);
+        }
+
+        public void FatalFormat(string format, params object[] args)
+        {
+            AppendToLog(FatalEntries, format, args);
+        }
+
+        public void Info(object message)
+        {
+            AppendToLog(InfoEntries, message);
+        }
+
+        public void Info(object message, Exception exception)
+        {
+            AppendToLog(InfoEntries, InfoExceptions, message, exception);
+        }
+
+        public void InfoFormat(string format, params object[] args)
+        {
+            AppendToLog(InfoEntries, format, args);
+        }
+
+        public void Warn(object message)
+        {
+            AppendToLog(WarnEntries, message);
+        }
+
+        public void Warn(object message, Exception exception)
+        {
+            AppendToLog(WarnEntries, WarnExceptions, message, exception);
+        }
+
+        public void WarnFormat(string format, params object[] args)
+        {
+            AppendToLog(WarnEntries, format, args);
+        }
+
+        public bool IsDebugEnabled
+        {
+            get { return true; }
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Support/LogicFacadeBase.cs b/lib/ServiceStack/src/ServiceStack.Common/Support/LogicFacadeBase.cs
new file mode 100644
index 0000000..d86dfe9
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Support/LogicFacadeBase.cs
@@ -0,0 +1,143 @@
+using System;
+using System.Collections.Generic;
+using ServiceStack.DesignPatterns.Command;
+using ServiceStack.Logging;
+using ServiceStack.LogicFacade;
+
+namespace ServiceStack.Common.Support
+{
+    public abstract class LogicFacadeBase : ILogicFacade
+    {
+        private readonly ILog log = LogManager.GetLogger(typeof(LogicFacadeBase));
+
+        internal class InitialisationContext : IInitContext
+        {
+            private readonly LogicFacadeBase logicFacade;
+
+            /// <summary>
+            /// Gets or sets the object that has been initialized only.
+            /// </summary>
+            public object InitialisedObject
+            {
+                get;
+                set;
+            }
+
+            /// <summary>
+            /// Determines whether this context is initialise only or not
+            /// </summary>
+            internal readonly InitOptions initOptions;
+
+            /// <summary>
+            /// Constructs a new InitialiseOnlyContext
+            /// </summary>
+            internal InitialisationContext(LogicFacadeBase logicFacade, InitOptions options)
+            {
+                this.logicFacade = logicFacade;
+                this.initOptions = options;
+            }
+
+            /// <summary>
+            /// Call to remove this current context and reveal the previous context (if any).
+            /// </summary>
+            public virtual void Dispose()
+            {
+                this.logicFacade.contexts.Pop();
+            }
+        }
+
+        /// <summary>
+        /// Gets the current context (or null if none).
+        /// </summary>
+        private InitialisationContext CurrentContext
+        {
+            get
+            {
+                //TODO: check if '|| this.contexts.Count == 0)' is intended as it was throwing an exception
+                if (this.contexts == null || this.contexts.Count == 0)
+                {
+                    return null;
+                }
+
+                return this.contexts.Peek();
+            }
+        }
+
+        [ThreadStatic]
+        internal Stack<InitialisationContext> contexts;
+
+        /// <summary>
+        /// Checks if the current context is set to "initialize only".
+        /// </summary>
+        public bool IsCurrentlyInitializeOnly
+        {
+            get
+            {
+                return this.CurrentContext != null
+                       && ((int)(this.CurrentContext.initOptions & InitOptions.InitialiseOnly) != 0);
+            }
+        }
+
+        public IInitContext AcquireInitContext(InitOptions initOptions)
+        {
+            if (this.contexts == null)
+            {
+                this.contexts = new Stack<InitialisationContext>();
+            }
+
+            var context = new InitialisationContext(this, initOptions);
+
+            this.contexts.Push(context);
+
+            return context;
+        }
+
+        /// <summary>
+        /// Executes the specified action.
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="action">The action.</param>
+        /// <returns></returns>
+        protected T Execute<T>(ICommand<T> action)
+        {
+            try
+            {
+                DateTime before = DateTime.Now;
+
+                this.log.DebugFormat("Executing action '{0}'", action.GetType().Name);
+
+                Init(action);
+
+                if (this.CurrentContext != null)
+                {
+                    this.CurrentContext.InitialisedObject = action;
+                }
+
+                if (this.IsCurrentlyInitializeOnly)
+                {
+                    this.log.DebugFormat("Action '{0}' not executed (InitializedOnlyContext).", action.GetType().Name);
+                    return default(T);
+                }
+                else
+                {
+                    T result = action.Execute();
+
+                    TimeSpan timeTaken = DateTime.Now - before;
+                    this.log.DebugFormat("Action '{0}' executed. Took {1} ms.", action.GetType().Name, timeTaken.TotalMilliseconds);
+
+                    return result;
+                }
+
+            }
+            catch (Exception ex)
+            {
+                log.ErrorFormat("Error executing action", ex);
+                throw;
+            }
+        }
+
+        protected abstract void Init<T>(ICommand<T> action);
+
+        public virtual void Dispose() { }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Support/NetDeflateProvider.cs b/lib/ServiceStack/src/ServiceStack.Common/Support/NetDeflateProvider.cs
new file mode 100644
index 0000000..3db1d1e
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Support/NetDeflateProvider.cs
@@ -0,0 +1,38 @@
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+using System;
+using System.IO;
+using System.IO.Compression;
+using System.Text;
+using ServiceStack.CacheAccess;
+using ServiceStack.Text;
+
+namespace ServiceStack.Common.Support
+{
+    public class NetDeflateProvider : IDeflateProvider
+    {
+        public byte[] Deflate(string text)
+        {
+            var buffer = Encoding.UTF8.GetBytes(text);
+            using(var ms = new MemoryStream())
+            using (var zipStream = new DeflateStream(ms, CompressionMode.Compress))
+            {
+                zipStream.Write(buffer, 0, buffer.Length);
+                zipStream.Close();
+
+                return ms.ToArray();
+            }
+        }
+
+        public string Inflate(byte[] gzBuffer)
+        {
+            using (var compressedStream = new MemoryStream(gzBuffer))
+            using (var zipStream = new DeflateStream(compressedStream, CompressionMode.Decompress))
+            {
+                var utf8Bytes = zipStream.ReadFully();
+                return Encoding.UTF8.GetString(utf8Bytes);
+            }
+        }
+
+    }
+}
+#endif
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Support/NetGZipProvider.cs b/lib/ServiceStack/src/ServiceStack.Common/Support/NetGZipProvider.cs
new file mode 100644
index 0000000..80dfb5a
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Support/NetGZipProvider.cs
@@ -0,0 +1,37 @@
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+using System;
+using System.IO;
+using System.IO.Compression;
+using System.Text;
+using ServiceStack.CacheAccess;
+using ServiceStack.Text;
+
+namespace ServiceStack.Common.Support
+{
+    public class NetGZipProvider : IGZipProvider
+    {
+        public byte[] GZip(string text)
+        {
+            var buffer = Encoding.UTF8.GetBytes(text);
+            using (var ms = new MemoryStream())
+            using (var zipStream = new GZipStream(ms, CompressionMode.Compress))
+            {
+                zipStream.Write(buffer, 0, buffer.Length);
+                zipStream.Close();
+
+                return ms.ToArray();
+            }
+        }
+        
+        public string GUnzip(byte[] gzBuffer)
+        {
+            using (var compressedStream = new MemoryStream(gzBuffer))
+            using (var zipStream = new GZipStream(compressedStream, CompressionMode.Decompress))
+            {
+                var utf8Bytes = zipStream.ReadFully();
+                return Encoding.UTF8.GetString(utf8Bytes);
+            }
+        }
+    }
+}
+#endif
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Support/PropertyInvoker.cs b/lib/ServiceStack/src/ServiceStack.Common/Support/PropertyInvoker.cs
new file mode 100644
index 0000000..17256f5
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Support/PropertyInvoker.cs
@@ -0,0 +1,69 @@
+using System;
+using System.Linq.Expressions;
+using System.Reflection;
+
+namespace ServiceStack.Common.Support
+{
+    public delegate void PropertySetterDelegate(object instance, object value);
+    public delegate object PropertyGetterDelegate(object instance);
+
+    public static class PropertyInvoker
+    {
+        public static PropertySetterDelegate GetPropertySetterFn(this PropertyInfo propertyInfo)
+        {
+            var propertySetMethod = propertyInfo.GetSetMethod();
+            if (propertySetMethod == null) return null;
+
+#if MONOTOUCH || SILVERLIGHT || XBOX
+            return (o, convertedValue) =>
+            {
+                propertySetMethod.Invoke(o, new[] { convertedValue });
+                return;
+            };
+#else
+            var instance = Expression.Parameter(typeof(object), "i");
+            var argument = Expression.Parameter(typeof(object), "a");
+
+            var instanceParam = Expression.Convert(instance, propertyInfo.DeclaringType);
+            var valueParam = Expression.Convert(argument, propertyInfo.PropertyType);
+
+            var setterCall = Expression.Call(instanceParam, propertyInfo.GetSetMethod(), valueParam);
+
+            return Expression.Lambda<PropertySetterDelegate>(setterCall, instance, argument).Compile();
+#endif
+        }
+
+        public static PropertyGetterDelegate GetPropertyGetterFn(this PropertyInfo propertyInfo)
+        {
+            var getMethodInfo = propertyInfo.GetGetMethod();
+            if (getMethodInfo == null) return null;
+
+#if MONOTOUCH || SILVERLIGHT || XBOX
+            return o => propertyInfo.GetGetMethod().Invoke(o, new object[] { });
+#else
+            try
+            {
+                var oInstanceParam = Expression.Parameter(typeof(object), "oInstanceParam");
+                var instanceParam = Expression.Convert(oInstanceParam, propertyInfo.DeclaringType);
+
+                var exprCallPropertyGetFn = Expression.Call(instanceParam, getMethodInfo);
+                var oExprCallPropertyGetFn = Expression.Convert(exprCallPropertyGetFn, typeof(object));
+
+                var propertyGetFn = Expression.Lambda<PropertyGetterDelegate>
+                    (
+                        oExprCallPropertyGetFn,
+                        oInstanceParam
+                    ).Compile();
+
+                return propertyGetFn;
+
+            }
+            catch (Exception ex)
+            {
+                Console.Write(ex.Message);
+                throw;
+            }
+#endif
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/TypeExtensions.cs b/lib/ServiceStack/src/ServiceStack.Common/TypeExtensions.cs
new file mode 100644
index 0000000..5c67b5e
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/TypeExtensions.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+
+namespace ServiceStack.Common
+{
+    public static class TypeExtensions
+    {
+        private static readonly Dictionary<Type, List<string>> TypePropertyNamesMap = new Dictionary<Type, List<string>>();
+
+        public static List<string> GetPropertyNames(this Type type)
+        {
+            lock (TypePropertyNamesMap)
+            {
+                List<string> propertyNames;
+                if (!TypePropertyNamesMap.TryGetValue(type, out propertyNames))
+                {
+                    propertyNames = Extensions.EnumerableExtensions.ConvertAll(type.GetProperties(), x => x.Name);
+                    TypePropertyNamesMap[type] = propertyNames;
+                }
+                return propertyNames;
+            }
+        }
+
+        public static List<T> ToAttributes<T>(this Type type) where T : Attribute
+        {
+            return type.GetCustomAttributes(typeof(T), true).SafeConvertAll(x => (T)x);
+        }
+
+#if !SILVERLIGHT
+        public static string GetAssemblyPath(this Type source)
+        {
+            var assemblyUri =
+                new Uri(source.Assembly.EscapedCodeBase);
+
+            return assemblyUri.LocalPath;
+        }
+#endif
+    }
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Common/UrnId.cs b/lib/ServiceStack/src/ServiceStack.Common/UrnId.cs
new file mode 100644
index 0000000..aaad712
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/UrnId.cs
@@ -0,0 +1,123 @@
+using System;
+using System.Text;
+
+namespace ServiceStack.Common
+{
+    /// <summary>
+    /// Creates a Unified Resource Name (URN) with the following formats:
+    /// 
+    ///		- urn:{TypeName}:{IdFieldValue}						e.g. urn:UserSession:1
+    ///		- urn:{TypeName}:{IdFieldName}:{IdFieldValue}		e.g. urn:UserSession:UserId:1			
+    /// 
+    /// </summary>
+    public class UrnId
+    {
+        private const char FieldSeperator = ':';
+        private const char FieldPartsSeperator = '/';
+        public string TypeName { get; private set; }
+        public string IdFieldValue { get; private set; }
+        public string IdFieldName { get; private set; }
+
+        const int HasNoIdFieldName = 3;
+        const int HasIdFieldName = 4;
+
+        private UrnId() { }
+
+        public static UrnId Parse(string urnId)
+        {
+            var urnParts = urnId.Split(FieldSeperator);
+            if (urnParts.Length == HasNoIdFieldName)
+            {
+                return new UrnId { TypeName = urnParts[1], IdFieldValue = urnParts[2] };
+            }
+            if (urnParts.Length == HasIdFieldName)
+            {
+                return new UrnId { TypeName = urnParts[1], IdFieldName = urnParts[2], IdFieldValue = urnParts[3] };
+            }
+            throw new ArgumentException("Cannot parse invalid urn: '{0}'", urnId);
+        }
+
+        public static string Create(string objectTypeName, string idFieldValue)
+        {
+            if (objectTypeName.Contains(FieldSeperator.ToString()))
+            {
+                throw new ArgumentException("objectTypeName cannot have the illegal characters: ':'", "objectTypeName");
+            }
+            if (idFieldValue.Contains(FieldSeperator.ToString()))
+            {
+                throw new ArgumentException("idFieldValue cannot have the illegal characters: ':'", "idFieldValue");
+            }
+            return string.Format("urn:{0}:{1}", objectTypeName, idFieldValue);
+        }
+
+        public static string CreateWithParts(string objectTypeName, params string[] keyParts)
+        {
+            if (objectTypeName.Contains(FieldSeperator.ToString()))
+            {
+                throw new ArgumentException("objectTypeName cannot have the illegal characters: ':'", "objectTypeName");
+            }
+
+            var sb = new StringBuilder();
+            foreach (var keyPart in keyParts)
+            {
+                if (sb.Length > 0)
+                    sb.Append(FieldPartsSeperator);
+                sb.Append(keyPart);
+            }
+
+            return string.Format("urn:{0}:{1}", objectTypeName, sb);
+        }
+
+        public static string CreateWithParts<T>(params string[] keyParts)
+        {
+            return CreateWithParts(typeof(T).Name, keyParts);
+        }
+
+        public static string Create<T>(string idFieldValue)
+        {
+            return Create(typeof(T), idFieldValue);
+        }
+
+        public static string Create(Type objectType, string idFieldValue)
+        {
+            if (idFieldValue.Contains(FieldSeperator.ToString()))
+            {
+                throw new ArgumentException("idFieldValue cannot have the illegal characters: ':'", "idFieldValue");
+            }
+            return string.Format("urn:{0}:{1}", objectType.Name, idFieldValue);
+        }
+
+        public static string Create<T>(string idFieldName, string idFieldValue)
+        {
+            return Create(typeof (T), idFieldName, idFieldValue);
+        }
+
+        public static string Create(Type objectType, string idFieldName, string idFieldValue)
+        {
+            if (idFieldValue.Contains(FieldSeperator.ToString()))
+            {
+                throw new ArgumentException("idFieldValue cannot have the illegal characters: ':'", "idFieldValue");
+            }
+            if (idFieldName.Contains(FieldSeperator.ToString()))
+            {
+                throw new ArgumentException("idFieldName cannot have the illegal characters: ':'", "idFieldName");
+            }
+            return string.Format("urn:{0}:{1}:{2}", objectType.Name, idFieldName, idFieldValue);
+        }
+
+        public static string GetStringId(string urn)
+        {
+            return Parse(urn).IdFieldValue;
+        }
+
+        public static Guid GetGuidId(string urn)
+        {
+            return new Guid(Parse(urn).IdFieldValue);
+        }
+
+        public static long GetLongId(string urn)
+        {
+            return long.Parse(Parse(urn).IdFieldValue);
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Utils/AssertUtils.cs b/lib/ServiceStack/src/ServiceStack.Common/Utils/AssertUtils.cs
new file mode 100644
index 0000000..b006770
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Utils/AssertUtils.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+
+namespace ServiceStack.Common.Utils
+{
+    public static class AssertUtils
+    {
+        public static void AreNotNull<T>(params T[] fields) where T : class 
+        {
+            foreach (var field in fields)
+            {
+                if (field == null)
+                {
+                    throw new ArgumentNullException(typeof(T).Name);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Asserts that the supplied arguments are not null.
+        /// 
+        /// AssertUtils.AreNotNull(new Dictionary<string,object>{ {"name",null} });
+        ///   will throw new ArgumentNullException("name");
+        /// </summary>
+        /// <param name="fieldMap">The field map.</param>
+        public static void AreNotNull(IDictionary<string,object> fieldMap)
+        {
+            foreach (var pair in fieldMap)
+            {
+                if (pair.Value == null)
+                {
+                    throw new ArgumentNullException(pair.Key);
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Utils/CommandsUtils.cs b/lib/ServiceStack/src/ServiceStack.Common/Utils/CommandsUtils.cs
new file mode 100644
index 0000000..8fe8822
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Utils/CommandsUtils.cs
@@ -0,0 +1,103 @@
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using ServiceStack.Common.Support;
+using ServiceStack.DesignPatterns.Command;
+
+namespace ServiceStack.Common.Utils
+{
+    public class CommandsUtils
+    {
+
+        public static List<T> ExecuteAsyncCommandList<T>(TimeSpan timeout, params ICommandList<T>[] commands)
+        {
+            return ExecuteAsyncCommandList(timeout, commands);
+        }
+
+        public static List<T> ExecuteAsyncCommandList<T>(TimeSpan timeout, IEnumerable<ICommandList<T>> commands)
+        {
+            var results = new List<T>();
+            var waitHandles = new List<WaitHandle>();
+            foreach (ICommandList<T> command in commands)
+            {
+                var waitHandle = new AutoResetEvent(false);
+                waitHandles.Add(waitHandle);
+                var commandResultsHandler = new CommandResultsHandler<T>(results, command, waitHandle);
+
+                ThreadPool.QueueUserWorkItem(ExecuteCommandList, commandResultsHandler);
+            }
+            WaitAll(waitHandles.ToArray(), timeout);
+            return results;
+        }
+
+
+        public static void WaitAll(WaitHandle[] waitHandles, TimeSpan timeout)
+        {
+            // throws an exception if there are no wait handles
+            if (waitHandles != null && waitHandles.Length > 0)
+            {
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+                if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA)
+                {
+                    // WaitAll for multiple handles on an STA thread is not supported.
+                    // CurrentThread is ApartmentState.STA when run under unit tests
+                    foreach (WaitHandle waitHandle in waitHandles)
+                    {
+                        waitHandle.WaitOne(timeout, false);
+                    }
+                }
+                else
+                {
+                    if (!WaitHandle.WaitAll(waitHandles, timeout, false))
+                    {
+                        throw new TimeoutException();
+                    }
+                }
+#else
+                if (!WaitHandle.WaitAll(waitHandles, timeout))
+                {
+                    throw new TimeoutException();
+                }
+#endif
+            }
+        }
+
+        private static void ExecuteCommandList(object state)
+        {
+            var handler = (ICommandExec)state;
+            handler.Execute();
+        }
+
+        private static void ExecuteCommandExec(object state)
+        {
+            var command = (ICommandExec)state;
+            command.Execute();
+        }
+
+        public static void ExecuteAsyncCommandExec(TimeSpan timeout, IEnumerable<ICommandExec> commands)
+        {
+            foreach (ICommandExec command in commands)
+            {
+                ThreadPool.QueueUserWorkItem(ExecuteCommandExec, command);
+            }
+        }
+
+        /// <summary>
+        /// Provide the an option for the callee to block until all commands are executed
+        /// </summary>
+        /// <param name="commands"></param>
+        /// <returns></returns>
+        public static List<WaitHandle> ExecuteAsyncCommandExec(IEnumerable<ICommandExec> commands)
+        {
+            var waitHandles = new List<WaitHandle>();
+            foreach (var command in commands)
+            {
+                var waitHandle = new AutoResetEvent(false);
+                waitHandles.Add(waitHandle);
+                var commandExecsHandler = new CommandExecsHandler(command, waitHandle);
+                ThreadPool.QueueUserWorkItem(ExecuteCommandList, commandExecsHandler);
+            }
+            return waitHandles;
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Utils/FuncUtils.cs b/lib/ServiceStack/src/ServiceStack.Common/Utils/FuncUtils.cs
new file mode 100644
index 0000000..87aff42
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Utils/FuncUtils.cs
@@ -0,0 +1,49 @@
+using System;
+using ServiceStack.Logging;
+
+namespace ServiceStack.Common.Utils
+{
+    public static class FuncUtils
+    {
+        private static readonly ILog Log = LogManager.GetLogger(typeof(FuncUtils));
+
+        /// <summary>
+        /// Invokes the action provided and returns true if no excpetion was thrown.
+        /// Otherwise logs the exception and returns false if an exception was thrown.
+        /// </summary>
+        /// <param name="action">The action.</param>
+        /// <returns></returns>
+        public static bool TryExec(Action action)
+        {
+            try
+            {
+                action();
+                return true;
+            }
+            catch (Exception ex)
+            {
+                Log.Error(ex.Message, ex);
+            }
+            return false;
+        }
+
+        public static T TryExec<T>(Func<T> func)
+        {
+            return TryExec(func, default(T));
+        }
+
+        public static T TryExec<T>(Func<T> func, T defaultValue)
+        {
+            try
+            {
+                return func();
+            }
+            catch (Exception ex)
+            {
+                Log.Error(ex.Message, ex);
+            }
+            return default(T);
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Utils/IdUtils.cs b/lib/ServiceStack/src/ServiceStack.Common/Utils/IdUtils.cs
new file mode 100644
index 0000000..35d164b
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Utils/IdUtils.cs
@@ -0,0 +1,157 @@
+using System;
+using System.IO;
+using ServiceStack.Common.Reflection;
+using ServiceStack.DesignPatterns.Model;
+
+namespace ServiceStack.Common.Utils
+{
+    public static class IdUtils<T>
+    {
+        internal static Func<T, object> CanGetId;
+
+        static IdUtils()
+        {
+
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+            var hasIdInterfaces = typeof(T).FindInterfaces(
+                (t, critera) => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IHasId<>), null);
+
+            if (hasIdInterfaces.Length > 0)
+            {
+                CanGetId = HasId<T>.GetId;
+                return;
+            }
+#endif
+
+            if (typeof(T).IsClass
+                && typeof(T).GetProperty(IdUtils.IdField) != null
+                && typeof(T).GetProperty(IdUtils.IdField).GetGetMethod() != null)
+            {
+                CanGetId = HasPropertyId<T>.GetId;
+            }
+            else
+            {
+                CanGetId = x => x.GetHashCode();
+            }
+        }
+
+        public static object GetId(T entity)
+        {
+            return CanGetId(entity);
+        }
+    }
+
+    internal static class HasPropertyId<TEntity>
+    {
+        private static readonly Func<TEntity, object> GetIdFn;
+
+        static HasPropertyId()
+        {
+            var pi = typeof(TEntity).GetProperty(IdUtils.IdField);
+            GetIdFn = StaticAccessors<TEntity>.ValueUnTypedGetPropertyTypeFn(pi);
+        }
+
+        public static object GetId(TEntity entity)
+        {
+            return GetIdFn(entity);
+        }
+    }
+
+    internal static class HasId<TEntity>
+    {
+        private static readonly Func<TEntity, object> GetIdFn;
+
+        static HasId()
+        {
+
+#if MONOTOUCH || SILVERLIGHT
+            GetIdFn = HasPropertyId<TEntity>.GetId;
+#else
+            var hasIdInterfaces = typeof(TEntity).FindInterfaces(
+                (t, critera) => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IHasId<>), null);
+
+            var genericArg = hasIdInterfaces[0].GetGenericArguments()[0];
+            var genericType = typeof(HasIdGetter<,>).MakeGenericType(typeof(TEntity), genericArg);
+
+            var oInstanceParam = System.Linq.Expressions.Expression.Parameter(typeof(TEntity), "oInstanceParam");
+            var exprCallStaticMethod = System.Linq.Expressions.Expression.Call
+                (
+                    genericType,
+                    "GetId",
+                    new Type[0],
+                    oInstanceParam
+                );
+            GetIdFn = System.Linq.Expressions.Expression.Lambda<Func<TEntity, object>>
+                (
+                    exprCallStaticMethod,
+                    oInstanceParam
+                ).Compile();
+#endif
+        }
+
+        public static object GetId(TEntity entity)
+        {
+            return GetIdFn(entity);
+        }
+    }
+
+    internal class HasIdGetter<TEntity, TId>
+        where TEntity : IHasId<TId>
+    {
+        public static object GetId(TEntity entity)
+        {
+            return entity.Id;
+        }
+    }
+
+    public static class IdUtils
+    {
+        public const string IdField = "Id";
+
+        public static object GetObjectId(this object entity)
+        {
+            return entity.GetType().GetProperty(IdField).GetGetMethod().Invoke(entity, new object[0]);
+        }
+
+        public static object GetId<T>(this T entity)
+        {
+            return IdUtils<T>.GetId(entity);
+        }
+
+        public static string CreateUrn<T>(object id)
+        {
+            return string.Format("urn:{0}:{1}", typeof(T).Name.ToLower(), id);
+        }
+
+        public static string CreateUrn(Type type, object id)
+        {
+            return string.Format("urn:{0}:{1}", type.Name.ToLower(), id);
+        }
+
+        public static string CreateUrn<T>(this T entity)
+        {
+            var id = GetId(entity);
+            return string.Format("urn:{0}:{1}", typeof(T).Name.ToLower(), id);
+        }
+
+        public static string CreateCacheKeyPath<T>(string idValue)
+        {
+            if (idValue.Length < 4)
+            {
+                idValue = idValue.PadLeft(4, '0');
+            }
+            idValue = idValue.Replace(" ", "-");
+
+            var rootDir = typeof(T).Name;
+            var dir1 = idValue.Substring(0, 2);
+            var dir2 = idValue.Substring(2, 2);
+
+            var path = string.Format("{1}{0}{2}{0}{3}{0}{4}", Path.DirectorySeparatorChar,
+                rootDir, dir1, dir2, idValue);
+
+            return path;
+        }
+
+    }
+
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Utils/PathUtils.cs b/lib/ServiceStack/src/ServiceStack.Common/Utils/PathUtils.cs
new file mode 100644
index 0000000..c8142a0
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Utils/PathUtils.cs
@@ -0,0 +1,84 @@
+using System;
+using System.IO;
+using System.Text;
+
+namespace ServiceStack.Common.Utils
+{
+    public static class PathUtils
+    {
+        public static string MapAbsolutePath(string relativePath, string appendPartialPathModifier)
+        {
+#if !SILVERLIGHT 
+            if (relativePath.StartsWith("~"))
+            {
+                var assemblyDirectoryPath = Path.GetDirectoryName(new Uri(typeof(PathUtils).Assembly.EscapedCodeBase).LocalPath);
+
+                // Escape the assembly bin directory to the hostname directory
+                var hostDirectoryPath = appendPartialPathModifier != null
+                                            ? assemblyDirectoryPath + appendPartialPathModifier
+                                            : assemblyDirectoryPath;
+
+                return Path.GetFullPath(relativePath.Replace("~", hostDirectoryPath));
+            }
+#endif
+            return relativePath;
+        }
+
+        /// <summary>
+        /// Maps the path of a file in the context of a VS project
+        /// </summary>
+        /// <param name="relativePath">the relative path</param>
+        /// <returns>the absolute path</returns>
+        /// <remarks>Assumes static content is two directories above the /bin/ directory,
+        /// eg. in a unit test scenario  the assembly would be in /bin/Debug/.</remarks>
+        public static string MapProjectPath(this string relativePath)
+        {
+            var mapPath = MapAbsolutePath(relativePath, string.Format("{0}..{0}..", Path.DirectorySeparatorChar));
+            return mapPath;
+        }
+
+        /// <summary>
+        /// Maps the path of a file in a self-hosted scenario
+        /// </summary>
+        /// <param name="relativePath">the relative path</param>
+        /// <returns>the absolute path</returns>
+        /// <remarks>Assumes static content is copied to /bin/ folder with the assemblies</remarks>
+        public static string MapAbsolutePath(this string relativePath)
+        {
+            var mapPath = MapAbsolutePath(relativePath, null);
+            return mapPath;
+        }
+
+        /// <summary>
+        /// Maps the path of a file in an Asp.Net hosted scenario
+        /// </summary>
+        /// <param name="relativePath">the relative path</param>
+        /// <returns>the absolute path</returns>
+        /// <remarks>Assumes static content is in the parent folder of the /bin/ directory</remarks>
+        public static string MapHostAbsolutePath(this string relativePath)
+        {
+            var mapPath = MapAbsolutePath(relativePath, string.Format("{0}..", Path.DirectorySeparatorChar));
+            return mapPath;
+        }
+
+        internal static string CombinePaths(StringBuilder sb, params string[] paths)
+        {
+            foreach (var path in paths)
+            {
+                if (sb.Length > 0)
+                    sb.Append("/");
+
+                sb.Append(path.TrimStart('/', '\\'));
+            }
+
+            return sb.ToString();
+        }
+
+        public static string CombinePaths(params string[] paths)
+        {
+            return CombinePaths(new StringBuilder(), paths);
+        }
+    }
+
+
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Utils/PerfUtils.cs b/lib/ServiceStack/src/ServiceStack.Common/Utils/PerfUtils.cs
new file mode 100644
index 0000000..ec5ffb1
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Utils/PerfUtils.cs
@@ -0,0 +1,32 @@
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+
+using System;
+using System.Diagnostics;
+
+namespace ServiceStack.Common.Utils
+{
+    public static class PerfUtils
+    {
+        public static TimeSpan ToTimeSpan(this long fromTicks)
+        {
+            return TimeSpan.FromSeconds(fromTicks * 1d / Stopwatch.Frequency);
+        }
+
+        public static long Measure(long iterations, Action action)
+        {
+            GC.Collect();
+            var begin = Stopwatch.GetTimestamp();
+
+            for (var i = 0; i < iterations; i++)
+            {
+                action();
+            }
+
+            var end = Stopwatch.GetTimestamp();
+
+            return (end - begin);
+        }
+    }
+}
+
+#endif
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Utils/ReflectionUtils.cs b/lib/ServiceStack/src/ServiceStack.Common/Utils/ReflectionUtils.cs
new file mode 100644
index 0000000..8ea9473
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Utils/ReflectionUtils.cs
@@ -0,0 +1,423 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Reflection.Emit;
+using ServiceStack.Common.Support;
+using ServiceStack.Logging;
+using ServiceStack.Net30.Collections.Concurrent;
+
+namespace ServiceStack.Common.Utils
+{
+    public class ReflectionUtils
+    {
+        public static readonly ILog Log = LogManager.GetLogger(typeof(ReflectionUtils));
+
+        /// <summary>
+        /// Populate an object with Example data.
+        /// </summary>
+        /// <param name="obj"></param>
+        /// <returns></returns>
+        public static object PopulateObject(object obj)
+        {
+            if (obj == null) return null;
+
+            return PopulateObjectInternal(obj, new Dictionary<Type, int>(20));
+        }
+
+        /// <summary>
+        /// Populates the object with example data.
+        /// </summary>
+        /// <param name="obj"></param>
+        /// <param name="recursionInfo">Tracks how deeply nested we are</param>
+        /// <returns></returns>
+        private static object PopulateObjectInternal(object obj, Dictionary<Type,int> recursionInfo)
+        {
+            if (obj == null) return null;
+            if (obj is string) return obj; // prevents it from dropping into the char[] Chars property.  Sheesh
+
+            var members = obj.GetType().GetMembers(BindingFlags.Public | BindingFlags.Instance);
+            foreach (var info in members)
+            {
+                var fieldInfo = info as FieldInfo;
+                var propertyInfo = info as PropertyInfo;
+                if (fieldInfo != null || propertyInfo != null)
+                {
+                    var memberType = fieldInfo != null ? fieldInfo.FieldType : propertyInfo.PropertyType;
+                    var value = CreateDefaultValue(memberType, recursionInfo);
+                    SetValue(fieldInfo, propertyInfo, obj, value);
+                }
+            }
+            return obj;
+        }
+
+        private static readonly Dictionary<Type, object> DefaultValueTypes 
+            = new Dictionary<Type, object>();
+
+        public static object GetDefaultValue(Type type)
+        {
+            if (!type.IsValueType) return null;
+
+            object defaultValue;
+            lock (DefaultValueTypes)
+            {
+                if (!DefaultValueTypes.TryGetValue(type, out defaultValue))
+                {
+                    defaultValue = Activator.CreateInstance(type);
+                    DefaultValueTypes[type] = defaultValue;
+                }
+            } 
+
+            return defaultValue;
+        }
+
+        private static readonly ConcurrentDictionary<string, AssignmentDefinition> AssignmentDefinitionCache 
+            = new ConcurrentDictionary<string, AssignmentDefinition>();
+
+        public static AssignmentDefinition GetAssignmentDefinition(Type toType, Type fromType)
+        {
+            var cacheKey = toType.FullName + "<" + fromType.FullName;
+
+            return AssignmentDefinitionCache.GetOrAdd(cacheKey, delegate {
+                
+                var definition = new AssignmentDefinition {
+                    ToType = toType,
+                    FromType = fromType,
+                };
+
+                var members = fromType.GetMembers(BindingFlags.Public | BindingFlags.Instance);
+                foreach (var info in members)
+                {
+                    var fromPropertyInfo = info as PropertyInfo;
+                    if (fromPropertyInfo != null)
+                    {
+                        var toPropertyInfo = GetPropertyInfo(toType, fromPropertyInfo.Name);
+                        if (toPropertyInfo == null) continue;
+
+                        if (!fromPropertyInfo.CanRead) continue;
+                        if (!toPropertyInfo.CanWrite) continue;
+
+                        definition.AddMatch(fromPropertyInfo, toPropertyInfo);
+                    }
+
+                    var fromFieldInfo = info as FieldInfo;
+                    if (fromFieldInfo != null)
+                    {
+                        var toFieldInfo = GetFieldInfo(toType, fromFieldInfo.Name);
+                        if (toFieldInfo == null) continue;
+
+                        definition.AddMatch(fromFieldInfo, toFieldInfo);
+                    }
+                }
+                return definition;
+            });
+
+        }
+
+        public static To PopulateObject<To, From>(To to, From from)
+        {
+            if (Equals(to, default(To)) || Equals(from, default(From))) return default(To);
+
+            var assignmentDefinition = GetAssignmentDefinition(to.GetType(), from.GetType());
+
+            assignmentDefinition.Populate(to, from);
+
+            return to;
+        }
+
+        public static To PopulateWithNonDefaultValues<To, From>(To to, From from)
+        {
+            if (Equals(to, default(To)) || Equals(from, default(From))) return default(To);
+
+            var assignmentDefinition = GetAssignmentDefinition(to.GetType(), from.GetType());
+
+            assignmentDefinition.PopulateWithNonDefaultValues(to, from);
+
+            return to;
+        }
+
+        public static To PopulateFromPropertiesWithAttribute<To, From>(To to, From from, 
+            Type attributeType)
+        {
+            if (Equals(to, default(To)) || Equals(from, default(From))) return default(To);
+
+            var assignmentDefinition = GetAssignmentDefinition(to.GetType(), from.GetType());
+
+            assignmentDefinition.PopulateFromPropertiesWithAttribute(to, from, attributeType);
+
+            return to;
+        }
+
+        public static void SetProperty(object obj, PropertyInfo propertyInfo, object value)
+        {
+            if (!propertyInfo.CanWrite)
+            {
+                Log.WarnFormat("Attempted to set read only property '{0}'", propertyInfo.Name);
+                return;
+            }
+            var propertySetMetodInfo = propertyInfo.GetSetMethod();
+            if (propertySetMetodInfo != null)
+            {
+                propertySetMetodInfo.Invoke(obj, new[] { value });
+            }
+        }
+
+        public static object GetProperty(object obj, PropertyInfo propertyInfo)
+        {
+            if (propertyInfo == null || !propertyInfo.CanRead)
+                return null;
+
+            var getMethod = propertyInfo.GetGetMethod();
+            return getMethod != null ? getMethod.Invoke(obj, new object[0]) : null;
+        }
+
+        public static void SetValue(FieldInfo fieldInfo, PropertyInfo propertyInfo, object obj, object value)
+        {
+            try
+            {
+                if (IsUnsettableValue(fieldInfo, propertyInfo)) return;
+                if (fieldInfo != null && !fieldInfo.IsLiteral)
+                {
+                    fieldInfo.SetValue(obj, value);
+                }
+                else
+                {
+                    SetProperty(obj, propertyInfo, value);
+                }
+            }
+            catch (Exception ex)
+            {
+                var name = (fieldInfo != null) ? fieldInfo.Name : propertyInfo.Name;
+                Log.DebugFormat("Could not set member: {0}. Error: {1}", name, ex.Message);
+            }
+        }
+
+        public static bool IsUnsettableValue(FieldInfo fieldInfo, PropertyInfo propertyInfo)
+        {
+            if (propertyInfo != null && propertyInfo.ReflectedType != null)
+            {
+                // Properties on non-user defined classes should not be set
+                // Currently we define those properties as properties declared on
+                // types defined in mscorlib
+
+                if (propertyInfo.DeclaringType.Assembly == typeof(object).Assembly)
+                {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        public static object[] CreateDefaultValues(IEnumerable<Type> types, Dictionary<Type, int> recursionInfo)
+        {
+            var values = new List<object>();
+            foreach (var type in types)
+            {
+                values.Add(CreateDefaultValue(type, recursionInfo));
+            }
+            return values.ToArray();
+        }
+
+        private const int MaxRecursionLevelForDefaultValues = 2; // do not nest a single type more than this deep.
+
+        public static object CreateDefaultValue(Type type, Dictionary<Type, int> recursionInfo)
+        {
+            if (type == typeof(string))
+            {
+                return type.Name;
+            }
+
+            if (type.IsEnum)
+            {
+#if SILVERLIGHT4
+                return Enum.ToObject(type, 0);
+#else
+                return Enum.GetValues(type).GetValue(0);
+#endif
+            }
+
+            // If we have hit our recursion limit for this type, then return null
+            int recurseLevel; // will get set to 0 if TryGetValue() fails
+            recursionInfo.TryGetValue(type, out recurseLevel);
+            if (recurseLevel > MaxRecursionLevelForDefaultValues) return null;
+
+            recursionInfo[type] = recurseLevel + 1; // increase recursion level for this type
+            try // use a try/finally block to make sure we decrease the recursion level for this type no matter which code path we take,
+            {
+
+                //when using KeyValuePair<TKey, TValue>, TKey must be non-default to stuff in a Dictionary
+                if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(KeyValuePair<,>))
+                {
+                    var genericTypes = type.GetGenericArguments();
+                    var valueType = Activator.CreateInstance(type, CreateDefaultValue(genericTypes[0], recursionInfo), CreateDefaultValue(genericTypes[1], recursionInfo));
+                    return PopulateObjectInternal(valueType, recursionInfo);
+                }
+
+                if (type.IsValueType)
+                {
+                    return Activator.CreateInstance(type);
+                }
+
+                if (type.IsArray)
+                {
+                    return PopulateArray(type, recursionInfo);
+                }
+
+                var constructorInfo = type.GetConstructor(Type.EmptyTypes);
+                var hasEmptyConstructor = constructorInfo != null;
+
+                if (hasEmptyConstructor)
+                {
+                    var value = constructorInfo.Invoke(new object[0]);
+
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+
+                    Type[] interfaces = type.FindInterfaces((t, critera) =>
+                        t.IsGenericType && t.GetGenericTypeDefinition() == typeof(ICollection<>)
+                        , null);
+
+                    bool isGenericCollection = interfaces.Length > 0;
+
+                    if (isGenericCollection)
+                    {
+                        SetGenericCollection(interfaces[0], value, recursionInfo);
+                    }
+#endif
+
+                    //when the object might have nested properties such as enums with non-0 values, etc
+                    return PopulateObjectInternal(value, recursionInfo);
+                }
+                return null;
+            }
+            finally
+            {
+                recursionInfo[type] = recurseLevel;
+            }
+        }
+
+        public static void SetGenericCollection(Type realisedListType, object genericObj, Dictionary<Type, int> recursionInfo)
+        {
+            var args = realisedListType.GetGenericArguments();
+
+            if (args.Length != 1)
+            {
+                Log.ErrorFormat("Found a generic list that does not take one generic argument: {0}", realisedListType);
+
+                return;
+            }
+
+            var methodInfo = realisedListType.GetMethod("Add");
+
+            if (methodInfo != null)
+            {
+                var argValues = CreateDefaultValues(args, recursionInfo);
+
+                methodInfo.Invoke(genericObj, argValues);
+            }
+        }
+
+        public static Array PopulateArray(Type type, Dictionary<Type, int> recursionInfo)
+        {
+            var elementType = type.GetElementType();
+            var objArray = Array.CreateInstance(elementType, 1);
+            var objElementType = CreateDefaultValue(elementType, recursionInfo);
+            objArray.SetValue(objElementType, 0);
+
+            return objArray;
+        }
+
+        //TODO: replace with InAssignableFrom
+        public static bool CanCast(Type toType, Type fromType)
+        {
+            if (toType.IsInterface)
+            {
+                var interfaceList = fromType.GetInterfaces().ToList();
+                if (interfaceList.Contains(toType)) return true;
+            }
+            else
+            {
+                Type baseType = fromType;
+                bool areSameTypes;
+                do
+                {
+                    areSameTypes = baseType == toType;
+                }
+                while (!areSameTypes && (baseType = fromType.BaseType) != null);
+
+                if (areSameTypes) return true;
+            }
+
+            return false;
+        }
+
+        public static MemberInfo GetMemberInfo(Type fromType, string memberName)
+        {
+            var baseType = fromType;
+            do
+            {
+                var members = baseType.GetMembers(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
+                foreach (var memberInfo in members)
+                {
+                    if (memberInfo.Name == memberName) return memberInfo;
+                }
+            }
+            while ((baseType = baseType.BaseType) != null);
+            return null;
+        }
+
+        public static FieldInfo GetFieldInfo(Type fromType, string fieldName)
+        {
+            var baseType = fromType;
+            do
+            {
+                var fieldInfos = baseType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
+                foreach (var fieldInfo in fieldInfos)
+                {
+                    if (fieldInfo.Name == fieldName) return fieldInfo;
+                }
+            }
+            while ((baseType = baseType.BaseType) != null);
+            return null;
+        }
+
+        public static PropertyInfo GetPropertyInfo(Type fromType, string propertyName)
+        {
+            var baseType = fromType;
+            do
+            {
+                var propertyInfos = baseType.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
+                foreach (var propertyInfo in propertyInfos)
+                {
+                    if (propertyInfo.Name == propertyName) return propertyInfo;
+                }
+            }
+            while ((baseType = baseType.BaseType) != null);
+            return null;
+        }
+
+        public static IEnumerable<KeyValuePair<PropertyInfo, T>> GetPropertyAttributes<T>(Type fromType) where T : Attribute
+        {
+            var attributeType = typeof(T);
+            var baseType = fromType;
+            do
+            {
+                var propertyInfos = baseType.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
+                foreach (var propertyInfo in propertyInfos)
+                {
+                    var attributes = propertyInfo.GetCustomAttributes(attributeType, true);
+                    foreach (T attribute in attributes)
+                    {
+                        yield return new KeyValuePair<PropertyInfo, T>(propertyInfo, attribute);
+                    }
+                }
+            }
+            while ((baseType = baseType.BaseType) != null);
+        }
+
+        public static object CreateInstance(Type type)
+        {
+            return Text.ReflectionExtensions.CreateInstance(type);
+        }
+    }
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Web/CompressedFileResult.cs b/lib/ServiceStack/src/ServiceStack.Common/Web/CompressedFileResult.cs
new file mode 100644
index 0000000..9620c8c
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Web/CompressedFileResult.cs
@@ -0,0 +1,60 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using ServiceStack.Common.Extensions;
+using ServiceStack.Configuration;
+using ServiceStack.Service;
+using ServiceStack.ServiceHost;
+using ServiceStack.Text;
+
+namespace ServiceStack.Common.Web
+{
+    public class CompressedFileResult
+        : IStreamWriter, IHasOptions
+    {
+        public const int Adler32ChecksumLength = 4;
+
+        public const string DefaultContentType = MimeTypes.Xml;
+
+        public string FilePath { get; private set; }
+
+        public Dictionary<string, string> Headers { get; private set; }
+
+        public IDictionary<string, string> Options
+        {
+            get { return this.Headers; }
+        }
+
+        public CompressedFileResult(string filePath)
+            : this(filePath, CompressionTypes.Deflate) { }
+
+        public CompressedFileResult(string filePath, string compressionType)
+            : this(filePath, compressionType, DefaultContentType) { }
+
+        public CompressedFileResult(string filePath, string compressionType, string contentMimeType)
+        {
+            if (!CompressionTypes.IsValid(compressionType))
+            {
+                throw new ArgumentException("Must be either 'deflate' or 'gzip'", compressionType);
+            }
+
+            this.FilePath = filePath;
+            this.Headers = new Dictionary<string, string> {
+                { HttpHeaders.ContentType, contentMimeType },
+                { HttpHeaders.ContentEncoding, compressionType },
+            };
+        }
+
+        public void WriteTo(Stream responseStream)
+        {
+            using (var fs = new FileStream(this.FilePath, FileMode.Open, FileAccess.Read))
+            {
+                fs.Position = Adler32ChecksumLength;
+
+                fs.WriteTo(responseStream);
+                responseStream.Flush();
+            }
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Web/CompressedResult.cs b/lib/ServiceStack/src/ServiceStack.Common/Web/CompressedResult.cs
new file mode 100644
index 0000000..34fa29e
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Web/CompressedResult.cs
@@ -0,0 +1,77 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using ServiceStack.Service;
+using ServiceStack.ServiceHost;
+
+namespace ServiceStack.Common.Web
+{
+    public class CompressedResult
+        : IStreamWriter, IHttpResult
+    {
+        public const int Adler32ChecksumLength = 4;
+
+        public const string DefaultContentType = MimeTypes.Xml;
+
+        public byte[] Contents { get; private set; }
+
+        public string ContentType { get; set; }
+
+        public Dictionary<string, string> Headers { get; private set; }
+
+        public int Status { get; set; }
+
+        public HttpStatusCode StatusCode
+        {
+            get { return (HttpStatusCode)Status; }
+            set { Status = (int)value; }
+        }
+
+        public string StatusDescription { get; set; }
+
+        public object Response
+        {
+            get { return this.Contents; }
+            set { throw new NotImplementedException(); }
+        }
+
+        public IContentTypeWriter ResponseFilter { get; set; }
+
+        public IRequestContext RequestContext { get; set; }
+
+        public IDictionary<string, string> Options
+        {
+            get { return this.Headers; }
+        }
+
+        public CompressedResult(byte[] contents)
+            : this(contents, CompressionTypes.Deflate) { }
+
+        public CompressedResult(byte[] contents, string compressionType)
+            : this(contents, compressionType, DefaultContentType) { }
+
+        public CompressedResult(byte[] contents, string compressionType, string contentMimeType)
+        {
+            if (!CompressionTypes.IsValid(compressionType))
+            {
+                throw new ArgumentException("Must be either 'deflate' or 'gzip'", compressionType);
+            }
+
+            this.StatusCode = HttpStatusCode.OK;
+            this.ContentType = contentMimeType;
+
+            this.Contents = contents;
+            this.Headers = new Dictionary<string, string> {
+                { HttpHeaders.ContentEncoding, compressionType },
+            };
+        }
+
+        public void WriteTo(Stream responseStream)
+        {
+            responseStream.Write(this.Contents, 0, this.Contents.Length);
+            //stream.Write(this.Contents, Adler32ChecksumLength, this.Contents.Length - Adler32ChecksumLength);
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Web/CompressionTypes.cs b/lib/ServiceStack/src/ServiceStack.Common/Web/CompressionTypes.cs
new file mode 100644
index 0000000..470942d
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Web/CompressionTypes.cs
@@ -0,0 +1,40 @@
+using System;
+
+namespace ServiceStack.Common.Web
+{
+    public static class CompressionTypes
+    {
+        public static readonly string[] AllCompressionTypes = new[] { Deflate, GZip };
+
+        public const string Default = Deflate;
+        public const string Deflate = "deflate";
+        public const string GZip = "gzip";
+
+        public static bool IsValid(string compressionType)
+        {
+            return compressionType == Deflate || compressionType == GZip;
+        }
+
+        public static void AssertIsValid(string compressionType)
+        {
+            if (!IsValid(compressionType))
+            {
+                throw new NotSupportedException(compressionType
+                    + " is not a supported compression type. Valid types: gzip, deflate.");
+            }
+        }
+
+        public static string GetExtension(string compressionType)
+        {
+            switch (compressionType)
+            {
+                case Deflate:
+                case GZip:
+                    return "." + compressionType;
+                default:
+                    throw new NotSupportedException(
+                        "Unknown compressionType: " + compressionType);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Web/ContentType.cs b/lib/ServiceStack/src/ServiceStack.Common/Web/ContentType.cs
new file mode 100644
index 0000000..cc08bc9
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Web/ContentType.cs
@@ -0,0 +1,210 @@
+using System;
+using ServiceStack.ServiceHost;
+using ServiceStack.Text;
+
+namespace ServiceStack.Common.Web
+{
+    public static class ContentType
+    {
+        public const string Utf8Suffix = "; charset=utf-8";
+
+        public const string HeaderContentType = "Content-Type";
+
+        public const string FormUrlEncoded = "application/x-www-form-urlencoded";
+
+        public const string MultiPartFormData = "multipart/form-data";
+
+        public const string Html = "text/html";
+
+        public const string JsonReport = "text/jsonreport";
+
+        public const string Xml = "application/xml";
+
+        public const string XmlText = "text/xml";
+
+        public const string Soap11 = " text/xml; charset=utf-8";
+
+        public const string Soap12 = " application/soap+xml";
+
+        public const string Json = "application/json";
+
+        public const string JsonText = "text/json";
+
+        public const string JavaScript = "application/javascript";
+
+        public const string Jsv = "application/jsv";
+
+        public const string JsvText = "text/jsv";
+
+        public const string Csv = "text/csv";
+
+        public const string Yaml = "application/yaml";
+
+        public const string YamlText = "text/yaml";
+
+        public const string PlainText = "text/plain";
+
+        public const string MarkdownText = "text/markdown";
+
+        public const string ProtoBuf = "application/x-protobuf";
+
+        public const string MsgPack = "application/x-msgpack";
+
+        public const string Bson = "application/bson";
+
+        public const string Binary = "application/octet-stream";
+
+        public static EndpointAttributes GetEndpointAttributes(string contentType)
+        {
+            if (contentType == null)
+                return EndpointAttributes.None;
+
+            var realContentType = GetRealContentType(contentType);
+            switch (realContentType)
+            {
+                case Json:
+                case JsonText:
+                    return EndpointAttributes.Json;
+
+                case Xml:
+                case XmlText:
+                    return EndpointAttributes.Xml;
+
+                case Html:
+                    return EndpointAttributes.Html;
+
+                case Jsv:
+                case JsvText:
+                    return EndpointAttributes.Jsv;
+
+                case Yaml:
+                case YamlText:
+                    return EndpointAttributes.Yaml;
+
+                case Csv:
+                    return EndpointAttributes.Csv;
+
+                case Soap11:
+                    return EndpointAttributes.Soap11;
+
+                case Soap12:
+                    return EndpointAttributes.Soap12;
+            }
+
+            return EndpointAttributes.None;
+        }
+
+        public static string GetRealContentType(string contentType)
+        {
+            return contentType == null
+                       ? null
+                       : contentType.Split(';')[0].Trim();
+        }
+
+        public static bool MatchesContentType(this string contentType, string matchesContentType)
+        {
+            return GetRealContentType(contentType) == GetRealContentType(matchesContentType);
+        }
+
+        public static bool IsBinary(this string contentType)
+        {
+            var realContentType = GetRealContentType(contentType);
+            switch (realContentType)
+            {
+                case ProtoBuf:
+                case MsgPack:
+                case Binary:
+                case Bson:
+                    return true;
+            }
+
+            var primaryType = realContentType.SplitOnFirst('/')[0];
+            switch (primaryType)
+            {
+                case "image":
+                case "audio":
+                case "video":
+                    return true;
+            }
+
+            return false;
+        }
+
+        public static Feature GetFeature(string contentType)
+        {
+            if (contentType == null)
+                return Feature.None;
+
+            var realContentType = GetRealContentType(contentType);
+            switch (realContentType)
+            {
+                case Json:
+                case JsonText:
+                    return Feature.Json;
+
+                case Xml:
+                case XmlText:
+                    return Feature.Xml;
+
+                case Html:
+                    return Feature.Html;
+
+                case Jsv:
+                case JsvText:
+                    return Feature.Jsv;
+
+                case Csv:
+                    return Feature.Csv;
+
+                case Soap11:
+                    return Feature.Soap11;
+
+                case Soap12:
+                    return Feature.Soap12;
+            }
+
+            return Feature.None;
+        }
+
+        public static string GetContentFormat(EndpointType endpointType)
+        {
+            return endpointType.ToString().ToLower();
+        }
+
+        public static string GetContentFormat(string contentType)
+        {
+            if (contentType == null) return contentType;
+            var parts = contentType.Split('/');
+            return parts[parts.Length - 1];
+        }
+
+        public static string ToContentFormat(this string contentType)
+        {
+            return GetContentFormat(contentType);
+        }
+
+        public static string GetContentType(EndpointType endpointType)
+        {
+            switch (endpointType)
+            {
+                case EndpointType.Soap11:
+                case EndpointType.Soap12:
+                case EndpointType.Xml:
+                    return Xml;
+
+                case EndpointType.Json:
+                    return Json;
+
+                case EndpointType.Jsv:
+                    return JsvText;
+
+                case EndpointType.ProtoBuf:
+                    return ProtoBuf;
+                
+                default:
+                    return null;
+            }
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Web/EndPoint.cs b/lib/ServiceStack/src/ServiceStack.Common/Web/EndPoint.cs
new file mode 100644
index 0000000..5443f3f
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Web/EndPoint.cs
@@ -0,0 +1,14 @@
+namespace ServiceStack.Common.Web
+{
+    public class EndPoint
+    {
+        public string Host { get; private set; }
+        public int Port { get; private set; }
+
+        public EndPoint(string host, int port)
+        {
+            Host = host;
+            Port = port;
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Web/EndpointType.cs b/lib/ServiceStack/src/ServiceStack.Common/Web/EndpointType.cs
new file mode 100644
index 0000000..efd47a4
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Web/EndpointType.cs
@@ -0,0 +1,14 @@
+namespace ServiceStack.Common.Web
+{
+    public enum EndpointType
+    {
+        None,
+        Xml,
+        Json,
+        Jsv,
+        Csv,
+        ProtoBuf,
+        Soap11,
+        Soap12,
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Web/HttpError.cs b/lib/ServiceStack/src/ServiceStack.Common/Web/HttpError.cs
new file mode 100644
index 0000000..ef3e9f4
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Web/HttpError.cs
@@ -0,0 +1,120 @@
+using System;
+using System.Collections.Generic;
+using System.Net;
+using ServiceStack.ServiceHost;
+using ServiceStack.ServiceInterface.ServiceModel;
+
+namespace ServiceStack.Common.Web
+{
+    public class HttpError : Exception, IHttpError
+    {
+        public HttpError() : this(null) {}
+
+        public HttpError(string message)
+            : this(HttpStatusCode.InternalServerError, message) {}
+
+        public HttpError(HttpStatusCode statusCode, string errorCode)
+            : this(statusCode, errorCode, null) { }
+
+        public HttpError(int statusCode, string errorCode)
+            : this(statusCode, errorCode, null) { }
+
+        public HttpError(object responseDto, HttpStatusCode statusCode, string errorCode, string errorMessage)
+            : this(statusCode, errorCode, errorMessage)
+        {
+            this.Response = responseDto;
+        }
+
+        public HttpError(object responseDto, int statusCode, string errorCode, string errorMessage)
+            : this(statusCode, errorCode, errorMessage)
+        {
+            this.Response = responseDto;
+        }
+
+        public HttpError(HttpStatusCode statusCode, string errorCode, string errorMessage)
+            : this((int)statusCode, errorCode, errorMessage){}
+
+        public HttpError(int statusCode, string errorCode, string errorMessage)
+            : base(errorMessage ?? errorCode)
+        {
+            this.ErrorCode = errorCode;
+            this.Status = statusCode;
+            this.Headers = new Dictionary<string, string>();
+            this.StatusDescription = errorCode;
+        }
+
+        public HttpError(HttpStatusCode statusCode, Exception innerException)
+            : this(innerException.Message, innerException)
+        {
+            this.StatusCode = statusCode;
+        }
+
+        public HttpError(string message, Exception innerException) : base(message, innerException)
+        {
+            if (innerException != null)
+            {
+                this.ErrorCode = innerException.GetType().Name;
+            }
+            this.Headers = new Dictionary<string, string>();			
+        }
+
+        public string ErrorCode { get; set; }
+
+        public string ContentType { get; set; }
+
+        public Dictionary<string, string> Headers { get; set; }
+        
+        public int Status { get; set; }
+
+        public HttpStatusCode StatusCode
+        {
+            get { return (HttpStatusCode)Status; }
+            set { Status = (int)value; }
+        }
+
+        public string StatusDescription { get; set; }
+
+        public object Response { get; set; }
+
+        public IContentTypeWriter ResponseFilter { get; set; }
+        
+        public IRequestContext RequestContext { get; set; }
+
+        public IDictionary<string, string> Options
+        {
+            get { return this.Headers; }
+        }
+
+        public ResponseStatus ResponseStatus
+        {
+            get
+            {
+                return this.Response.ToResponseStatus();
+            }
+        }
+
+        public List<ResponseError> GetFieldErrors()
+        {
+            var responseStatus = ResponseStatus;
+            if (responseStatus != null)
+                return responseStatus.Errors ?? new List<ResponseError>();
+            
+            return new List<ResponseError>();
+        }
+
+        public static Exception NotFound(string message)
+        {
+            return new HttpError(HttpStatusCode.NotFound, message);
+        }
+
+        public static Exception Unauthorized(string message)
+        {
+            return new HttpError(HttpStatusCode.Unauthorized, message);
+        }
+
+        public static Exception Conflict(string message)
+        {
+            return new HttpError(HttpStatusCode.Conflict, message);
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Web/HttpHeaders.cs b/lib/ServiceStack/src/ServiceStack.Common/Web/HttpHeaders.cs
new file mode 100644
index 0000000..761fdb2
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Web/HttpHeaders.cs
@@ -0,0 +1,53 @@
+namespace ServiceStack.Common.Web
+{
+    public static class HttpHeaders
+    {
+        public const string XParamOverridePrefix = "X-Param-Override-";
+
+        public const string XHttpMethodOverride = "X-Http-Method-Override";
+
+        public const string XUserAuthId = "X-UAId";
+
+        public const string XForwardedFor = "X-Forwarded-For";
+
+        public const string XRealIp = "X-Real-IP";
+
+        public const string Referer = "Referer";
+
+        public const string CacheControl = "Cache-Control";
+
+        public const string IfModifiedSince = "If-Modified-Since";
+
+        public const string LastModified = "Last-Modified";
+
+        public const string Accept = "Accept";
+
+        public const string AcceptEncoding = "Accept-Encoding";
+
+        public const string ContentType = "Content-Type";
+
+        public const string ContentEncoding = "Content-Encoding";
+
+        public const string ContentLength = "Content-Length";
+
+        public const string ContentDisposition = "Content-Disposition";
+
+        public const string Location = "Location";
+
+        public const string SetCookie = "Set-Cookie";
+
+        public const string ETag = "ETag";
+
+        public const string Authorization = "Authorization";
+
+        public const string WwwAuthenticate = "WWW-Authenticate";
+
+        public const string AllowOrigin = "Access-Control-Allow-Origin";
+
+        public const string AllowMethods = "Access-Control-Allow-Methods";
+
+        public const string AllowHeaders = "Access-Control-Allow-Headers";
+        
+        public const string AllowCredentials = "Access-Control-Allow-Credentials";
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Web/HttpMethods.cs b/lib/ServiceStack/src/ServiceStack.Common/Web/HttpMethods.cs
new file mode 100644
index 0000000..09f53fc
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Web/HttpMethods.cs
@@ -0,0 +1,37 @@
+using System;
+using ServiceStack.ServiceHost;
+
+namespace ServiceStack.Common.Web
+{
+    public static class HttpMethods
+    {
+        public const string Get = "GET";
+        public const string Put = "PUT";
+        public const string Post = "POST";
+        public const string Delete = "DELETE";
+        public const string Head = "HEAD";
+        public const string Options = "OPTIONS";
+        public const string Patch = "PATCH";
+
+        public static EndpointAttributes GetEndpointAttribute(string httpMethod)
+        {
+            switch (httpMethod.ToUpper())
+            {
+                case Get:
+                    return EndpointAttributes.HttpGet;
+                case Put:
+                    return EndpointAttributes.HttpPut;
+                case Post:
+                    return EndpointAttributes.HttpPost;
+                case Delete:
+                    return EndpointAttributes.HttpDelete;
+                case Patch:
+                    return EndpointAttributes.HttpPatch;
+                case Head:
+                    return EndpointAttributes.HttpHead;
+            }
+
+            return EndpointAttributes.None;
+        }
+    }
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Web/HttpResponseFilter.cs b/lib/ServiceStack/src/ServiceStack.Common/Web/HttpResponseFilter.cs
new file mode 100644
index 0000000..b9619ab
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Web/HttpResponseFilter.cs
@@ -0,0 +1,304 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using ServiceStack.ServiceHost;
+using ServiceStack.ServiceModel.Serialization;
+using ServiceStack.Text;
+
+namespace ServiceStack.Common.Web
+{
+    public class HttpResponseFilter : IContentTypeFilter
+    {
+        private static readonly UTF8Encoding UTF8EncodingWithoutBom = new UTF8Encoding(false);
+
+        public static HttpResponseFilter Instance = new HttpResponseFilter();
+
+        public Dictionary<string, StreamSerializerDelegate> ContentTypeSerializers
+            = new Dictionary<string, StreamSerializerDelegate>();
+
+        public Dictionary<string, ResponseSerializerDelegate> ContentTypeResponseSerializers
+            = new Dictionary<string, ResponseSerializerDelegate>();
+
+        public Dictionary<string, StreamDeserializerDelegate> ContentTypeDeserializers
+            = new Dictionary<string, StreamDeserializerDelegate>();
+
+        public HttpResponseFilter()
+        {
+            this.ContentTypeFormats = new Dictionary<string, string>();
+        }
+
+        public void ClearCustomFilters()
+        {
+            this.ContentTypeFormats = new Dictionary<string, string>();
+            this.ContentTypeSerializers = new Dictionary<string, StreamSerializerDelegate>();
+            this.ContentTypeDeserializers = new Dictionary<string, StreamDeserializerDelegate>();
+        }
+
+        public Dictionary<string, string> ContentTypeFormats { get; set; }
+
+        public void Register(string contentType, StreamSerializerDelegate streamSerializer, StreamDeserializerDelegate streamDeserializer)
+        {
+            if (contentType.IsNullOrEmpty())
+                throw new ArgumentNullException("contentType");
+
+            var parts = contentType.Split('/');
+            var format = parts[parts.Length - 1];
+            this.ContentTypeFormats[format] = contentType;
+
+            SetContentTypeSerializer(contentType, streamSerializer);
+            SetContentTypeDeserializer(contentType, streamDeserializer);
+        }
+
+        public void Register(string contentType, ResponseSerializerDelegate responseSerializer,
+                             StreamDeserializerDelegate streamDeserializer)
+        {
+            if (contentType.IsNullOrEmpty())
+                throw new ArgumentNullException("contentType");
+
+            var parts = contentType.Split('/');
+            var format = parts[parts.Length - 1];
+            this.ContentTypeFormats[format] = contentType;
+
+            this.ContentTypeResponseSerializers[contentType] = responseSerializer;
+            SetContentTypeDeserializer(contentType, streamDeserializer);
+        }
+
+        public void SetContentTypeSerializer(string contentType, StreamSerializerDelegate streamSerializer)
+        {
+            this.ContentTypeSerializers[contentType] = streamSerializer;
+        }
+
+        public void SetContentTypeDeserializer(string contentType, StreamDeserializerDelegate streamDeserializer)
+        {
+            this.ContentTypeDeserializers[contentType] = streamDeserializer;
+        }
+
+        public string Serialize(string contentType, object response)
+        {
+            switch (contentType)
+            {
+                case ContentType.Xml:
+                    return XmlSerializer.SerializeToString(response);
+
+                case ContentType.Json:
+                    return JsonDataContractSerializer.Instance.SerializeToString(response);
+
+                case ContentType.Jsv:
+                    return TypeSerializer.SerializeToString(response);
+
+                default:
+                    throw new NotSupportedException("ContentType not supported: " + contentType);
+            }
+        }
+
+        public byte[] SerializeToBytes(IRequestContext requestContext, object response)
+        {
+            var contentType = requestContext.ResponseContentType;
+
+            StreamSerializerDelegate responseStreamWriter;
+            if (this.ContentTypeSerializers.TryGetValue(contentType, out responseStreamWriter) ||
+                this.ContentTypeSerializers.TryGetValue(ContentType.GetRealContentType(contentType), out responseStreamWriter))
+            {
+                using (var ms = new MemoryStream())
+                {
+                    responseStreamWriter(requestContext, response, ms);
+                    ms.Position = 0;
+                    return ms.ToArray();
+                }
+            }
+
+            ResponseSerializerDelegate responseWriter;
+            if (this.ContentTypeResponseSerializers.TryGetValue(contentType, out responseWriter) ||
+                this.ContentTypeResponseSerializers.TryGetValue(ContentType.GetRealContentType(contentType), out responseWriter))
+            {
+                using (var ms = new MemoryStream())
+                {
+                    var httpRes = new HttpResponseStreamWrapper(ms);
+                    responseWriter(requestContext, response, httpRes);
+                    ms.Position = 0;
+                    return ms.ToArray();
+                }
+            }
+
+            var contentTypeAttr = ContentType.GetEndpointAttributes(contentType);
+            switch (contentTypeAttr)
+            {
+                case EndpointAttributes.Xml:
+                    return XmlSerializer.SerializeToString(response).ToUtf8Bytes();
+
+                case EndpointAttributes.Json:
+                    return JsonDataContractSerializer.Instance.SerializeToString(response).ToUtf8Bytes();
+
+                case EndpointAttributes.Jsv:
+                    return TypeSerializer.SerializeToString(response).ToUtf8Bytes();
+            }
+
+            throw new NotSupportedException("ContentType not supported: " + contentType);
+        }
+
+        public string SerializeToString(IRequestContext requestContext, object response)
+        {
+            var contentType = requestContext.ResponseContentType;
+
+            StreamSerializerDelegate responseStreamWriter;
+            if (this.ContentTypeSerializers.TryGetValue(contentType, out responseStreamWriter) ||
+                this.ContentTypeSerializers.TryGetValue(ContentType.GetRealContentType(contentType), out responseStreamWriter))
+            {
+                using (var ms = new MemoryStream())
+                {
+                    responseStreamWriter(requestContext, response, ms);
+
+                    ms.Position = 0;
+                    var result = new StreamReader(ms, UTF8EncodingWithoutBom).ReadToEnd();
+                    return result;
+                }
+            }
+
+            ResponseSerializerDelegate responseWriter;
+            if (this.ContentTypeResponseSerializers.TryGetValue(contentType, out responseWriter) ||
+                this.ContentTypeResponseSerializers.TryGetValue(ContentType.GetRealContentType(contentType), out responseWriter))
+            {
+                using (var ms = new MemoryStream())
+                {
+                    var httpRes = new HttpResponseStreamWrapper(ms);
+                    responseWriter(requestContext, response, httpRes);
+
+                    ms.Position = 0;
+                    var result = new StreamReader(ms, UTF8EncodingWithoutBom).ReadToEnd();
+                    return result;
+                }
+            }
+
+
+            var contentTypeAttr = ContentType.GetEndpointAttributes(contentType);
+            switch (contentTypeAttr)
+            {
+                case EndpointAttributes.Xml:
+                    return XmlSerializer.SerializeToString(response);
+
+                case EndpointAttributes.Json:
+                    return JsonDataContractSerializer.Instance.SerializeToString(response);
+
+                case EndpointAttributes.Jsv:
+                    return TypeSerializer.SerializeToString(response);
+            }
+
+            throw new NotSupportedException("ContentType not supported: " + contentType);
+        }
+
+        public void SerializeToStream(IRequestContext requestContext, object response, Stream responseStream)
+        {
+            var contentType = requestContext.ResponseContentType;
+            var serializer = GetResponseSerializer(contentType);
+            if (serializer == null)
+                throw new NotSupportedException("ContentType not supported: " + contentType);
+
+            var httpRes = new HttpResponseStreamWrapper(responseStream);
+            serializer(requestContext, response, httpRes);
+        }
+
+        public void SerializeToResponse(IRequestContext requestContext, object response, IHttpResponse httpResponse)
+        {
+            var contentType = requestContext.ResponseContentType;
+            var serializer = GetResponseSerializer(contentType);
+            if (serializer == null)
+                throw new NotSupportedException("ContentType not supported: " + contentType);
+
+            serializer(requestContext, response, httpResponse);
+        }
+
+        public ResponseSerializerDelegate GetResponseSerializer(string contentType)
+        {
+            ResponseSerializerDelegate responseWriter;
+            if (this.ContentTypeResponseSerializers.TryGetValue(contentType, out responseWriter)||
+                this.ContentTypeResponseSerializers.TryGetValue(ContentType.GetRealContentType(contentType), out responseWriter))
+            {
+                return responseWriter;
+            }
+
+            var serializer = GetStreamSerializer(contentType);
+            if (serializer == null) return null;
+
+            return (httpReq, dto, httpRes) => serializer(httpReq, dto, httpRes.OutputStream);
+        }
+
+        public StreamSerializerDelegate GetStreamSerializer(string contentType)
+        {
+            StreamSerializerDelegate responseWriter;
+            if (this.ContentTypeSerializers.TryGetValue(contentType, out responseWriter)||
+                this.ContentTypeSerializers.TryGetValue(ContentType.GetRealContentType(contentType), out responseWriter))
+            {
+                return responseWriter;
+            }
+
+            var contentTypeAttr = ContentType.GetEndpointAttributes(contentType);
+            switch (contentTypeAttr)
+            {
+                case EndpointAttributes.Xml:
+                    return (r, o, s) => XmlSerializer.SerializeToStream(o, s);
+
+                case EndpointAttributes.Json:
+                    return (r, o, s) => JsonDataContractSerializer.Instance.SerializeToStream(o, s);
+
+                case EndpointAttributes.Jsv:
+                    return (r, o, s) => TypeSerializer.SerializeToStream(o, s);
+            }
+
+            return null;
+        }
+
+        public object DeserializeFromString(string contentType, Type type, string request)
+        {
+            var contentTypeAttr = ContentType.GetEndpointAttributes(contentType);
+            switch (contentTypeAttr)
+            {
+                case EndpointAttributes.Xml:
+                    return XmlSerializer.DeserializeFromString(request, type);
+
+                case EndpointAttributes.Json:
+                    return JsonDataContractDeserializer.Instance.DeserializeFromString(request, type);
+
+                case EndpointAttributes.Jsv:
+                    return TypeSerializer.DeserializeFromString(request, type);
+
+                default:
+                    throw new NotSupportedException("ContentType not supported: " + contentType);
+            }
+        }
+
+        public object DeserializeFromStream(string contentType, Type type, Stream fromStream)
+        {
+            var deserializer = GetStreamDeserializer(contentType);
+            if (deserializer == null)
+                throw new NotSupportedException("ContentType not supported: " + contentType);
+
+            return deserializer(type, fromStream);
+        }
+
+        public StreamDeserializerDelegate GetStreamDeserializer(string contentType)
+        {
+            StreamDeserializerDelegate streamReader;
+            var realContentType = contentType.Split(';')[0].Trim();
+            if (this.ContentTypeDeserializers.TryGetValue(realContentType, out streamReader))
+            {
+                return streamReader;
+            }
+
+            var contentTypeAttr = ContentType.GetEndpointAttributes(contentType);
+            switch (contentTypeAttr)
+            {
+                case EndpointAttributes.Xml:
+                    return XmlSerializer.DeserializeFromStream;
+
+                case EndpointAttributes.Json:
+                    return JsonDataContractDeserializer.Instance.DeserializeFromStream;
+
+                case EndpointAttributes.Jsv:
+                    return TypeSerializer.DeserializeFromStream;
+            }
+
+            return null;
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Web/HttpResponseStreamWrapper.cs b/lib/ServiceStack/src/ServiceStack.Common/Web/HttpResponseStreamWrapper.cs
new file mode 100644
index 0000000..4d5a373
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Web/HttpResponseStreamWrapper.cs
@@ -0,0 +1,69 @@
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using ServiceStack.Common.Utils;
+using ServiceStack.ServiceHost;
+
+namespace ServiceStack.Common.Web
+{
+    public class HttpResponseStreamWrapper : IHttpResponse
+    {
+        private static readonly UTF8Encoding UTF8EncodingWithoutBom = new UTF8Encoding(false);
+
+        public HttpResponseStreamWrapper(Stream stream)
+        {
+            this.OutputStream = stream;
+            this.Headers = new Dictionary<string, string>();
+        }
+
+        public Dictionary<string, string> Headers { get; set; }
+
+        public object OriginalResponse
+        {
+            get { return null; }
+        }
+
+        public int StatusCode { set; private get; }
+        public string StatusDescription { set; private get; }
+        public string ContentType { get; set; }
+
+        public ICookies Cookies { get; set; }
+
+        public void AddHeader(string name, string value)
+        {
+            this.Headers[name] = value;
+        }
+
+        public void Redirect(string url)
+        {
+            this.Headers[HttpHeaders.Location] = url;
+        }
+
+        public Stream OutputStream { get; private set; }
+
+        public void Write(string text)
+        {
+            var bytes = UTF8EncodingWithoutBom.GetBytes(text);
+            OutputStream.Write(bytes, 0, bytes.Length);
+        }
+
+        public void Close()
+        {
+            if (IsClosed) return;
+            OutputStream.Close();
+            IsClosed = true;
+        }
+
+        public void End()
+        {
+            Close();
+        }
+
+        public void Flush()
+        {
+            OutputStream.Flush();
+        }
+
+        public bool IsClosed { get; private set; }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Web/HttpResult.cs b/lib/ServiceStack/src/ServiceStack.Common/Web/HttpResult.cs
new file mode 100644
index 0000000..a6cb988
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Web/HttpResult.cs
@@ -0,0 +1,247 @@
+#if !SILVERLIGHT
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using ServiceStack.Service;
+using ServiceStack.ServiceHost;
+using ServiceStack.Text;
+
+namespace ServiceStack.Common.Web
+{
+    public class HttpResult
+        : IHttpResult, IStreamWriter
+    {
+        public HttpResult()
+            : this((object)null, null)
+        {
+        }
+
+        public HttpResult(object response)
+            : this(response, null)
+        {
+        }
+
+        public HttpResult(object response, string contentType)
+            : this(response, contentType, HttpStatusCode.OK)
+        {
+        }
+
+        public HttpResult(HttpStatusCode statusCode, string statusDescription)
+            : this()
+        {
+            StatusCode = statusCode;
+            StatusDescription = statusDescription;
+        }
+
+        public HttpResult(object response, HttpStatusCode statusCode)
+            : this(response, null, statusCode) { }
+
+        public HttpResult(object response, string contentType, HttpStatusCode statusCode)
+        {
+            this.Headers = new Dictionary<string, string>();
+            this.ResponseFilter = HttpResponseFilter.Instance;
+
+            this.Response = response;
+            this.ContentType = contentType;
+            this.StatusCode = statusCode;
+        }
+
+        public HttpResult(FileInfo fileResponse)
+            : this(fileResponse, false, MimeTypes.GetMimeType(fileResponse.Name)) { }
+
+        public HttpResult(FileInfo fileResponse, bool asAttachment)
+            : this(fileResponse, asAttachment, MimeTypes.GetMimeType(fileResponse.Name)) { }
+
+        public HttpResult(FileInfo fileResponse, bool asAttachment, string contentType)
+            : this(null, contentType, HttpStatusCode.OK)
+        {
+            this.FileInfo = fileResponse;
+
+            if (!asAttachment) return;
+
+            var headerValue =
+                "attachment; " +
+                "filename=\"" + fileResponse.Name + "\"; " +
+                "size=" + fileResponse.Length + "; " +
+                "creation-date=" + fileResponse.CreationTimeUtc.ToString("R").Replace(",", "") + "; " +
+                "modification-date=" + fileResponse.LastWriteTimeUtc.ToString("R").Replace(",", "") + "; " +
+                "read-date=" + fileResponse.LastAccessTimeUtc.ToString("R").Replace(",", "");
+
+            this.Headers = new Dictionary<string, string> {
+                { HttpHeaders.ContentDisposition, headerValue },
+            };
+        }
+
+        public HttpResult(Stream responseStream, string contentType)
+            : this(null, contentType, HttpStatusCode.OK)
+        {
+            this.ResponseStream = responseStream;
+        }
+
+        public HttpResult(string responseText, string contentType)
+            : this(null, contentType, HttpStatusCode.OK)
+        {
+            this.ResponseText = responseText;
+        }
+
+        public string ResponseText { get; private set; }
+
+        public Stream ResponseStream { get; private set; }
+
+        public FileInfo FileInfo { get; private set; }
+
+        public string ContentType { get; set; }
+
+        public Dictionary<string, string> Headers { get; private set; }
+
+        public DateTime LastModified
+        {
+            set
+            {
+                this.Headers[HttpHeaders.LastModified] = value.ToUniversalTime().ToString("r");
+            }
+        }
+
+        public string Location
+        {
+            set
+            {
+                if (StatusCode == HttpStatusCode.OK)
+                    StatusCode = HttpStatusCode.Redirect;
+
+                this.Headers[HttpHeaders.Location] = value;
+            }
+        }
+
+        public void SetPermanentCookie(string name, string value)
+        {
+            SetCookie(name, value, DateTime.UtcNow.AddYears(20), null);
+        }
+
+        public void SetPermanentCookie(string name, string value, string path)
+        {
+            SetCookie(name, value, DateTime.UtcNow.AddYears(20), path);
+        }
+
+        public void SetSessionCookie(string name, string value)
+        {
+            SetSessionCookie(name, value, null);
+        }
+
+        public void SetSessionCookie(string name, string value, string path)
+        {
+            path = path ?? "/";
+            this.Headers[HttpHeaders.SetCookie] = string.Format("{0}={1};path=" + path, name, value);
+        }
+
+        public void SetCookie(string name, string value, TimeSpan expiresIn, string path)
+        {
+            var expiresAt = DateTime.UtcNow.Add(expiresIn);
+            SetCookie(name, value, expiresAt, path);
+        }
+
+        public void SetCookie(string name, string value, DateTime expiresAt, string path)
+        {
+            path = path ?? "/";
+            var cookie = string.Format("{0}={1};expires={2};path={3}", name, value, expiresAt.ToString("R"), path);
+            this.Headers[HttpHeaders.SetCookie] = cookie;
+        }
+
+        public void DeleteCookie(string name)
+        {
+            var cookie = string.Format("{0}=;expires={1};path=/", name, DateTime.UtcNow.AddDays(-1).ToString("R"));
+            this.Headers[HttpHeaders.SetCookie] = cookie;
+        }
+
+        public IDictionary<string, string> Options
+        {
+            get { return this.Headers; }
+        }
+
+        public int Status { get; set; }
+
+        public HttpStatusCode StatusCode
+        {
+            get { return (HttpStatusCode) Status; }
+            set { Status = (int) value; }
+        }
+
+        public string StatusDescription { get; set; }
+
+        public object Response { get; set; }
+
+        public IContentTypeWriter ResponseFilter { get; set; }
+
+        public IRequestContext RequestContext { get; set; }
+
+        public string View { get; set; }
+
+        public string Template { get; set; }
+
+        public void WriteTo(Stream responseStream)
+        {
+            if (this.FileInfo != null)
+            {
+                using (var fs = this.FileInfo.OpenRead())
+                {
+                    fs.WriteTo(responseStream);
+                    responseStream.Flush();
+                }
+                return;
+            }
+
+            if (this.ResponseStream != null)
+            {
+                this.ResponseStream.WriteTo(responseStream);
+                responseStream.Flush();
+                try
+                {
+                    this.ResponseStream.Dispose();
+                }
+                catch { /*ignore*/ }
+
+                return;
+            }
+
+            if (this.ResponseText != null)
+            {
+                var bytes = System.Text.Encoding.UTF8.GetBytes(this.ResponseText);
+                responseStream.Write(bytes, 0, bytes.Length);
+                responseStream.Flush();
+                return;
+            }
+
+            if (this.ResponseFilter == null)
+                throw new ArgumentNullException("ResponseFilter");
+            if (this.RequestContext == null)
+                throw new ArgumentNullException("RequestContext");
+
+            var bytesResponse = this.Response as byte[];
+            if (bytesResponse != null)
+            {
+                responseStream.Write(bytesResponse, 0, bytesResponse.Length);
+                return;
+            }
+
+            if (View != null)
+                RequestContext.SetItem("View", View);
+            if (Template != null)
+                RequestContext.SetItem("Template", Template);
+
+            ResponseFilter.SerializeToStream(this.RequestContext, this.Response, responseStream);
+        }
+
+        public static HttpResult Status201Created(object response, string newLocationUri)
+        {
+            return new HttpResult(response) {
+                StatusCode = HttpStatusCode.Created,
+                Headers =
+                {
+                    { HttpHeaders.Location, newLocationUri },
+                }
+            };
+        }
+    }
+}
+#endif
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Web/HttpResultExtensions.cs b/lib/ServiceStack/src/ServiceStack.Common/Web/HttpResultExtensions.cs
new file mode 100644
index 0000000..55222d6
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Web/HttpResultExtensions.cs
@@ -0,0 +1,80 @@
+using System;
+using ServiceStack.Common.Utils;
+using ServiceStack.ServiceHost;
+using ServiceStack.ServiceInterface.ServiceModel;
+
+namespace ServiceStack.Common.Web
+{
+    public static class HttpResultExtensions
+    {
+        /// <summary>
+        /// Shortcut to get the ResponseDTO whether it's bare or inside a IHttpResult
+        /// </summary>
+        /// <param name="response"></param>
+        /// <returns></returns>
+        public static object ToDto(this object response)
+        {
+            if (response == null) return null;
+            var httpResult = response as IHttpResult;
+            return httpResult != null ? httpResult.Response : response;
+        }
+
+        /// <summary>
+        /// Alias of ToDto
+        /// </summary>
+        public static object ToResponseDto(this object response)
+        {
+            return ToDto(response);
+        }
+
+        /// <summary>
+        /// Shortcut to get the ResponseDTO whether it's bare or inside a IHttpResult
+        /// </summary>
+        /// <param name="response"></param>
+        /// <returns>TResponse if found; otherwise null</returns>
+        public static TResponse ToDto<TResponse>(this object response) where TResponse : class
+        {
+            if (response == null) return default(TResponse);
+            var httpResult = response as IHttpResult;
+            return (httpResult != null ? httpResult.Response : response) as TResponse;
+        }
+
+        /// <summary>
+        /// Alias of ToDto
+        /// </summary>
+        public static TResponse ToResponseDto<TResponse>(this object response) where TResponse : class
+        {
+            return ToDto<TResponse>(response);
+        }
+
+        /// <summary>
+        /// Shortcut to get the ResponseStatus whether it's bare or inside a IHttpResult
+        /// </summary>
+        /// <param name="response"></param>
+        /// <returns></returns>
+        public static ResponseStatus ToResponseStatus(this object response)
+        {
+            if (response == null) return null;
+
+            var hasResponseStatus = response as IHasResponseStatus;
+            if (hasResponseStatus != null)
+                return hasResponseStatus.ResponseStatus;
+
+            var propertyInfo = response.GetType().GetProperty("ResponseStatus");
+            if (propertyInfo == null)
+                return null;
+
+            return ReflectionUtils.GetProperty(response, propertyInfo) as ResponseStatus;
+        }
+
+        /// <summary>
+        /// Whether the response is an IHttpError or Exception
+        /// </summary>
+        /// <param name="response"></param>
+        /// <returns></returns>
+        public static bool IsErrorResponse(this object response)
+        {
+            return response != null && (response is IHttpError || response is Exception);
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Web/MimeTypes.cs b/lib/ServiceStack/src/ServiceStack.Common/Web/MimeTypes.cs
new file mode 100644
index 0000000..6901020
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Web/MimeTypes.cs
@@ -0,0 +1,117 @@
+using System;
+using System.Collections.Generic;
+
+namespace ServiceStack.Common.Web
+{
+    public static class MimeTypes
+    {
+        public static Dictionary<string,string> ExtensionMimeTypes = new Dictionary<string, string>();
+
+        public const string Html = "text/html";
+        public const string Xml = "text/xml";
+        public const string Json = "text/json";
+        public const string Jsv = "text/jsv";
+        public const string Csv = "text/csv";
+        public const string ProtoBuf = "application/x-protobuf";
+
+        public const string JavaScript = "text/javascript";
+
+        public static string GetExtension(string mimeType)
+        {
+            switch (mimeType)
+            {
+                case ProtoBuf:
+                    return ".pbuf";
+            }
+
+            var parts = mimeType.Split('/');
+            if (parts.Length == 1) return "." + parts[0];
+            if (parts.Length == 2) return "." + parts[1];
+
+            throw new NotSupportedException("Unknown mimeType: " + mimeType);
+        }
+
+        public static string GetMimeType(string fileNameOrExt)
+        {
+            fileNameOrExt.ThrowIfNullOrEmpty();
+            var parts = fileNameOrExt.Split('.');
+            var fileExt = parts[parts.Length - 1];
+
+            string mimeType;
+            if (ExtensionMimeTypes.TryGetValue(fileExt, out mimeType))
+            {
+                return mimeType;
+            }
+
+            switch (fileExt)
+            {
+                case "jpeg":
+                case "gif":
+                case "png":
+                case "tiff":
+                case "bmp":
+                    return "image/" + fileExt;
+
+                case "jpg":
+                    return "image/jpeg";
+
+                case "tif":
+                    return "image/tiff";
+
+                case "htm":
+                case "html":
+                case "shtml":
+                    return "text/html";
+
+                case "js":
+                    return "text/javascript";
+
+                case "csv":
+                case "css":
+                case "sgml":
+                    return "text/" + fileExt;
+
+                case "txt":
+                    return "text/plain";
+
+                case "wav":
+                    return "audio/wav";
+
+                case "mp3":
+                    return "audio/mpeg3";
+
+                case "mid":
+                    return "audio/midi";
+
+                case "qt":
+                case "mov":
+                    return "video/quicktime";
+
+                case "mpg":
+                    return "video/mpeg";
+
+                case "avi":
+                    return "video/" + fileExt;
+
+                case "rtf":
+                    return "application/" + fileExt;
+
+                case "xls":
+                    return "application/x-excel";
+
+                case "doc":
+                    return "application/msword";
+
+                case "ppt":
+                    return "application/powerpoint";
+
+                case "gz":
+                case "tgz":
+                    return "application/x-compressed";
+
+                default:
+                    return "application/" + fileExt;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Common/Web/SerializationContext.cs b/lib/ServiceStack/src/ServiceStack.Common/Web/SerializationContext.cs
new file mode 100644
index 0000000..61b213c
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Common/Web/SerializationContext.cs
@@ -0,0 +1,70 @@
+using System;
+using System.Collections.Generic;
+using System.Net;
+using ServiceStack.ServiceHost;
+
+namespace ServiceStack.Common.Web
+{
+    public class SerializationContext : IRequestContext
+    {
+        public SerializationContext(string contentType)
+        {
+            this.ResponseContentType = this.ContentType = contentType;
+        }
+
+        public T Get<T>() where T : class
+        {
+            return default(T);
+        }
+
+        public string GetHeader(string headerName)
+        {
+            return null;
+        }
+
+        public string IpAddress
+        {
+            get { throw new NotImplementedException(); }
+        }
+
+        public IDictionary<string, System.Net.Cookie> Cookies
+        {
+            get { return new Dictionary<string, System.Net.Cookie>(); }
+        }
+
+        public EndpointAttributes EndpointAttributes
+        {
+            get { return EndpointAttributes.None; }
+        }
+
+        public IRequestAttributes RequestAttributes
+        {
+            get { throw new NotImplementedException(); }
+        }
+
+        public string ContentType { get; set; }
+
+        public string ResponseContentType { get; set; }
+
+        public string CompressionType { get; set; }
+
+        public string AbsoluteUri
+        {
+            get { throw new NotImplementedException(); }
+        }
+
+        public string PathInfo
+        {
+            get { throw new NotImplementedException(); }
+        }
+
+        public IFile[] Files
+        {
+            get { return new IFile[0]; }
+        }
+
+        public void Dispose()
+        {
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/ICacheClearable.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/ICacheClearable.cs
new file mode 100644
index 0000000..e2fe138
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/ICacheClearable.cs
@@ -0,0 +1,11 @@
+using System.Collections.Generic;
+
+namespace ServiceStack.CacheAccess
+{
+	public interface ICacheClearable
+	{
+		void Clear(IEnumerable<string> cacheKeys);
+
+		void Clear(params string[] cacheKeys);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/ICacheClient.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/ICacheClient.cs
new file mode 100644
index 0000000..03af550
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/ICacheClient.cs
@@ -0,0 +1,113 @@
+using System;
+using System.Collections.Generic;
+
+namespace ServiceStack.CacheAccess
+{
+	/// <summary>
+	/// A common interface implementation that is implemeneted by most cache providers
+	/// </summary>
+	public interface ICacheClient 
+		: IDisposable
+	{
+		/// <summary>
+		/// Removes the specified item from the cache.
+		/// </summary>
+		/// <param name="key">The identifier for the item to delete.</param>
+		/// <returns>
+		/// true if the item was successfully removed from the cache; false otherwise.
+		/// </returns>
+		bool Remove(string key);
+
+		/// <summary>
+		/// Removes the cache for all the keys provided.
+		/// </summary>
+		/// <param name="keys">The keys.</param>
+		void RemoveAll(IEnumerable<string> keys);
+
+		/// <summary>
+		/// Retrieves the specified item from the cache.
+		/// </summary>
+		/// <typeparam name="T"></typeparam>
+		/// <param name="key">The identifier for the item to retrieve.</param>
+		/// <returns>
+		/// The retrieved item, or <value>null</value> if the key was not found.
+		/// </returns>
+		T Get<T>(string key);
+
+		/// <summary>
+		/// Increments the value of the specified key by the given amount. 
+		/// The operation is atomic and happens on the server.
+		/// A non existent value at key starts at 0
+		/// </summary>
+		/// <param name="key">The identifier for the item to increment.</param>
+		/// <param name="amount">The amount by which the client wants to increase the item.</param>
+		/// <returns>
+		/// The new value of the item or -1 if not found.
+		/// </returns>
+		/// <remarks>The item must be inserted into the cache before it can be changed. The item must be inserted as a <see cref="T:System.String"/>. The operation only works with <see cref="System.UInt32"/> values, so -1 always indicates that the item was not found.</remarks>
+		long Increment(string key, uint amount);
+
+		/// <summary>
+		/// Increments the value of the specified key by the given amount. 
+		/// The operation is atomic and happens on the server.
+		/// A non existent value at key starts at 0
+		/// </summary>
+		/// <param name="key">The identifier for the item to increment.</param>
+		/// <param name="amount">The amount by which the client wants to decrease the item.</param>
+		/// <returns>
+		/// The new value of the item or -1 if not found.
+		/// </returns>
+		/// <remarks>The item must be inserted into the cache before it can be changed. The item must be inserted as a <see cref="T:System.String"/>. The operation only works with <see cref="System.UInt32"/> values, so -1 always indicates that the item was not found.</remarks>
+		long Decrement(string key, uint amount);
+
+		/// <summary>
+		/// Adds a new item into the cache at the specified cache key only if the cache is empty.
+		/// </summary>
+		/// <param name="key">The key used to reference the item.</param>
+		/// <param name="value">The object to be inserted into the cache.</param>
+		/// <returns>
+		/// true if the item was successfully stored in the cache; false otherwise.
+		/// </returns>
+		/// <remarks>The item does not expire unless it is removed due memory pressure.</remarks>
+		bool Add<T>(string key, T value);
+
+		/// <summary>
+		/// Sets an item into the cache at the cache key specified regardless if it already exists or not.
+		/// </summary>
+		bool Set<T>(string key, T value);
+
+		/// <summary>
+		/// Replaces the item at the cachekey specified only if an items exists at the location already. 
+		/// </summary>
+		bool Replace<T>(string key, T value);
+
+		bool Add<T>(string key, T value, DateTime expiresAt);
+		bool Set<T>(string key, T value, DateTime expiresAt);
+		bool Replace<T>(string key, T value, DateTime expiresAt);
+
+		bool Add<T>(string key, T value, TimeSpan expiresIn);
+		bool Set<T>(string key, T value, TimeSpan expiresIn);
+		bool Replace<T>(string key, T value, TimeSpan expiresIn);
+
+		/// <summary>
+		/// Invalidates all data on the cache.
+		/// </summary>
+		void FlushAll();
+
+		/// Retrieves multiple items from the cache. 
+		/// The default value of T is set for all keys that do not exist.
+		/// </summary>
+		/// <param name="keys">The list of identifiers for the items to retrieve.</param>
+		/// <returns>
+		/// a Dictionary holding all items indexed by their key.
+		/// </returns>
+		IDictionary<string, T> GetAll<T>(IEnumerable<string> keys);
+
+		/// <summary>
+		/// Sets multiple items to the cache. 
+		/// </summary>
+		/// <typeparam name="T"></typeparam>
+		/// <param name="values">The values.</param>
+		void SetAll<T>(IDictionary<string, T> values);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/ICacheHasContentType.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/ICacheHasContentType.cs
new file mode 100644
index 0000000..fd344d3
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/ICacheHasContentType.cs
@@ -0,0 +1,7 @@
+namespace ServiceStack.CacheAccess
+{
+	public interface ICacheHasContentType
+	{
+		string ContentType { get; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/ICacheManager.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/ICacheManager.cs
new file mode 100644
index 0000000..67286f5
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/ICacheManager.cs
@@ -0,0 +1,14 @@
+using System;
+
+namespace ServiceStack.CacheAccess
+{
+	public interface ICacheManager
+		: ICacheClearable, IHasCacheClient
+	{
+		T Resolve<T>(string cacheKey, Func<T> createCacheFn)
+			where T : class;
+
+		T Resolve<T>(string cacheKey, TimeSpan expireIn, Func<T> createCacheFn)
+			where T : class;
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/ICacheTextManager.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/ICacheTextManager.cs
new file mode 100644
index 0000000..2a14460
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/ICacheTextManager.cs
@@ -0,0 +1,16 @@
+using System;
+
+namespace ServiceStack.CacheAccess
+{
+	public interface ICacheTextManager 
+		: IHasCacheClient, ICacheClearable
+	{
+		string ContentType { get; }
+
+		string ResolveText<T>(string cacheKey, Func<T> createCacheFn)
+			where T : class;
+
+		string ResolveText<T>(string cacheKey, TimeSpan expiresIn, Func<T> createCacheFn)
+			where T : class;
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/ICacheTextManagerFactory.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/ICacheTextManagerFactory.cs
new file mode 100644
index 0000000..903ffb3
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/ICacheTextManagerFactory.cs
@@ -0,0 +1,7 @@
+namespace ServiceStack.CacheAccess
+{
+	public interface ICacheTextManagerFactory
+	{
+		ICacheTextManager Resolve(string contentType);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/ICompressableCacheTextManager.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/ICompressableCacheTextManager.cs
new file mode 100644
index 0000000..2bcc8e3
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/ICompressableCacheTextManager.cs
@@ -0,0 +1,11 @@
+using System;
+
+namespace ServiceStack.CacheAccess
+{
+	public interface ICompressableCacheTextManager
+		: IHasCacheClient, ICacheHasContentType, ICacheClearable
+	{
+		object Resolve<T>(string compressionType, string cacheKey, Func<T> createCacheFn) 
+			where T : class;
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/ICompressableCacheTextManagerFactory.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/ICompressableCacheTextManagerFactory.cs
new file mode 100644
index 0000000..a201573
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/ICompressableCacheTextManagerFactory.cs
@@ -0,0 +1,7 @@
+namespace ServiceStack.CacheAccess
+{
+	public interface ICompressableCacheTextManagerFactory
+	{
+		ICompressableCacheTextManager Resolve(string contentType);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/IDeflateProvider.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/IDeflateProvider.cs
new file mode 100644
index 0000000..a6e9330
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/IDeflateProvider.cs
@@ -0,0 +1,9 @@
+namespace ServiceStack.CacheAccess
+{
+	public interface IDeflateProvider
+	{
+		byte[] Deflate(string text);
+		
+		string Inflate(byte[] gzBuffer);
+	}
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/IGZipProvider.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/IGZipProvider.cs
new file mode 100644
index 0000000..9208591
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/IGZipProvider.cs
@@ -0,0 +1,9 @@
+namespace ServiceStack.CacheAccess
+{
+	public interface IGZipProvider
+	{
+		byte[] GZip(string text);
+
+		string GUnzip(byte[] gzBuffer);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/IHasCacheClient.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/IHasCacheClient.cs
new file mode 100644
index 0000000..c0da2b0
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/IHasCacheClient.cs
@@ -0,0 +1,7 @@
+namespace ServiceStack.CacheAccess
+{
+	public interface IHasCacheClient
+	{
+		ICacheClient CacheClient { get; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/IMemcachedClient.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/IMemcachedClient.cs
new file mode 100644
index 0000000..081886a
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/IMemcachedClient.cs
@@ -0,0 +1,107 @@
+using System;
+using System.Collections.Generic;
+
+namespace ServiceStack.CacheAccess
+{
+	/// <summary>
+	/// A light interface over a cache client.
+	/// This interface was inspired by Enyim.Caching.MemcachedClient
+	/// 
+	/// Only the methods that are intended to be used are required, if you require
+	/// extra functionality you can uncomment the unused methods below as they have been
+	/// implemented in DdnMemcachedClient
+	/// </summary>
+	public interface IMemcachedClient : IDisposable
+	{
+		/// <summary>
+		/// Removes the specified item from the cache.
+		/// </summary>
+		/// <param name="key">The identifier for the item to delete.</param>
+		/// <returns>
+		/// true if the item was successfully removed from the cache; false otherwise.
+		/// </returns>
+		bool Remove(string key);
+
+		/// <summary>
+		/// Removes the cache for all the keys provided.
+		/// </summary>
+		/// <param name="keys">The keys.</param>
+		void RemoveAll(IEnumerable<string> keys);
+
+		/// <summary>
+		/// Retrieves the specified item from the cache.
+		/// </summary>
+		/// <param ICTname="key">The identifier for the item to retrieve.</param>
+		/// <returns>
+		/// The retrieved item, or <value>null</value> if the key was not found.
+		/// </returns>
+		object Get(string key);
+		object Get(string key, out ulong lastModifiedValue);
+
+		/// <summary>
+		/// Increments the value of the specified key by the given amount. The operation is atomic and happens on the server.
+		/// </summary>
+		/// <param name="key">The identifier for the item to increment.</param>
+		/// <param name="amount">The amount by which the client wants to increase the item.</param>
+		/// <returns>
+		/// The new value of the item or -1 if not found.
+		/// </returns>
+		/// <remarks>The item must be inserted into the cache before it can be changed. The item must be inserted as a <see cref="T:System.String"/>. The operation only works with <see cref="System.UInt32"/> values, so -1 always indicates that the item was not found.</remarks>
+		long Increment(string key, uint amount);
+
+		/// <summary>
+		/// Increments the value of the specified key by the given amount. The operation is atomic and happens on the server.
+		/// </summary>
+		/// <param name="key">The identifier for the item to increment.</param>
+		/// <param name="amount">The amount by which the client wants to decrease the item.</param>
+		/// <returns>
+		/// The new value of the item or -1 if not found.
+		/// </returns>
+		/// <remarks>The item must be inserted into the cache before it can be changed. The item must be inserted as a <see cref="T:System.String"/>. The operation only works with <see cref="System.UInt32"/> values, so -1 always indicates that the item was not found.</remarks>
+		long Decrement(string key, uint amount);
+
+		/// <summary>
+		/// Inserts an item into the cache with a cache key to reference its location.
+		/// </summary>
+		/// <param name="key">The key used to reference the item.</param>
+		/// <param name="value">The object to be inserted into the cache.</param>
+		/// <returns>
+		/// true if the item was successfully stored in the cache; false otherwise.
+		/// </returns>
+		/// <remarks>The item does not expire unless it is removed due memory pressure.</remarks>
+		bool Add(string key, object value);
+		bool Set(string key, object value);
+		bool Replace(string key, object value);
+
+		/// <summary>
+		/// Inserts an item into the cache with a cache key to reference its location.
+		/// </summary>
+		/// <param name="key">The key used to reference the item.</param>
+		/// <param name="value">The object to be inserted into the cache.</param>
+		/// <param name="expiresAt">The time when the item is invalidated in the cache.</param>
+		/// <returns>true if the item was successfully stored in the cache; false otherwise.</returns>
+		bool Add(string key, object value, DateTime expiresAt);
+		bool Set(string key, object value, DateTime expiresAt);
+		bool Replace(string key, object value, DateTime expiresAt);
+
+		/// <summary>
+		/// Removes all data from the cache.
+		/// </summary>
+		void FlushAll();
+
+		/// <summary>
+		/// Retrieves multiple items from the cache.
+		/// </summary>
+		/// <param name="keys">The list of identifiers for the items to retrieve.</param>
+		/// <returns>
+		/// a Dictionary holding all items indexed by their key.
+		/// </returns>
+		IDictionary<string, object> GetAll(IEnumerable<string> keys);
+
+		bool CheckAndSet(string key, object value, ulong lastModifiedValue);
+
+		bool CheckAndSet(string key, object value, ulong lastModifiedValue, DateTime expiresAt);
+
+		IDictionary<string, object> GetAll(IEnumerable<string> keys, out IDictionary<string, ulong> lastModifiedValues);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/IPersistenceProviderCache.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/IPersistenceProviderCache.cs
new file mode 100644
index 0000000..8857501
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/IPersistenceProviderCache.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace ServiceStack.CacheAccess
+{
+	public interface IPersistenceProviderCache
+	{
+		TEntity GetById<TEntity>(object entityId)
+			where TEntity : class, new();
+
+		List<TEntity> GetByIds<TEntity>(ICollection entityIds)
+			where TEntity : class, new();
+
+		void SetCache<TEntity>(TEntity entity)
+			where TEntity : class, new();
+
+		void Store<TEntity>(TEntity entity)
+			where TEntity : class, new();
+
+		void StoreAll<TEntity>(params TEntity[] entities)
+			where TEntity : class, new();
+
+		void ClearAll<TEntity>(ICollection entityIds)
+			where TEntity : class, new();
+
+		void Clear<TEntity>(params object[] entityIds)
+			where TEntity : class, new();
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/IPersistenceProviderCacheFactory.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/IPersistenceProviderCacheFactory.cs
new file mode 100644
index 0000000..1034d39
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/IPersistenceProviderCacheFactory.cs
@@ -0,0 +1,11 @@
+using ServiceStack.DataAccess;
+
+namespace ServiceStack.CacheAccess
+{
+	public interface IPersistenceProviderCacheFactory
+	{
+		IPersistenceProviderCache Create(IPersistenceProviderManager providerManager);
+		
+		IPersistenceProviderCache Create(string conntectionString);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/ISession.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/ISession.cs
new file mode 100644
index 0000000..4c3942a
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/ISession.cs
@@ -0,0 +1,31 @@
+namespace ServiceStack.CacheAccess
+{
+	/// <summary>
+	/// A Users Session
+	/// </summary>
+	public interface ISession
+	{
+		/// <summary>
+		/// Store any object at key
+		/// </summary>
+		/// <param name="key"></param>
+		/// <returns></returns>
+		object this[string key] { get; set; }
+
+		/// <summary>
+		/// Set a typed value at key
+		/// </summary>
+		/// <typeparam name="T"></typeparam>
+		/// <param name="key"></param>
+		/// <param name="value"></param>
+		void Set<T>(string key, T value);
+		
+		/// <summary>
+		/// Get a typed value at key
+		/// </summary>
+		/// <typeparam name="T"></typeparam>
+		/// <param name="key"></param>
+		/// <returns></returns>
+		T Get<T>(string key);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/ISessionFactory.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/ISessionFactory.cs
new file mode 100644
index 0000000..357f60e
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/CacheAccess/ISessionFactory.cs
@@ -0,0 +1,26 @@
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+using ServiceStack.ServiceHost;
+
+namespace ServiceStack.CacheAccess
+{
+	/// <summary>
+	/// Retrieves a User Session
+	/// </summary>
+	public interface ISessionFactory
+	{
+		/// <summary>
+		/// Gets the session for this request, creates one if it doesn't exist.
+		/// </summary>
+		/// <param name="httpReq"></param>
+		/// <param name="httpRes"></param>
+		/// <returns></returns>
+		ISession GetOrCreateSession(IHttpRequest httpReq, IHttpResponse httpRes);
+
+		/// <summary>
+		/// Gets the session for this request, creates one if it doesn't exist.
+		/// Only for ASP.NET apps. Uses the HttpContext.Current singleton.
+		/// </summary>
+		ISession GetOrCreateSession();
+	}
+}
+#endif
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Configuration/IContainerAdapter.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Configuration/IContainerAdapter.cs
new file mode 100644
index 0000000..1977ea2
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Configuration/IContainerAdapter.cs
@@ -0,0 +1,22 @@
+namespace ServiceStack.Configuration
+{
+	/// <summary>
+	/// Allow delegation of dependencies to other IOC's
+	/// </summary>
+	public interface IContainerAdapter
+	{
+		/// <summary>
+		/// Resolve Property Dependency
+		/// </summary>
+		/// <typeparam name="T"></typeparam>
+		/// <returns></returns>
+		T TryResolve<T>();
+
+		/// <summary>
+		/// Resolve Constructor Dependency
+		/// </summary>
+		/// <typeparam name="T"></typeparam>
+		/// <returns></returns>
+		T Resolve<T>();
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Configuration/IFactoryProvider.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Configuration/IFactoryProvider.cs
new file mode 100644
index 0000000..3da07f0
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Configuration/IFactoryProvider.cs
@@ -0,0 +1,16 @@
+using System;
+
+namespace ServiceStack.Configuration
+{
+	public interface IFactoryProvider 
+		: IContainerAdapter, IDisposable
+	{
+		void Register<T>(T provider);
+
+		T Resolve<T>(string name);
+
+		T ResolveOptional<T>(string name, T defaultValue);
+
+		T Create<T>(string name);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Configuration/IRelease.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Configuration/IRelease.cs
new file mode 100644
index 0000000..ac1bc5b
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Configuration/IRelease.cs
@@ -0,0 +1,7 @@
+namespace ServiceStack.Configuration
+{
+    public interface IRelease
+    {
+        void Release(object instance);
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Configuration/IResourceManager.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Configuration/IResourceManager.cs
new file mode 100644
index 0000000..90de282
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Configuration/IResourceManager.cs
@@ -0,0 +1,15 @@
+using System.Collections.Generic;
+
+namespace ServiceStack.Configuration
+{
+	public interface IResourceManager
+	{
+		string GetString(string name);
+
+		IList<string> GetList(string key);
+
+		IDictionary<string, string> GetDictionary(string key);
+
+		T Get<T>(string name, T defaultValue);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Configuration/ITypeFactory.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Configuration/ITypeFactory.cs
new file mode 100644
index 0000000..7bab54b
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Configuration/ITypeFactory.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace ServiceStack.Configuration
+{
+	public interface ITypeFactory
+	{
+		object CreateInstance(Type type);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/Criteria/ICriteria.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/Criteria/ICriteria.cs
new file mode 100644
index 0000000..8a9fd3b
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/Criteria/ICriteria.cs
@@ -0,0 +1,6 @@
+namespace ServiceStack.DataAccess.Criteria
+{
+	public interface ICriteria
+	{
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/Criteria/IOrderAscendingCriteria.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/Criteria/IOrderAscendingCriteria.cs
new file mode 100644
index 0000000..5d158eb
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/Criteria/IOrderAscendingCriteria.cs
@@ -0,0 +1,7 @@
+namespace ServiceStack.DataAccess.Criteria
+{
+	public interface IOrderAscendingCriteria : ICriteria
+	{
+		string OrderedAscendingBy { get; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/Criteria/IOrderDescendingCriteria.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/Criteria/IOrderDescendingCriteria.cs
new file mode 100644
index 0000000..02a2caf
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/Criteria/IOrderDescendingCriteria.cs
@@ -0,0 +1,7 @@
+namespace ServiceStack.DataAccess.Criteria
+{
+	public interface IOrderDescendingCriteria : ICriteria
+	{
+		string OrderedDescendingBy { get; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/Criteria/IPagingCriteria.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/Criteria/IPagingCriteria.cs
new file mode 100644
index 0000000..188de7e
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/Criteria/IPagingCriteria.cs
@@ -0,0 +1,8 @@
+namespace ServiceStack.DataAccess.Criteria
+{
+	public interface IPagingCriteria : ICriteria
+	{
+		uint ResultOffset { get; }
+		uint ResultLimit { get; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/Criteria/PagingCriteria.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/Criteria/PagingCriteria.cs
new file mode 100644
index 0000000..3bba8b0
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/Criteria/PagingCriteria.cs
@@ -0,0 +1,14 @@
+namespace ServiceStack.DataAccess.Criteria
+{
+	public class PagingCriteria : IPagingCriteria
+	{
+		public uint ResultOffset { get; private set; }
+		public uint ResultLimit { get; private set; }
+
+		public PagingCriteria(uint resultOffset, uint resultLimit)
+		{
+			this.ResultOffset = resultOffset;
+			this.ResultLimit = resultLimit;
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/DataAccessException.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/DataAccessException.cs
new file mode 100644
index 0000000..4223c08
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/DataAccessException.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Runtime.Serialization;
+
+namespace ServiceStack.DataAccess
+{
+	public class DataAccessException : Exception
+	{
+		public DataAccessException()
+		{
+		}
+
+		public DataAccessException(string message) 
+			: base(message)
+		{
+		}
+
+		public DataAccessException(string message, Exception innerException) 
+			: base(message, innerException)
+		{
+		}
+
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+		protected DataAccessException(SerializationInfo info, StreamingContext context) 
+			: base(info, context)
+		{
+		}
+#endif
+
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IAggregatable.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IAggregatable.cs
new file mode 100644
index 0000000..ff33d91
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IAggregatable.cs
@@ -0,0 +1,11 @@
+namespace ServiceStack.DataAccess
+{
+	public interface IAggregatable
+	{
+		double GetAvg<T>(T entity, string fieldName);
+		long GetCount<T>(T entity, string fieldName);
+		T GetMin<T>(T entity, string fieldName);
+		T GetMax<T>(T entity, string fieldName);
+		long GetSum<T>(T entity, string fieldName);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IBasicPersistenceProvider.Generic.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IBasicPersistenceProvider.Generic.cs
new file mode 100644
index 0000000..d7d0062
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IBasicPersistenceProvider.Generic.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace ServiceStack.DataAccess
+{
+	/// <summary>
+	/// For providers that want a cleaner API with a little more perf
+	/// </summary>
+	/// <typeparam name="T"></typeparam>
+	public interface IBasicPersistenceProvider<T> 
+		: IDisposable
+	{
+		T GetById(object id);
+
+		IList<T> GetByIds(IEnumerable ids);
+
+		IList<T> GetAll();
+
+		T Store(T entity);
+
+		void StoreAll(IEnumerable<T> entities);
+
+		void Delete(T entity);
+
+		void DeleteById(object id);
+
+		void DeleteByIds(IEnumerable ids);
+
+		void DeleteAll();
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IBasicPersistenceProvider.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IBasicPersistenceProvider.cs
new file mode 100644
index 0000000..4aacf5e
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IBasicPersistenceProvider.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace ServiceStack.DataAccess
+{
+	public interface IBasicPersistenceProvider : IDisposable
+	{
+		T GetById<T>(object id)
+			where T : class, new();
+	
+		IList<T> GetByIds<T>(ICollection ids) 
+			where T : class, new();
+
+		T Store<T>(T entity)
+			where T : class, new();
+
+		void StoreAll<TEntity>(IEnumerable<TEntity> entities)
+			where TEntity : class, new();
+
+		void Delete<T>(T entity)
+			where T : class, new();
+
+		void DeleteById<T>(object id)
+			where T : class, new();
+
+		void DeleteByIds<T>(ICollection ids)
+			where T : class, new();
+
+		void DeleteAll<TEntity>()
+			where TEntity : class, new();
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IHasDbConnection.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IHasDbConnection.cs
new file mode 100644
index 0000000..7b11e6e
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IHasDbConnection.cs
@@ -0,0 +1,11 @@
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+using System.Data;
+
+namespace ServiceStack.DataAccess
+{
+	public interface IHasDbConnection
+	{
+		IDbConnection DbConnection { get; }
+	}
+}
+#endif
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IPersistenceProvider.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IPersistenceProvider.cs
new file mode 100644
index 0000000..a235eea
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IPersistenceProvider.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace ServiceStack.DataAccess
+{
+	public interface IPersistenceProvider : IBasicPersistenceProvider, IDisposable
+	{
+		IList<T> GetAll<T>()
+			where T : class, new();
+
+		IList<T> GetAllOrderedBy<T>(string fieldName, bool sortAsc)
+			where T : class, new();
+
+		T FindByValue<T>(string name, object value)
+			where T : class, new();
+
+		IList<T> FindAllByValue<T>(string name, object value)
+			where T : class, new();
+
+		IList<T> FindByValues<T>(string name, ICollection values)
+			where T : class, new();
+
+		void Flush();
+
+		IList<T> StoreAll<T>(IList<T> entities)
+			where T : class, new();
+		
+		void DeleteAll<T>(IList<T> entities)
+			where T : class, new();
+
+		ITransactionContext BeginTransaction();
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IPersistenceProviderManager.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IPersistenceProviderManager.cs
new file mode 100644
index 0000000..e80bcd2
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IPersistenceProviderManager.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace ServiceStack.DataAccess
+{
+	/// <summary>
+	/// Manages a connection to a persistance provider
+	/// </summary>
+	public interface IPersistenceProviderManager : IDisposable
+	{
+		IPersistenceProvider GetProvider();
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IPersistenceProviderManagerFactory.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IPersistenceProviderManagerFactory.cs
new file mode 100644
index 0000000..7df9d70
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IPersistenceProviderManagerFactory.cs
@@ -0,0 +1,7 @@
+namespace ServiceStack.DataAccess
+{
+	public interface IPersistenceProviderManagerFactory
+	{
+		IPersistenceProviderManager CreateProviderManager(string connectionString);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IQueryable.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IQueryable.cs
new file mode 100644
index 0000000..aa1ae5b
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IQueryable.cs
@@ -0,0 +1,12 @@
+using System.Collections.Generic;
+
+namespace ServiceStack.DataAccess
+{
+	public interface IQueryable : IQueryableByExample, IQueryableByPredicate, IQueryableByComparer
+	{
+		//IList<Extent> Query<Extent>();
+		//IList<ElementType> Query<ElementType>(Type extent);
+		//IList<Extent> Query<Extent>(Predicate<Extent> match, IComparer<Extent> comparer);
+		//IList<Extent> Query<Extent>(Predicate<Extent> match, Comparison<Extent> comparison);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IQueryableByComparer.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IQueryableByComparer.cs
new file mode 100644
index 0000000..fd29d06
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IQueryableByComparer.cs
@@ -0,0 +1,9 @@
+using System.Collections.Generic;
+
+namespace ServiceStack.DataAccess
+{
+	public interface IQueryableByComparer
+	{
+		IList<Extent> Query<Extent>(IComparer<Extent> comparer);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IQueryableByExample.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IQueryableByExample.cs
new file mode 100644
index 0000000..5bd75ea
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IQueryableByExample.cs
@@ -0,0 +1,9 @@
+using System.Collections.Generic;
+
+namespace ServiceStack.DataAccess
+{
+	public interface IQueryableByExample
+	{
+		IList<Extent> QueryByExample<Extent>(object template);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IQueryableByPredicate.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IQueryableByPredicate.cs
new file mode 100644
index 0000000..d88f3e6
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IQueryableByPredicate.cs
@@ -0,0 +1,10 @@
+using System;
+using System.Collections.Generic;
+
+namespace ServiceStack.DataAccess
+{
+	public interface IQueryableByPredicate
+	{
+		IList<Extent> Query<Extent>(Predicate<Extent> match);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IQueryablePersistenceProvider.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IQueryablePersistenceProvider.cs
new file mode 100644
index 0000000..8c49082
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IQueryablePersistenceProvider.cs
@@ -0,0 +1,11 @@
+using System.Collections.Generic;
+using ServiceStack.DataAccess.Criteria;
+
+namespace ServiceStack.DataAccess
+{
+	public interface IQueryablePersistenceProvider : IPersistenceProvider, IQueryable
+	{
+		IList<T> GetAll<T>(ICriteria criteria)
+			where T : class, new();
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IResultSet.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IResultSet.cs
new file mode 100644
index 0000000..85aa5ff
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/IResultSet.cs
@@ -0,0 +1,11 @@
+using System.Collections.Generic;
+
+namespace ServiceStack.DataAccess
+{
+	public interface IResultSet<T>
+	{
+		long Offset { get; }
+		long TotalCount { get; }
+		IEnumerable<T> Results { get; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/ITransactionContext.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/ITransactionContext.cs
new file mode 100644
index 0000000..45a1f59
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAccess/ITransactionContext.cs
@@ -0,0 +1,10 @@
+using System;
+
+namespace ServiceStack.DataAccess
+{
+    public interface ITransactionContext : IDisposable
+    {
+        bool Commit();
+        bool Rollback();
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DataAnnotations/AliasAttribute.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAnnotations/AliasAttribute.cs
new file mode 100644
index 0000000..a8fecc7
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAnnotations/AliasAttribute.cs
@@ -0,0 +1,15 @@
+using System;
+
+namespace ServiceStack.DataAnnotations
+{
+	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Class | AttributeTargets.Struct)]
+	public class AliasAttribute : Attribute
+	{
+		public string Name { get; set; }
+
+		public AliasAttribute(string name)
+		{
+			this.Name = name;
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DataAnnotations/AutoIncrementAttribute.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAnnotations/AutoIncrementAttribute.cs
new file mode 100644
index 0000000..3ae5526
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAnnotations/AutoIncrementAttribute.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace ServiceStack.DataAnnotations
+{
+	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
+	public class AutoIncrementAttribute : Attribute
+	{
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DataAnnotations/CompositeIndexAttribute.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAnnotations/CompositeIndexAttribute.cs
new file mode 100644
index 0000000..4553e34
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAnnotations/CompositeIndexAttribute.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+
+namespace ServiceStack.DataAnnotations
+{
+	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
+	public class CompositeIndexAttribute : Attribute
+	{
+		public CompositeIndexAttribute()
+		{
+			this.FieldNames = new List<string>();
+		}
+
+		public CompositeIndexAttribute(params string[] fieldNames)
+		{
+			this.FieldNames = new List<string>(fieldNames);
+		}
+
+		public CompositeIndexAttribute(bool unique, params string[] fieldNames)
+		{
+			this.Unique = unique;
+			this.FieldNames = new List<string>(fieldNames);
+		}
+
+		public List<string> FieldNames { get; set; }
+
+		public bool Unique { get; set; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DataAnnotations/DefaultAttribute.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAnnotations/DefaultAttribute.cs
new file mode 100644
index 0000000..3946fd3
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAnnotations/DefaultAttribute.cs
@@ -0,0 +1,30 @@
+using System;
+
+namespace ServiceStack.DataAnnotations
+{
+	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
+	public class DefaultAttribute : Attribute
+	{
+		public int IntValue { get; set; }
+		public double DoubleValue { get; set; }
+
+		public Type DefaultType { get; set; }
+		public string DefaultValue { get; set; }
+
+		public DefaultAttribute(int intValue)
+		{
+			this.IntValue = intValue;
+		}
+
+		public DefaultAttribute(double doubleValue)
+		{
+			this.DoubleValue = doubleValue;
+		}
+
+		public DefaultAttribute(Type defaultType, string defaultValue)
+		{
+			this.DefaultValue = defaultValue;
+			this.DefaultType = defaultType;
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DataAnnotations/IndexAttribute.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAnnotations/IndexAttribute.cs
new file mode 100644
index 0000000..8fc7445
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAnnotations/IndexAttribute.cs
@@ -0,0 +1,19 @@
+using System;
+
+namespace ServiceStack.DataAnnotations
+{
+	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Class | AttributeTargets.Struct)]
+	public class IndexAttribute : Attribute
+	{
+		public IndexAttribute()
+		{
+		}
+
+		public IndexAttribute(bool unique)
+		{
+			Unique = unique;
+		}
+
+		public bool Unique { get; set; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DataAnnotations/ReferencesAttribute.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAnnotations/ReferencesAttribute.cs
new file mode 100644
index 0000000..9289bbb
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DataAnnotations/ReferencesAttribute.cs
@@ -0,0 +1,15 @@
+using System;
+
+namespace ServiceStack.DataAnnotations
+{
+	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Class | AttributeTargets.Struct)]
+	public class ReferencesAttribute : Attribute
+	{
+		public Type Type { get; set; }
+
+		public ReferencesAttribute(Type type)
+		{
+			this.Type = type;
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Command/ICommand.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Command/ICommand.cs
new file mode 100644
index 0000000..81b3372
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Command/ICommand.cs
@@ -0,0 +1,7 @@
+namespace ServiceStack.DesignPatterns.Command
+{
+    public interface ICommand<ReturnType>
+    {
+        ReturnType Execute();
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Command/ICommandExec.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Command/ICommandExec.cs
new file mode 100644
index 0000000..36949ff
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Command/ICommandExec.cs
@@ -0,0 +1,6 @@
+namespace ServiceStack.DesignPatterns.Command
+{
+    public interface ICommandExec : ICommand<bool>
+    {
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Command/ICommandIEnumerable.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Command/ICommandIEnumerable.cs
new file mode 100644
index 0000000..d685a70
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Command/ICommandIEnumerable.cs
@@ -0,0 +1,8 @@
+using System.Collections.Generic;
+
+namespace ServiceStack.DesignPatterns.Command
+{
+    public interface ICommandIEnumerable<T> : ICommand<IEnumerable<T>>
+    {
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Command/ICommandIList.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Command/ICommandIList.cs
new file mode 100644
index 0000000..7b2a60b
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Command/ICommandIList.cs
@@ -0,0 +1,8 @@
+using System.Collections.Generic;
+
+namespace ServiceStack.DesignPatterns.Command
+{
+    public interface ICommandIList<T> : IList<T>
+    {
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Command/ICommandList.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Command/ICommandList.cs
new file mode 100644
index 0000000..0f07a3c
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Command/ICommandList.cs
@@ -0,0 +1,8 @@
+using System.Collections.Generic;
+
+namespace ServiceStack.DesignPatterns.Command
+{
+    public interface ICommandList<T> : ICommand<List<T>>
+    {
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Command/ICommandVoid.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Command/ICommandVoid.cs
new file mode 100644
index 0000000..2b59d29
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Command/ICommandVoid.cs
@@ -0,0 +1,8 @@
+
+namespace ServiceStack.DesignPatterns.Command
+{
+    public interface ICommandVoid
+    {
+        void Execute();
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Model/IHasGuidId.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Model/IHasGuidId.cs
new file mode 100644
index 0000000..47676a4
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Model/IHasGuidId.cs
@@ -0,0 +1,8 @@
+using System;
+
+namespace ServiceStack.DesignPatterns.Model
+{
+	public interface IHasGuidId : IHasId<Guid>
+	{
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Model/IHasId.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Model/IHasId.cs
new file mode 100644
index 0000000..61eafbb
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Model/IHasId.cs
@@ -0,0 +1,7 @@
+namespace ServiceStack.DesignPatterns.Model
+{
+	public interface IHasId<T>
+	{
+		T Id { get; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Model/IHasIntId.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Model/IHasIntId.cs
new file mode 100644
index 0000000..dc32c51
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Model/IHasIntId.cs
@@ -0,0 +1,6 @@
+namespace ServiceStack.DesignPatterns.Model
+{
+	public interface IHasIntId : IHasId<int>
+	{
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Model/IHasLongId.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Model/IHasLongId.cs
new file mode 100644
index 0000000..1cd37a3
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Model/IHasLongId.cs
@@ -0,0 +1,6 @@
+namespace ServiceStack.DesignPatterns.Model
+{
+	public interface IHasLongId : IHasId<long>
+	{
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Model/IHasNamed.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Model/IHasNamed.cs
new file mode 100644
index 0000000..e5edde0
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Model/IHasNamed.cs
@@ -0,0 +1,7 @@
+namespace ServiceStack.DesignPatterns.Model
+{
+	public interface IHasNamed<T>
+	{
+		T this[string listId] { get; set; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Model/IHasNamedCollection.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Model/IHasNamedCollection.cs
new file mode 100644
index 0000000..3b1f3c8
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Model/IHasNamedCollection.cs
@@ -0,0 +1,8 @@
+using System.Collections.Generic;
+
+namespace ServiceStack.DesignPatterns.Model
+{
+	public interface IHasNamedCollection<T> : IHasNamed<ICollection<T>>
+	{
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Model/IHasNamedList.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Model/IHasNamedList.cs
new file mode 100644
index 0000000..2d03cc8
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Model/IHasNamedList.cs
@@ -0,0 +1,9 @@
+using System;
+using System.Collections.Generic;
+
+namespace ServiceStack.DesignPatterns.Model
+{
+	public interface IHasNamedList<T> : IHasNamed<IList<T>>
+	{
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Model/IHasStringId.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Model/IHasStringId.cs
new file mode 100644
index 0000000..72db68e
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Model/IHasStringId.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace ServiceStack.DesignPatterns.Model
+{
+	public interface IHasStringId : IHasId<string>
+	{
+	}
+
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Model/IHasUserId.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Model/IHasUserId.cs
new file mode 100644
index 0000000..65f0d1f
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Model/IHasUserId.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace ServiceStack.DesignPatterns.Model
+{
+	public interface IHasUserId
+	{
+		Guid UserId { get; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Model/IHasUserSession.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Model/IHasUserSession.cs
new file mode 100644
index 0000000..96b1dc8
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Model/IHasUserSession.cs
@@ -0,0 +1,11 @@
+using System;
+
+namespace ServiceStack.DesignPatterns.Model
+{
+	public interface IHasUserSession
+	{
+		Guid UserId { get; }
+
+		Guid SessionId { get; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Serialization/IStringDeserializer.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Serialization/IStringDeserializer.cs
new file mode 100644
index 0000000..f78ae51
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Serialization/IStringDeserializer.cs
@@ -0,0 +1,10 @@
+using System;
+
+namespace ServiceStack.DesignPatterns.Serialization
+{
+    public interface IStringDeserializer
+    {
+        To Parse<To>(string serializedText);
+        object Parse(string serializedText, Type type);
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Serialization/IStringSerializer.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Serialization/IStringSerializer.cs
new file mode 100644
index 0000000..3da7239
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Serialization/IStringSerializer.cs
@@ -0,0 +1,7 @@
+namespace ServiceStack.DesignPatterns.Serialization
+{
+	public interface IStringSerializer
+	{
+		string Parse<TFrom>(TFrom from);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Serialization/ITextSerializer.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Serialization/ITextSerializer.cs
new file mode 100644
index 0000000..8ad61da
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Serialization/ITextSerializer.cs
@@ -0,0 +1,16 @@
+using System;
+using System.IO;
+
+namespace ServiceStack.DesignPatterns.Serialization
+{
+	public interface ITextSerializer
+	{
+		object DeserializeFromString(string json, Type returnType);
+		T DeserializeFromString<T>(string json);
+		T DeserializeFromStream<T>(Stream stream);
+		object DeserializeFromStream(Type type, Stream stream);
+
+		string SerializeToString<T>(T obj);
+		void SerializeToStream<T>(T obj, Stream stream);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Translator/ITranslator.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Translator/ITranslator.cs
new file mode 100644
index 0000000..c915910
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/DesignPatterns/Translator/ITranslator.cs
@@ -0,0 +1,7 @@
+namespace ServiceStack.DesignPatterns.Translator
+{
+    public interface ITranslator<To, From>
+    {
+        To Parse(From from);
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Logging/ILog.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Logging/ILog.cs
new file mode 100644
index 0000000..1d1135f
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Logging/ILog.cs
@@ -0,0 +1,119 @@
+using System;
+
+namespace ServiceStack.Logging
+{
+    /// <summary>
+    /// Logs a message in a running application
+    /// </summary>
+    public interface ILog 
+    {
+		/// <summary>
+		/// Gets or sets a value indicating whether this instance is debug enabled.
+		/// </summary>
+		/// <value>
+		/// 	<c>true</c> if this instance is debug enabled; otherwise, <c>false</c>.
+		/// </value>
+    	bool IsDebugEnabled { get; }
+        
+		/// <summary>
+        /// Logs a Debug message.
+        /// </summary>
+        /// <param name="message">The message.</param>
+        void Debug(object message);
+
+        /// <summary>
+        /// Logs a Debug message and exception.
+        /// </summary>
+        /// <param name="message">The message.</param>
+        /// <param name="exception">The exception.</param>
+        void Debug(object message, Exception exception);
+
+        /// <summary>
+        /// Logs a Debug format message.
+        /// </summary>
+        /// <param name="format">The format.</param>
+        /// <param name="args">The args.</param>
+        void DebugFormat(string format, params object[] args);
+
+        /// <summary>
+        /// Logs a Error message.
+        /// </summary>
+        /// <param name="message">The message.</param>
+        void Error(object message);
+
+        /// <summary>
+        /// Logs a Error message and exception.
+        /// </summary>
+        /// <param name="message">The message.</param>
+        /// <param name="exception">The exception.</param>
+        void Error(object message, Exception exception);
+
+        /// <summary>
+        /// Logs a Error format message.
+        /// </summary>
+        /// <param name="format">The format.</param>
+        /// <param name="args">The args.</param>
+        void ErrorFormat(string format, params object[] args);
+
+        /// <summary>
+        /// Logs a Fatal message.
+        /// </summary>
+        /// <param name="message">The message.</param>
+        void Fatal(object message);
+
+        /// <summary>
+        /// Logs a Fatal message and exception.
+        /// </summary>
+        /// <param name="message">The message.</param>
+        /// <param name="exception">The exception.</param>
+        void Fatal(object message, Exception exception);
+
+        /// <summary>
+        /// Logs a Error format message.
+        /// </summary>
+        /// <param name="format">The format.</param>
+        /// <param name="args">The args.</param>
+        void FatalFormat(string format, params object[] args);
+
+        /// <summary>
+        /// Logs an Info message and exception.
+        /// </summary>
+        /// <param name="message">The message.</param>
+        void Info(object message);
+
+        /// <summary>
+        /// Logs an Info message and exception.
+        /// </summary>
+        /// <param name="message">The message.</param>
+        /// <param name="exception">The exception.</param>
+        void Info(object message, Exception exception);
+
+        /// <summary>
+        /// Logs an Info format message.
+        /// </summary>
+        /// <param name="format">The format.</param>
+        /// <param name="args">The args.</param>
+        void InfoFormat(string format, params object[] args);
+
+        /// <summary>
+        /// Logs a Warning message.
+        /// </summary>
+        /// <param name="message">The message.</param>
+        void Warn(object message);
+
+        /// <summary>
+        /// Logs a Warning message and exception.
+        /// </summary>
+        /// <param name="message">The message.</param>
+        /// <param name="exception">The exception.</param>
+        void Warn(object message, Exception exception);
+
+        /// <summary>
+        /// Logs a Warning format message.
+        /// </summary>
+        /// <param name="format">The format.</param>
+        /// <param name="args">The args.</param>
+        void WarnFormat(string format, params object[] args);
+    }
+
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Logging/ILogFactory.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Logging/ILogFactory.cs
new file mode 100644
index 0000000..fdbfceb
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Logging/ILogFactory.cs
@@ -0,0 +1,24 @@
+using System;
+
+namespace ServiceStack.Logging
+{
+    /// <summary>
+    /// Factory to create ILog instances
+    /// </summary>
+    public interface ILogFactory
+    {
+        /// <summary>
+        /// Gets the logger.
+        /// </summary>
+        /// <param name="type">The type.</param>
+        /// <returns></returns>
+        ILog GetLogger(Type type);
+
+        /// <summary>
+        /// Gets the logger.
+        /// </summary>
+        /// <param name="typeName">Name of the type.</param>
+        /// <returns></returns>
+        ILog GetLogger(string typeName);
+    }
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Logging/LogManager.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Logging/LogManager.cs
new file mode 100644
index 0000000..2c59686
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Logging/LogManager.cs
@@ -0,0 +1,52 @@
+using System;
+using ServiceStack.Logging.Support.Logging;
+
+namespace ServiceStack.Logging
+{
+    /// <summary>
+    /// Logging API for this library. You can inject your own implementation otherwise
+    /// will use the DebugLogFactory to write to System.Diagnostics.Debug
+    /// </summary>
+    public class LogManager
+    {
+        private static ILogFactory logFactory;
+
+        /// <summary>
+        /// Gets or sets the log factory.
+        /// Use this to override the factory that is used to create loggers
+        /// </summary>
+        /// <value>The log factory.</value>
+        public static ILogFactory LogFactory
+        {
+            get
+            {
+                if (logFactory == null)
+                {
+                    return new DebugLogFactory();
+                }
+                return logFactory;
+            }
+            set { logFactory = value; }
+        }
+
+        /// <summary>
+        /// Gets the logger.
+        /// </summary>
+        /// <param name="type">The type.</param>
+        /// <returns></returns>
+        public static ILog GetLogger(Type type)
+        {
+            return LogFactory.GetLogger(type);
+        }
+
+        /// <summary>
+        /// Gets the logger.
+        /// </summary>
+        /// <param name="typeName">Name of the type.</param>
+        /// <returns></returns>
+        public static ILog GetLogger(string typeName)
+        {
+            return LogFactory.GetLogger(typeName);
+        }
+    }
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Logging/Support/Logging/ConsoleLogFactory.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Logging/Support/Logging/ConsoleLogFactory.cs
new file mode 100644
index 0000000..b494754
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Logging/Support/Logging/ConsoleLogFactory.cs
@@ -0,0 +1,22 @@
+using System;
+
+namespace ServiceStack.Logging.Support.Logging
+{
+    /// <summary>
+    /// Creates a Debug Logger, that logs all messages to: System.Diagnostics.Debug
+    /// 
+    /// Made public so its testable
+    /// </summary>
+	public class ConsoleLogFactory : ILogFactory
+    {
+        public ILog GetLogger(Type type)
+        {
+            return new ConsoleLogger(type);
+        }
+
+        public ILog GetLogger(string typeName)
+        {
+			return new ConsoleLogger(typeName);
+        }
+    }
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Logging/Support/Logging/ConsoleLogger.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Logging/Support/Logging/ConsoleLogger.cs
new file mode 100644
index 0000000..6f8576c
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Logging/Support/Logging/ConsoleLogger.cs
@@ -0,0 +1,151 @@
+using System;
+
+namespace ServiceStack.Logging.Support.Logging
+{
+    /// <summary>
+    /// Default logger is to Console.WriteLine
+    /// 
+    /// Made public so its testable
+    /// </summary>
+    public class ConsoleLogger : ILog
+    {
+        const string DEBUG = "DEBUG: ";
+        const string ERROR = "ERROR: ";
+        const string FATAL = "FATAL: ";
+        const string INFO = "INFO: ";
+        const string WARN = "WARN: ";
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="DebugLogger"/> class.
+        /// </summary>
+        /// <param name="type">The type.</param>
+        public ConsoleLogger(string type)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="DebugLogger"/> class.
+        /// </summary>
+        /// <param name="type">The type.</param>
+		public ConsoleLogger(Type type)
+        {
+        }
+
+        #region ILog Members
+
+		public bool IsDebugEnabled { get { return true; } }
+		
+		/// <summary>
+        /// Logs the specified message.
+        /// </summary>
+        /// <param name="message">The message.</param>
+        /// <param name="exception">The exception.</param>
+        private static void Log(object message, Exception exception)
+        {
+            string msg = message == null ? string.Empty : message.ToString();
+            if (exception != null)
+            {
+                msg += ", Exception: " + exception.Message;
+            }
+            Console.WriteLine(msg);
+        }
+
+        /// <summary>
+        /// Logs the format.
+        /// </summary>
+        /// <param name="message">The message.</param>
+        /// <param name="args">The args.</param>
+        private static void LogFormat(object message, params object[] args)
+        {
+            string msg = message == null ? string.Empty : message.ToString();
+            Console.WriteLine(msg, args);
+        }
+
+        /// <summary>
+        /// Logs the specified message.
+        /// </summary>
+        /// <param name="message">The message.</param>
+        private static void Log(object message)
+        {
+            string msg = message == null ? string.Empty : message.ToString();
+            Console.WriteLine(msg);
+        }
+
+        public void Debug(object message, Exception exception)
+        {
+            Log(DEBUG + message, exception);
+        }
+
+        public void Debug(object message)
+        {
+            Log(DEBUG + message);
+        }
+
+        public void DebugFormat(string format, params object[] args)
+        {
+            LogFormat(DEBUG + format, args);
+        }
+
+        public void Error(object message, Exception exception)
+        {
+            Log(ERROR + message, exception);
+        }
+
+        public void Error(object message)
+        {
+            Log(ERROR + message);
+        }
+
+        public void ErrorFormat(string format, params object[] args)
+        {
+            LogFormat(ERROR + format, args);
+        }
+
+        public void Fatal(object message, Exception exception)
+        {
+            Log(FATAL + message, exception);
+        }
+
+        public void Fatal(object message)
+        {
+            Log(FATAL + message);
+        }
+
+        public void FatalFormat(string format, params object[] args)
+        {
+            LogFormat(FATAL + format, args);
+        }
+
+        public void Info(object message, Exception exception)
+        {
+            Log(INFO + message, exception);
+        }
+
+        public void Info(object message)
+        {
+            Log(INFO + message);
+        }
+
+        public void InfoFormat(string format, params object[] args)
+        {
+            LogFormat(INFO + format, args);
+        }
+
+        public void Warn(object message, Exception exception)
+        {
+            Log(WARN + message, exception);
+        }
+
+        public void Warn(object message)
+        {
+            Log(WARN + message);
+        }
+
+        public void WarnFormat(string format, params object[] args)
+        {
+            LogFormat(WARN + format, args);
+        }
+
+        #endregion
+    }
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Logging/Support/Logging/DebugLogFactory.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Logging/Support/Logging/DebugLogFactory.cs
new file mode 100644
index 0000000..58b5724
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Logging/Support/Logging/DebugLogFactory.cs
@@ -0,0 +1,22 @@
+using System;
+
+namespace ServiceStack.Logging.Support.Logging
+{
+    /// <summary>
+    /// Creates a Debug Logger, that logs all messages to: System.Diagnostics.Debug
+    /// 
+    /// Made public so its testable
+    /// </summary>
+    public class DebugLogFactory : ILogFactory
+    {
+        public ILog GetLogger(Type type)
+        {
+            return new DebugLogger(type);
+        }
+
+        public ILog GetLogger(string typeName)
+        {
+            return new DebugLogger(typeName);
+        }
+    }
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Logging/Support/Logging/DebugLogger.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Logging/Support/Logging/DebugLogger.cs
new file mode 100644
index 0000000..2384414
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Logging/Support/Logging/DebugLogger.cs
@@ -0,0 +1,151 @@
+using System;
+
+namespace ServiceStack.Logging.Support.Logging
+{
+    /// <summary>
+	/// Default logger is to System.Diagnostics.Debug.WriteLine
+    /// 
+    /// Made public so its testable
+    /// </summary>
+    public class DebugLogger : ILog
+    {
+        const string DEBUG = "DEBUG: ";
+        const string ERROR = "ERROR: ";
+        const string FATAL = "FATAL: ";
+        const string INFO = "INFO: ";
+        const string WARN = "WARN: ";
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="DebugLogger"/> class.
+        /// </summary>
+        /// <param name="type">The type.</param>
+        public DebugLogger(string type)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="DebugLogger"/> class.
+        /// </summary>
+        /// <param name="type">The type.</param>
+        public DebugLogger(Type type)
+        {
+        }
+
+        #region ILog Members
+
+        /// <summary>
+        /// Logs the specified message.
+        /// </summary>
+        /// <param name="message">The message.</param>
+        /// <param name="exception">The exception.</param>
+        private static void Log(object message, Exception exception)
+        {
+            string msg = message == null ? string.Empty : message.ToString();
+            if (exception != null)
+            {
+                msg += ", Exception: " + exception.Message;
+            }
+			System.Diagnostics.Debug.WriteLine(msg);
+        }
+
+        /// <summary>
+        /// Logs the format.
+        /// </summary>
+        /// <param name="message">The message.</param>
+        /// <param name="args">The args.</param>
+        private static void LogFormat(object message, params object[] args)
+        {
+            string msg = message == null ? string.Empty : message.ToString();
+			System.Diagnostics.Debug.WriteLine(string.Format(msg, args));
+        }
+
+        /// <summary>
+        /// Logs the specified message.
+        /// </summary>
+        /// <param name="message">The message.</param>
+        private static void Log(object message)
+        {
+            string msg = message == null ? string.Empty : message.ToString();
+			System.Diagnostics.Debug.WriteLine(msg);
+        }
+
+        public void Debug(object message, Exception exception)
+        {
+            Log(DEBUG + message, exception);
+        }
+
+		public bool IsDebugEnabled { get { return true; } }
+
+    	public void Debug(object message)
+        {
+            Log(DEBUG + message);
+        }
+
+        public void DebugFormat(string format, params object[] args)
+        {
+            LogFormat(DEBUG + format, args);
+        }
+
+        public void Error(object message, Exception exception)
+        {
+            Log(ERROR + message, exception);
+        }
+
+        public void Error(object message)
+        {
+            Log(ERROR + message);
+        }
+
+        public void ErrorFormat(string format, params object[] args)
+        {
+            LogFormat(ERROR + format, args);
+        }
+
+        public void Fatal(object message, Exception exception)
+        {
+            Log(FATAL + message, exception);
+        }
+
+        public void Fatal(object message)
+        {
+            Log(FATAL + message);
+        }
+
+        public void FatalFormat(string format, params object[] args)
+        {
+            LogFormat(FATAL + format, args);
+        }
+
+        public void Info(object message, Exception exception)
+        {
+            Log(INFO + message, exception);
+        }
+
+        public void Info(object message)
+        {
+            Log(INFO + message);
+        }
+
+        public void InfoFormat(string format, params object[] args)
+        {
+            LogFormat(INFO + format, args);
+        }
+
+        public void Warn(object message, Exception exception)
+        {
+            Log(WARN + message, exception);
+        }
+
+        public void Warn(object message)
+        {
+            Log(WARN + message);
+        }
+
+        public void WarnFormat(string format, params object[] args)
+        {
+            LogFormat(WARN + format, args);
+        }
+
+        #endregion
+    }
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Logging/Support/Logging/NullDebugLogger.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Logging/Support/Logging/NullDebugLogger.cs
new file mode 100644
index 0000000..d10c77e
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Logging/Support/Logging/NullDebugLogger.cs
@@ -0,0 +1,120 @@
+using System;
+
+namespace ServiceStack.Logging.Support.Logging
+{
+    /// <summary>
+    /// Default logger is to System.Diagnostics.Debug.Print
+    /// 
+    /// Made public so its testable
+    /// </summary>
+    public class NullDebugLogger : ILog
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="DebugLogger"/> class.
+        /// </summary>
+        /// <param name="type">The type.</param>
+        public NullDebugLogger(string type)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="DebugLogger"/> class.
+        /// </summary>
+        /// <param name="type">The type.</param>
+		public NullDebugLogger(Type type)
+        {
+        }
+
+        #region ILog Members
+
+        /// <summary>
+        /// Logs the specified message.
+        /// </summary>
+        /// <param name="message">The message.</param>
+        /// <param name="exception">The exception.</param>
+        private static void Log(object message, Exception exception)
+		{
+        }
+
+        /// <summary>
+        /// Logs the format.
+        /// </summary>
+        /// <param name="message">The message.</param>
+        /// <param name="args">The args.</param>
+        private static void LogFormat(object message, params object[] args)
+		{
+		}
+
+        /// <summary>
+        /// Logs the specified message.
+        /// </summary>
+        /// <param name="message">The message.</param>
+        private static void Log(object message)
+		{
+		}
+
+        public void Debug(object message, Exception exception)
+		{
+		}
+
+		public bool IsDebugEnabled { get { return true; } }
+
+    	public void Debug(object message)
+		{
+		}
+
+        public void DebugFormat(string format, params object[] args)
+		{
+		}
+
+        public void Error(object message, Exception exception)
+		{
+		}
+
+        public void Error(object message)
+		{
+		}
+
+        public void ErrorFormat(string format, params object[] args)
+		{
+		}
+
+        public void Fatal(object message, Exception exception)
+		{
+		}
+
+        public void Fatal(object message)
+		{
+		}
+
+        public void FatalFormat(string format, params object[] args)
+		{
+		}
+
+        public void Info(object message, Exception exception)
+		{
+		}
+
+        public void Info(object message)
+		{
+		}
+
+        public void InfoFormat(string format, params object[] args)
+		{
+		}
+
+        public void Warn(object message, Exception exception)
+		{
+		}
+
+        public void Warn(object message)
+		{
+		}
+
+        public void WarnFormat(string format, params object[] args)
+		{
+		}
+
+        #endregion
+    }
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Logging/Support/Logging/NullLogFactory.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Logging/Support/Logging/NullLogFactory.cs
new file mode 100644
index 0000000..4874d14
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Logging/Support/Logging/NullLogFactory.cs
@@ -0,0 +1,22 @@
+using System;
+
+namespace ServiceStack.Logging.Support.Logging
+{
+    /// <summary>
+    /// Creates a Debug Logger, that logs all messages to: System.Diagnostics.Debug
+    /// 
+    /// Made public so its testable
+    /// </summary>
+	public class NullLogFactory : ILogFactory
+    {
+        public ILog GetLogger(Type type)
+        {
+			return new NullDebugLogger(type);
+        }
+
+        public ILog GetLogger(string typeName)
+        {
+			return new NullDebugLogger(typeName);
+        }
+    }
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Logging/Support/Logging/TestLogFactory.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Logging/Support/Logging/TestLogFactory.cs
new file mode 100644
index 0000000..5927d3b
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Logging/Support/Logging/TestLogFactory.cs
@@ -0,0 +1,20 @@
+using System;
+
+namespace ServiceStack.Logging.Support.Logging
+{
+    /// <summary>
+    /// Creates a test Logger, that stores all log messages in a member list
+    /// </summary>
+	public class TestLogFactory : ILogFactory
+    {
+        public ILog GetLogger(Type type)
+        {
+            return new TestLogger(type);
+        }
+
+        public ILog GetLogger(string typeName)
+        {
+            return new TestLogger(typeName);
+        }
+    }
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Logging/Support/Logging/TestLogger.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Logging/Support/Logging/TestLogger.cs
new file mode 100644
index 0000000..25f397f
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Logging/Support/Logging/TestLogger.cs
@@ -0,0 +1,136 @@
+using System;
+using System.Collections.Generic;
+
+namespace ServiceStack.Logging.Support.Logging {
+    /// <summary>
+    /// Tests logger which  stores all log messages in a member list which can be examined later
+    /// 
+    /// Made public so its testable
+    /// </summary>
+    public class TestLogger : ILog {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="TestLogger"/> class.
+        /// </summary>
+        /// <param name="type">The type.</param>
+        public TestLogger(string type) {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="TestLogger"/> class.
+        /// </summary>
+        /// <param name="type">The type.</param>
+        public TestLogger(Type type) {
+        }
+
+        public enum Levels {
+            DEBUG,
+            ERROR,
+            FATAL,
+            INFO,
+            WARN,
+        };
+
+        static private List<KeyValuePair<Levels, string>> _logs = new List<KeyValuePair<Levels, string>>();
+
+
+        static public IList<KeyValuePair<Levels, string>> GetLogs() { return _logs; }
+
+        #region ILog Members
+
+        public bool IsDebugEnabled { get { return true; } }
+
+        /// <summary>
+        /// Logs the specified message.
+        /// </summary>
+        /// <param name="message">The message.</param>
+        /// <param name="exception">The exception.</param>
+        private static void Log(Levels level, object message, Exception exception) {
+            string msg = message == null ? string.Empty : message.ToString();
+            if(exception != null) {
+                msg += ", Exception: " + exception.Message;
+            }
+            _logs.Add(new KeyValuePair<Levels, string>(level, msg));
+        }
+
+        /// <summary>
+        /// Logs the format.
+        /// </summary>
+        /// <param name="message">The message.</param>
+        /// <param name="args">The args.</param>
+        private static void LogFormat(Levels level, object message, params object[] args) {
+            string msg = message == null ? string.Empty : message.ToString();
+            _logs.Add(new KeyValuePair<Levels, string>(level, string.Format(msg, args)));
+        }
+
+        /// <summary>
+        /// Logs the specified message.
+        /// </summary>
+        /// <param name="message">The message.</param>
+        private static void Log(Levels level, object message) {
+            string msg = message == null ? string.Empty : message.ToString();
+            _logs.Add(new KeyValuePair<Levels, string>(level, msg));
+        }
+
+        public void Debug(object message, Exception exception) {
+            Log(Levels.DEBUG, message, exception);
+        }
+
+        public void Debug(object message) {
+            Log(Levels.DEBUG, message);
+        }
+
+        public void DebugFormat(string format, params object[] args) {
+            LogFormat(Levels.DEBUG, format, args);
+        }
+
+        public void Error(object message, Exception exception) {
+            Log(Levels.ERROR, message, exception);
+        }
+
+        public void Error(object message) {
+            Log(Levels.ERROR, message);
+        }
+
+        public void ErrorFormat(string format, params object[] args) {
+            LogFormat(Levels.ERROR, format, args);
+        }
+
+        public void Fatal(object message, Exception exception) {
+            Log(Levels.FATAL, message, exception);
+        }
+
+        public void Fatal(object message) {
+            Log(Levels.FATAL, message);
+        }
+
+        public void FatalFormat(string format, params object[] args) {
+            LogFormat(Levels.FATAL, format, args);
+        }
+
+        public void Info(object message, Exception exception) {
+            Log(Levels.INFO, message, exception);
+        }
+
+        public void Info(object message) {
+            Log(Levels.INFO, message);
+        }
+
+        public void InfoFormat(string format, params object[] args) {
+            LogFormat(Levels.INFO, format, args);
+        }
+
+        public void Warn(object message, Exception exception) {
+            Log(Levels.WARN, message, exception);
+        }
+
+        public void Warn(object message) {
+            Log(Levels.WARN, message);
+        }
+
+        public void WarnFormat(string format, params object[] args) {
+            LogFormat(Levels.WARN, format, args);
+        }
+
+        #endregion
+    }
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/LogicFacade/IApplicationContext.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/LogicFacade/IApplicationContext.cs
new file mode 100644
index 0000000..f1e3888
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/LogicFacade/IApplicationContext.cs
@@ -0,0 +1,16 @@
+using ServiceStack.CacheAccess;
+using ServiceStack.Configuration;
+
+namespace ServiceStack.LogicFacade
+{
+	public interface IApplicationContext
+	{
+		IFactoryProvider Factory { get; }
+
+		T Get<T>() where T : class;
+
+		ICacheClient Cache { get; }
+
+		IResourceManager Resources { get; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/LogicFacade/IInitContext.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/LogicFacade/IInitContext.cs
new file mode 100644
index 0000000..6448865
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/LogicFacade/IInitContext.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace ServiceStack.LogicFacade
+{
+	public interface IInitContext : IDisposable
+	{
+		object InitialisedObject
+		{
+			get;
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/LogicFacade/ILogicFacade.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/LogicFacade/ILogicFacade.cs
new file mode 100644
index 0000000..0b3501f
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/LogicFacade/ILogicFacade.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace ServiceStack.LogicFacade
+{
+	public interface ILogicFacade : IDisposable
+	{
+		IInitContext AcquireInitContext(InitOptions options);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/LogicFacade/IOperationContext.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/LogicFacade/IOperationContext.cs
new file mode 100644
index 0000000..69ee0ae
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/LogicFacade/IOperationContext.cs
@@ -0,0 +1,12 @@
+using System;
+using ServiceStack.ServiceHost;
+
+namespace ServiceStack.LogicFacade
+{
+	public interface IOperationContext : IDisposable
+	{
+		IApplicationContext Application { get;  }
+		
+		IRequestContext Request { get; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/LogicFacade/IServiceModelFinder.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/LogicFacade/IServiceModelFinder.cs
new file mode 100644
index 0000000..0e45cec
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/LogicFacade/IServiceModelFinder.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Reflection;
+
+namespace ServiceStack.LogicFacade
+{
+	/// <summary>
+	/// The same functionality is on IServiceResolver
+	/// </summary>
+	[Obsolete]
+	public interface IServiceModelFinder
+	{
+		Type FindTypeByOperation(string operationName, int? version);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/LogicFacade/IXmlRequest.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/LogicFacade/IXmlRequest.cs
new file mode 100644
index 0000000..edcfab7
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/LogicFacade/IXmlRequest.cs
@@ -0,0 +1,7 @@
+namespace ServiceStack.LogicFacade
+{
+	public interface IXmlRequest
+	{
+		string Xml { get; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/LogicFacade/InitOptions.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/LogicFacade/InitOptions.cs
new file mode 100644
index 0000000..3b4411b
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/LogicFacade/InitOptions.cs
@@ -0,0 +1,11 @@
+using System;
+
+namespace ServiceStack.LogicFacade
+{
+	[Flags]
+	public enum InitOptions
+	{
+		None = 0,
+		InitialiseOnly = 1
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/IMessage.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/IMessage.cs
new file mode 100644
index 0000000..d64de66
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/IMessage.cs
@@ -0,0 +1,32 @@
+using System;
+using ServiceStack.DataAnnotations;
+using ServiceStack.DesignPatterns.Model;
+
+namespace ServiceStack.Messaging
+{
+	public interface IMessage
+		: IHasId<Guid>
+	{
+		DateTime CreatedDate { get; }
+
+		long Priority { get; set; }
+
+		int RetryAttempts { get; set; }
+
+		Guid? ReplyId { get; set; }
+
+        string ReplyTo { get; set; }
+
+        int Options { get; set; }
+
+        MessageError Error { get; set; }
+
+		object Body { get; set; }
+	}
+
+    public interface IMessage<T>
+		: IMessage
+	{
+		T GetBody();
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/IMessageFactory.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/IMessageFactory.cs
new file mode 100644
index 0000000..6e6875f
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/IMessageFactory.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace ServiceStack.Messaging
+{
+	public interface IMessageFactory : IMessageQueueClientFactory
+	{
+		IMessageProducer CreateMessageProducer();
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/IMessageProducer.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/IMessageProducer.cs
new file mode 100644
index 0000000..a1f32c0
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/IMessageProducer.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace ServiceStack.Messaging
+{
+	public interface IMessageProducer
+		: IDisposable
+	{
+		void Publish<T>(T messageBody);
+		void Publish<T>(IMessage<T> message);
+	}
+
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/IMessageQueueClient.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/IMessageQueueClient.cs
new file mode 100644
index 0000000..ded56e4
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/IMessageQueueClient.cs
@@ -0,0 +1,44 @@
+using System;
+
+namespace ServiceStack.Messaging
+{
+	public interface IMessageQueueClient
+		: IMessageProducer
+	{
+		/// <summary>
+		/// Publish the specified message into the durable queue @queueName
+		/// </summary>
+		/// <param name="queueName"></param>
+		/// <param name="messageBytes"></param>
+		void Publish(string queueName, byte[] messageBytes);
+		
+		/// <summary>
+		/// Publish the specified message into the transient queue @queueName
+		/// </summary>
+		/// <param name="queueName"></param>
+		/// <param name="messageBytes"></param>
+		void Notify(string queueName, byte[] messageBytes);
+
+		/// <summary>
+		/// Synchronous blocking get.
+		/// </summary>
+		/// <param name="queueName"></param>
+		/// <param name="timeOut"></param>
+		/// <returns></returns>
+		byte[] Get(string queueName, TimeSpan? timeOut);
+		
+		/// <summary>
+		/// Non blocking get message
+		/// </summary>
+		/// <param name="queueName"></param>
+		/// <returns></returns>
+		byte[] GetAsync(string queueName);
+
+		/// <summary>
+		/// Blocking wait for notifications on any of the supplied channels
+		/// </summary>
+		/// <param name="channelNames"></param>
+		/// <returns></returns>
+		string WaitForNotifyOnAny(params string[] channelNames);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/IMessageQueueClientFactory.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/IMessageQueueClientFactory.cs
new file mode 100644
index 0000000..f686202
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/IMessageQueueClientFactory.cs
@@ -0,0 +1,10 @@
+using System;
+
+namespace ServiceStack.Messaging
+{
+	public interface IMessageQueueClientFactory
+		: IDisposable
+	{
+		IMessageQueueClient CreateMessageQueueClient();
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/IMessageService.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/IMessageService.cs
new file mode 100644
index 0000000..da14eda
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/IMessageService.cs
@@ -0,0 +1,60 @@
+using System;
+
+namespace ServiceStack.Messaging
+{
+    /// <summary>
+    /// Simple definition of an MQ Host
+    /// </summary>
+	public interface IMessageService
+		: IDisposable
+	{
+		/// <summary>
+		/// Factory to create consumers and producers that work with this service
+		/// </summary>
+		IMessageFactory MessageFactory { get; }
+
+        /// <summary>
+        /// Register DTOs and hanlders the MQ Host will process
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="processMessageFn"></param>
+		void RegisterHandler<T>(Func<IMessage<T>, object> processMessageFn);
+
+    	/// <summary>
+    	/// Register DTOs and hanlders the MQ Host will process
+    	/// </summary>
+    	/// <typeparam name="T"></typeparam>
+    	/// <param name="processMessageFn"></param>
+    	/// <param name="processExceptionEx"></param>
+    	void RegisterHandler<T>(Func<IMessage<T>, object> processMessageFn, Action<IMessage<T>, Exception> processExceptionEx);
+
+        /// <summary>
+        /// Get Total Current Stats for all Message Handlers
+        /// </summary>
+        /// <returns></returns>
+        IMessageHandlerStats GetStats();
+
+        /// <summary>
+        /// Get the status of the service. Potential Statuses: Disposed, Stopped, Stopping, Starting, Started
+        /// </summary>
+        /// <returns></returns>
+        string GetStatus();
+
+        /// <summary>
+        /// Get a Stats dump
+        /// </summary>
+        /// <returns></returns>
+        string GetStatsDescription();
+
+        /// <summary>
+        /// Start the MQ Host if not already started.
+        /// </summary>
+		void Start();
+
+        /// <summary>
+        /// Stop the MQ Host if not already stopped. 
+        /// </summary>
+        void Stop();
+	}
+
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/MessageError.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/MessageError.cs
new file mode 100644
index 0000000..891317e
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/MessageError.cs
@@ -0,0 +1,14 @@
+namespace ServiceStack.Messaging
+{
+	/// <summary>
+	/// An Error Message Type that can be easily serialized
+	/// </summary>
+	public class MessageError
+	{
+		public string ErrorCode { get; set; }
+
+		public string Message { get; set; }
+
+		public string StackTrace { get; set; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/MessageFactory.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/MessageFactory.cs
new file mode 100644
index 0000000..8a0bd7a
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/MessageFactory.cs
@@ -0,0 +1,90 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using ServiceStack.DataAnnotations;
+
+namespace ServiceStack.Messaging
+{
+	internal delegate IMessage MessageFactoryDelegate(object body);
+
+	public static class MessageFactory
+	{
+		static readonly Dictionary<Type, MessageFactoryDelegate> CacheFn 
+			= new Dictionary<Type, MessageFactoryDelegate>();
+
+		public static IMessage Create(object response)
+		{
+			if (response == null) return null;
+			var type = response.GetType();
+
+			MessageFactoryDelegate factoryFn;
+			lock (CacheFn) CacheFn.TryGetValue(type, out factoryFn);
+
+			if (factoryFn != null)
+				return factoryFn(response);
+
+			var genericMessageType = typeof(Message<>).MakeGenericType(type);
+			var mi = genericMessageType.GetMethod("Create", 
+				BindingFlags.Public | BindingFlags.Static);
+			factoryFn = (MessageFactoryDelegate) Delegate.CreateDelegate(
+				typeof (MessageFactoryDelegate), mi);
+
+			lock (CacheFn) CacheFn[type] = factoryFn;
+
+			return factoryFn(response);
+		}
+	}
+
+    public class Message : IMessage
+    {
+        public Guid Id { get; set; }
+        public DateTime CreatedDate { get; set; }
+        public long Priority { get; set; }
+        public int RetryAttempts { get; set; }
+        public Guid? ReplyId { get; set; }
+        public string ReplyTo { get; set; }
+        public int Options { get; set; }
+        public MessageError Error { get; set; }
+        public object Body { get; set; }
+    }
+
+	/// <summary>
+	/// Basic implementation of IMessage[T]
+	/// </summary>
+	/// <typeparam name="T"></typeparam>
+	public class Message<T>
+        : Message, IMessage<T>
+	{
+		public Message()
+		{
+			this.Id = Guid.NewGuid();
+			this.CreatedDate = DateTime.UtcNow;
+            this.Options = (int) MessageOption.NotifyOneWay;
+		}
+
+		public Message(T body) : this()
+		{
+			Body = body;
+		}
+
+		public static IMessage Create(object oBody)
+		{
+			return new Message<T>((T) oBody);
+		}
+
+		public T GetBody()
+		{
+			return (T)Body;
+		}
+
+		public override string ToString()
+		{
+			return string.Format("CreatedDate={0}, Id={1}, Type={2}, Retry={3}",
+				this.CreatedDate,
+				this.Id.ToString("N"),
+				typeof(T).Name,
+				this.RetryAttempts);
+		}
+
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/MessageHandlerStats.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/MessageHandlerStats.cs
new file mode 100644
index 0000000..9d389e8
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/MessageHandlerStats.cs
@@ -0,0 +1,62 @@
+using System.Text;
+
+namespace ServiceStack.Messaging
+{
+    public interface IMessageHandlerStats
+    {
+        string Name { get; }
+        int TotalMessagesProcessed { get; }
+        int TotalMessagesFailed { get; }
+        int TotalRetries { get; }
+        int TotalNormalMessagesReceived { get; }
+        int TotalPriorityMessagesReceived { get; }
+        void Add(IMessageHandlerStats stats);
+    }
+
+    public class MessageHandlerStats : IMessageHandlerStats
+    {
+        public MessageHandlerStats(string name)
+        {
+            Name = name;
+        }
+
+        public MessageHandlerStats(string name, int totalMessagesProcessed, int totalMessagesFailed, int totalRetries, 
+            int totalNormalMessagesReceived, int totalPriorityMessagesReceived)
+        {
+            Name = name;
+            TotalMessagesProcessed = totalMessagesProcessed;
+            TotalMessagesFailed = totalMessagesFailed;
+            TotalRetries = totalRetries;
+            TotalNormalMessagesReceived = totalNormalMessagesReceived;
+            TotalPriorityMessagesReceived = totalPriorityMessagesReceived;
+        }
+
+        public string Name { get; private set; }
+        public int TotalMessagesProcessed { get; private set; }
+        public int TotalMessagesFailed { get; private set; }
+        public int TotalRetries { get; private set; }
+        public int TotalNormalMessagesReceived { get; private set; }
+        public int TotalPriorityMessagesReceived { get; private set; }
+
+        public virtual void Add(IMessageHandlerStats stats)
+        {
+            TotalMessagesProcessed += stats.TotalMessagesProcessed;
+            TotalMessagesFailed += stats.TotalMessagesFailed;
+            TotalRetries += stats.TotalRetries;
+            TotalNormalMessagesReceived += stats.TotalNormalMessagesReceived;
+            TotalPriorityMessagesReceived += stats.TotalPriorityMessagesReceived;
+        }
+
+        public override string ToString()
+        {
+            var sb = new StringBuilder("Stats for " + Name);
+            sb.AppendLine("\n---------------");
+            sb.AppendFormat("\nTotalNormalMessagesReceived: {0}", TotalNormalMessagesReceived);
+            sb.AppendFormat("\nTotalPriorityMessagesReceived: {0}", TotalPriorityMessagesReceived);
+            sb.AppendFormat("\nTotalProcessed: {0}", TotalMessagesProcessed);
+            sb.AppendFormat("\nTotalRetries: {0}", TotalRetries);
+            sb.AppendFormat("\nTotalFailed: {0}", TotalMessagesFailed);
+            return sb.ToString();
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/MessageOption.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/MessageOption.cs
new file mode 100644
index 0000000..8eebe9b
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/MessageOption.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace ServiceStack.Messaging
+{
+    [Flags]
+    public enum MessageOption : int
+    {
+        None = 0,
+        All = int.MaxValue,
+
+        NotifyOneWay = 1 << 0,
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/MessagingException.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/MessagingException.cs
new file mode 100644
index 0000000..f114f46
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/MessagingException.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Runtime.Serialization;
+
+namespace ServiceStack.Messaging
+{
+	/// <summary>
+	/// Base Exception for all ServiceStack.Messaging exceptions
+	/// </summary>
+	public class MessagingException
+		: Exception
+	{
+		public MessagingException()
+		{
+		}
+
+		public MessagingException(string message)
+			: base(message)
+		{
+		}
+
+		public MessagingException(string message, Exception innerException)
+			: base(message, innerException)
+		{
+		}
+
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+		protected MessagingException(SerializationInfo info, StreamingContext context)
+			: base(info, context)
+		{
+		}
+#endif
+        public virtual MessageError ToMessageError()
+		{
+			return new MessageError {
+				ErrorCode = GetType().Name,
+				Message = this.Message,
+				StackTrace = this.ToString(), //Also includes inner exception
+			};
+		}
+	}
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/QueueNames.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/QueueNames.cs
new file mode 100644
index 0000000..767e3aa
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/QueueNames.cs
@@ -0,0 +1,83 @@
+using System;
+using System.Text;
+
+namespace ServiceStack.Messaging
+{
+	/// <summary>
+	/// Util static generic class to create unique queue names for types
+	/// </summary>
+	/// <typeparam name="T"></typeparam>
+	public static class QueueNames<T>
+	{
+		static QueueNames()
+		{
+			var utf8 = new UTF8Encoding(false);
+
+			Priority = "mq:" + typeof(T).Name + ".priorityq";
+			PriorityBytes = utf8.GetBytes(Priority);
+			In = "mq:" + typeof(T).Name + ".inq";
+			InBytes = utf8.GetBytes(In);
+			Out = "mq:" + typeof(T).Name + ".outq";
+			OutBytes = utf8.GetBytes(Out);
+			Dlq = "mq:" + typeof(T).Name + ".dlq";
+			DlqBytes = utf8.GetBytes(Dlq);
+		}
+
+		public static string Priority { get; private set; }
+		public static byte[] PriorityBytes { get; private set; }
+
+		public static string In { get; private set; }
+		public static byte[] InBytes { get; private set; }
+
+		public static string Out { get; private set; }
+		public static byte[] OutBytes { get; private set; }
+
+		public static string Dlq { get; private set; }
+		public static byte[] DlqBytes { get; private set; }
+	}
+
+	/// <summary>
+	/// Util class to create unique queue names for runtime types
+	/// </summary>
+	public class QueueNames
+	{
+		public static string TopicIn = "mq:topic:in";
+		public static string TopicOut = "mq:topic:out";
+		public static string QueuePrefix = "";
+
+		public static void SetQueuePrefix(string prefix)
+		{
+			TopicIn = prefix + "mq:topic:in";
+			TopicOut = prefix + "mq:topic:out";
+			QueuePrefix = prefix;
+		}
+
+		private readonly Type messageType;
+
+		public QueueNames(Type messageType)
+		{
+			this.messageType = messageType;
+		}
+
+		public string Priority
+		{
+			get { return QueuePrefix + "mq:" + messageType.Name + ".priorityq"; }
+		}
+
+		public string In
+		{
+			get { return QueuePrefix + "mq:" + messageType.Name + ".inq"; }
+		}
+
+		public string Out
+		{
+			get { return QueuePrefix + "mq:" + messageType.Name + ".outq"; }
+		}
+
+		public string Dlq
+		{
+			get { return QueuePrefix + "mq:" + messageType.Name + ".dlq"; }
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/UnRetryableMessagingException.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/UnRetryableMessagingException.cs
new file mode 100644
index 0000000..47e5653
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Messaging/UnRetryableMessagingException.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Runtime.Serialization;
+
+namespace ServiceStack.Messaging
+{
+	/// <summary>
+	/// For messaging exceptions that should by-pass the messaging service's configured
+	/// retry attempts and store the message straight into the DLQ
+	/// </summary>
+	public class UnRetryableMessagingException 
+		: MessagingException
+	{
+		public UnRetryableMessagingException()
+		{
+		}
+
+		public UnRetryableMessagingException(string message) : base(message)
+		{
+		}
+
+		public UnRetryableMessagingException(string message, Exception innerException) : base(message, innerException)
+		{
+		}
+
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+		protected UnRetryableMessagingException(SerializationInfo info, StreamingContext context) : base(info, context)
+		{
+		}
+#endif
+    }
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/OrmLite/DbConnectionFactory.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/OrmLite/DbConnectionFactory.cs
new file mode 100644
index 0000000..6c14b37
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/OrmLite/DbConnectionFactory.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Data;
+
+namespace ServiceStack.OrmLite
+{
+    public class DbConnectionFactory : IDbConnectionFactory
+    {
+        private readonly Func<IDbConnection> connectionFactoryFn;
+
+        public DbConnectionFactory(Func<IDbConnection> connectionFactoryFn)
+        {
+            this.connectionFactoryFn = connectionFactoryFn;
+        }
+
+        public IDbConnection OpenDbConnection()
+        {
+            var dbConn = CreateDbConnection();
+            dbConn.Open();
+            return dbConn;
+        }
+
+        public IDbConnection CreateDbConnection()
+        {
+            return connectionFactoryFn();
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/OrmLite/IDbConnectionFactory.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/OrmLite/IDbConnectionFactory.cs
new file mode 100644
index 0000000..42ce8a1
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/OrmLite/IDbConnectionFactory.cs
@@ -0,0 +1,10 @@
+using System.Data;
+
+namespace ServiceStack.OrmLite
+{
+    public interface IDbConnectionFactory
+    {
+        IDbConnection OpenDbConnection();
+        IDbConnection CreateDbConnection();
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Properties/AssemblyInfo.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..2d34ab0
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Properties/AssemblyInfo.cs
@@ -0,0 +1,39 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Serialization;
+
+// 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("ServiceStack.Interfaces")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("ServiceStack")]
+[assembly: AssemblyProduct("ServiceStack.Interfaces")]
+[assembly: AssemblyCopyright("Copyright © ServiceStack 2012")]
+[assembly: AssemblyTrademark("")]
+[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("d13ebd2a-6589-453d-bf31-4c744a59e993")]
+
+// 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 Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("3.9.8.0")]
+
+[assembly: ContractNamespace("http://schemas.servicestack.net/types", 
+	ClrNamespace = "ServiceStack.ServiceInterface.ServiceModel")]
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Generic/IRedisHash.Generic.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Generic/IRedisHash.Generic.cs
new file mode 100644
index 0000000..ee135e7
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Generic/IRedisHash.Generic.cs
@@ -0,0 +1,23 @@
+//
+// https://github.com/mythz/ServiceStack.Redis
+// ServiceStack.Redis: ECMA CLI Binding to the Redis key-value storage system
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2010 Liquidbit Ltd.
+//
+// Licensed under the same terms of Redis and ServiceStack: new BSD license.
+//
+
+using System.Collections.Generic;
+using ServiceStack.DesignPatterns.Model;
+
+namespace ServiceStack.Redis.Generic
+{
+	public interface IRedisHash<TKey, TValue> : IDictionary<TKey, TValue>, IHasStringId
+	{
+		Dictionary<TKey, TValue> GetAll();
+	}
+
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Generic/IRedisList.Generic.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Generic/IRedisList.Generic.cs
new file mode 100644
index 0000000..a7f300e
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Generic/IRedisList.Generic.cs
@@ -0,0 +1,50 @@
+//
+// https://github.com/mythz/ServiceStack.Redis
+// ServiceStack.Redis: ECMA CLI Binding to the Redis key-value storage system
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2010 Liquidbit Ltd.
+//
+// Licensed under the same terms of Redis and ServiceStack: new BSD license.
+//
+
+using System;
+using System.Collections.Generic;
+using ServiceStack.DesignPatterns.Model;
+
+namespace ServiceStack.Redis.Generic
+{
+	/// <summary>
+	/// Wrap the common redis list operations under a IList[string] interface.
+	/// </summary>
+
+	public interface IRedisList<T> 
+		: IList<T>, IHasStringId
+	{
+		List<T> GetAll();
+		List<T> GetRange(int startingFrom, int endingAt);
+		List<T> GetRangeFromSortedList(int startingFrom, int endingAt);
+		void RemoveAll();
+		void Trim(int keepStartingFrom, int keepEndingAt);
+		int RemoveValue(T value);
+		int RemoveValue(T value, int noOfMatches);
+
+		void AddRange(IEnumerable<T> values);
+		void Append(T value);
+		void Prepend(T value);
+		T RemoveStart();
+		T BlockingRemoveStart(TimeSpan? timeOut);
+		T RemoveEnd();
+
+		void Enqueue(T value);
+		T Dequeue();
+		T BlockingDequeue(TimeSpan? timeOut);
+
+		void Push(T value);
+		T Pop();
+		T BlockingPop(TimeSpan? timeOut);
+		T PopAndPush(IRedisList<T> toList);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Generic/IRedisSet.Generic.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Generic/IRedisSet.Generic.cs
new file mode 100644
index 0000000..82d9001
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Generic/IRedisSet.Generic.cs
@@ -0,0 +1,31 @@
+//
+// https://github.com/mythz/ServiceStack.Redis
+// ServiceStack.Redis: ECMA CLI Binding to the Redis key-value storage system
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2010 Liquidbit Ltd.
+//
+// Licensed under the same terms of Redis and ServiceStack: new BSD license.
+//
+
+using System.Collections.Generic;
+using ServiceStack.DesignPatterns.Model;
+
+namespace ServiceStack.Redis.Generic
+{
+	public interface IRedisSet<T> : ICollection<T>, IHasStringId
+	{
+		List<T> Sort(int startingFrom, int endingAt);
+		HashSet<T> GetAll();
+		T PopRandomItem();
+		T GetRandomItem();
+		void MoveTo(T item, IRedisSet<T> toSet);
+		void PopulateWithIntersectOf(params IRedisSet<T>[] sets);
+		void PopulateWithUnionOf(params IRedisSet<T>[] sets);
+		void GetDifferences(params IRedisSet<T>[] withSets);
+		void PopulateWithDifferencesOf(IRedisSet<T> fromSet, params IRedisSet<T>[] withSets);
+	}
+
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Generic/IRedisSortedSet.Generic.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Generic/IRedisSortedSet.Generic.cs
new file mode 100644
index 0000000..d2fb069
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Generic/IRedisSortedSet.Generic.cs
@@ -0,0 +1,38 @@
+//
+// https://github.com/mythz/ServiceStack.Redis
+// ServiceStack.Redis: ECMA CLI Binding to the Redis key-value storage system
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2010 Liquidbit Ltd.
+//
+// Licensed under the same terms of Redis and ServiceStack: new BSD license.
+//
+
+using System.Collections.Generic;
+using ServiceStack.DesignPatterns.Model;
+
+namespace ServiceStack.Redis.Generic
+{
+	public interface IRedisSortedSet<T> : ICollection<T>, IHasStringId
+	{
+		T PopItemWithHighestScore();
+		T PopItemWithLowestScore();
+		double IncrementItem(T item, double incrementBy);
+		int IndexOf(T item);
+		int IndexOfDescending(T item);
+		List<T> GetAll();
+		List<T> GetAllDescending();
+		List<T> GetRange(int fromRank, int toRank);
+		List<T> GetRangeByLowestScore(double fromScore, double toScore);
+		List<T> GetRangeByLowestScore(double fromScore, double toScore, int? skip, int? take);
+		List<T> GetRangeByHighestScore(double fromScore, double toScore);
+		List<T> GetRangeByHighestScore(double fromScore, double toScore, int? skip, int? take);
+		int RemoveRange(int minRank, int maxRank);
+		int RemoveRangeByScore(double fromScore, double toScore);
+		double GetItemScore(T item);
+		int PopulateWithIntersectOf(params IRedisSortedSet<T>[] setIds);
+		int PopulateWithUnionOf(params IRedisSortedSet<T>[] setIds);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Generic/IRedisTransaction.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Generic/IRedisTransaction.cs
new file mode 100644
index 0000000..2603fe1
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Generic/IRedisTransaction.cs
@@ -0,0 +1,26 @@
+//
+// https://github.com/mythz/ServiceStack.Redis
+// ServiceStack.Redis: ECMA CLI Binding to the Redis key-value storage system
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2010 Liquidbit Ltd.
+//
+// Licensed under the same terms of Redis and ServiceStack: new BSD license.
+//
+
+using System;
+
+namespace ServiceStack.Redis.Generic
+{
+    /// <summary>
+    /// Redis transaction for typed client
+    /// </summary>
+    /// <typeparam name="T"></typeparam>
+	public interface IRedisTypedTransaction<T>: IRedisTypedQueueableOperation<T>, IDisposable
+	{
+		bool Commit();
+		void Rollback();
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Generic/IRedisTypedClient.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Generic/IRedisTypedClient.cs
new file mode 100644
index 0000000..2635d3e
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Generic/IRedisTypedClient.cs
@@ -0,0 +1,188 @@
+//
+// https://github.com/mythz/ServiceStack.Redis
+// ServiceStack.Redis: ECMA CLI Binding to the Redis key-value storage system
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2010 Liquidbit Ltd.
+//
+// Licensed under the same terms of Redis and ServiceStack: new BSD license.
+//
+
+using System;
+using System.Collections.Generic;
+using ServiceStack.DataAccess;
+using ServiceStack.DesignPatterns.Model;
+
+namespace ServiceStack.Redis.Generic
+{
+	public interface IRedisTypedClient<T>
+		: IBasicPersistenceProvider<T>
+	{
+		IHasNamed<IRedisList<T>> Lists { get; set; }
+		IHasNamed<IRedisSet<T>> Sets { get; set; }
+		IHasNamed<IRedisSortedSet<T>> SortedSets { get; set; }
+		IRedisHash<TKey, T> GetHash<TKey>(string hashId);
+
+		IRedisTypedTransaction<T> CreateTransaction();
+        IRedisTypedPipeline<T> CreatePipeline();
+
+        IRedisClient RedisClient { get; }
+		
+		IDisposable AcquireLock();
+		IDisposable AcquireLock(TimeSpan timeOut);
+
+		int Db { get; set; }
+		List<string> GetAllKeys();
+		IRedisSet TypeIdsSet { get; }
+
+		T this[string key] { get; set; }
+
+		string SequenceKey { get; set; }
+		void SetSequence(int value);
+		long GetNextSequence();
+		long GetNextSequence(int incrBy);
+		RedisKeyType GetEntryType(string key);
+		string GetRandomKey();
+
+		void SetEntry(string key, T value);
+		void SetEntry(string key, T value, TimeSpan expireIn);
+		bool SetEntryIfNotExists(string key, T value);
+		T GetValue(string key);
+		T GetAndSetValue(string key, T value);
+		bool ContainsKey(string key);
+		bool RemoveEntry(string key);
+		bool RemoveEntry(params string[] args);
+		bool RemoveEntry(params IHasStringId[] entities);
+		long IncrementValue(string key);
+		long IncrementValueBy(string key, int count);
+		long DecrementValue(string key);
+		long DecrementValueBy(string key, int count);
+
+		bool ExpireIn(object id, TimeSpan expiresAt);
+		bool ExpireAt(object id, DateTime dateTime);
+		bool ExpireEntryIn(string key, TimeSpan expiresAt);
+		bool ExpireEntryAt(string key, DateTime dateTime);
+
+		TimeSpan GetTimeToLive(string key);
+		void Save();
+		void SaveAsync();
+		void FlushDb();
+		void FlushAll();
+		T[] SearchKeys(string pattern);
+		List<T> GetValues(List<string> keys);
+		List<T> GetSortedEntryValues(IRedisSet<T> fromSet, int startingFrom, int endingAt);
+
+	    void StoreAsHash(T entity);
+	    T GetFromHash(object id);
+
+		//Set operations
+		HashSet<T> GetAllItemsFromSet(IRedisSet<T> fromSet);
+		void AddItemToSet(IRedisSet<T> toSet, T item);
+		void RemoveItemFromSet(IRedisSet<T> fromSet, T item);
+		T PopItemFromSet(IRedisSet<T> fromSet);
+		void MoveBetweenSets(IRedisSet<T> fromSet, IRedisSet<T> toSet, T item);
+		int GetSetCount(IRedisSet<T> set);
+		bool SetContainsItem(IRedisSet<T> set, T item);
+		HashSet<T> GetIntersectFromSets(params IRedisSet<T>[] sets);
+		void StoreIntersectFromSets(IRedisSet<T> intoSet, params IRedisSet<T>[] sets);
+		HashSet<T> GetUnionFromSets(params IRedisSet<T>[] sets);
+		void StoreUnionFromSets(IRedisSet<T> intoSet, params IRedisSet<T>[] sets);
+		HashSet<T> GetDifferencesFromSet(IRedisSet<T> fromSet, params IRedisSet<T>[] withSets);
+		void StoreDifferencesFromSet(IRedisSet<T> intoSet, IRedisSet<T> fromSet, params IRedisSet<T>[] withSets);
+		T GetRandomItemFromSet(IRedisSet<T> fromSet);
+
+		//List operations
+		List<T> GetAllItemsFromList(IRedisList<T> fromList);
+		List<T> GetRangeFromList(IRedisList<T> fromList, int startingFrom, int endingAt);
+		List<T> SortList(IRedisList<T> fromList, int startingFrom, int endingAt);
+		void AddItemToList(IRedisList<T> fromList, T value);
+		void PrependItemToList(IRedisList<T> fromList, T value);
+		T RemoveStartFromList(IRedisList<T> fromList);
+		T BlockingRemoveStartFromList(IRedisList<T> fromList, TimeSpan? timeOut);
+		T RemoveEndFromList(IRedisList<T> fromList);
+		void RemoveAllFromList(IRedisList<T> fromList);
+		void TrimList(IRedisList<T> fromList, int keepStartingFrom, int keepEndingAt);
+		int RemoveItemFromList(IRedisList<T> fromList, T value);
+		int RemoveItemFromList(IRedisList<T> fromList, T value, int noOfMatches);
+		int GetListCount(IRedisList<T> fromList);
+		T GetItemFromList(IRedisList<T> fromList, int listIndex);
+		void SetItemInList(IRedisList<T> toList, int listIndex, T value);
+
+		//Queue operations
+		void EnqueueItemOnList(IRedisList<T> fromList, T item);
+		T DequeueItemFromList(IRedisList<T> fromList);
+		T BlockingDequeueItemFromList(IRedisList<T> fromList, TimeSpan? timeOut);
+		
+		//Stack operations
+		void PushItemToList(IRedisList<T> fromList, T item);
+		T PopItemFromList(IRedisList<T> fromList);
+		T BlockingPopItemFromList(IRedisList<T> fromList, TimeSpan? timeOut);
+		T PopAndPushItemBetweenLists(IRedisList<T> fromList, IRedisList<T> toList);
+
+		//Sorted Set operations
+		void AddItemToSortedSet(IRedisSortedSet<T> toSet, T value);
+		void AddItemToSortedSet(IRedisSortedSet<T> toSet, T value, double score);
+		bool RemoveItemFromSortedSet(IRedisSortedSet<T> fromSet, T value);
+		T PopItemWithLowestScoreFromSortedSet(IRedisSortedSet<T> fromSet);
+		T PopItemWithHighestScoreFromSortedSet(IRedisSortedSet<T> fromSet);
+		bool SortedSetContainsItem(IRedisSortedSet<T> set, T value);
+		double IncrementItemInSortedSet(IRedisSortedSet<T> set, T value, double incrementBy);
+		int GetItemIndexInSortedSet(IRedisSortedSet<T> set, T value);
+		int GetItemIndexInSortedSetDesc(IRedisSortedSet<T> set, T value);
+		List<T> GetAllItemsFromSortedSet(IRedisSortedSet<T> set);
+		List<T> GetAllItemsFromSortedSetDesc(IRedisSortedSet<T> set);
+		List<T> GetRangeFromSortedSet(IRedisSortedSet<T> set, int fromRank, int toRank);
+		List<T> GetRangeFromSortedSetDesc(IRedisSortedSet<T> set, int fromRank, int toRank);
+		IDictionary<T, double> GetAllWithScoresFromSortedSet(IRedisSortedSet<T> set);
+		IDictionary<T, double> GetRangeWithScoresFromSortedSet(IRedisSortedSet<T> set, int fromRank, int toRank);
+		IDictionary<T, double> GetRangeWithScoresFromSortedSetDesc(IRedisSortedSet<T> set, int fromRank, int toRank);
+		List<T> GetRangeFromSortedSetByLowestScore(IRedisSortedSet<T> set, string fromStringScore, string toStringScore);
+		List<T> GetRangeFromSortedSetByLowestScore(IRedisSortedSet<T> set, string fromStringScore, string toStringScore, int? skip, int? take);
+		List<T> GetRangeFromSortedSetByLowestScore(IRedisSortedSet<T> set, double fromScore, double toScore);
+		List<T> GetRangeFromSortedSetByLowestScore(IRedisSortedSet<T> set, double fromScore, double toScore, int? skip, int? take);
+		IDictionary<T, double> GetRangeWithScoresFromSortedSetByLowestScore(IRedisSortedSet<T> set, string fromStringScore, string toStringScore);
+		IDictionary<T, double> GetRangeWithScoresFromSortedSetByLowestScore(IRedisSortedSet<T> set, string fromStringScore, string toStringScore, int? skip, int? take);
+		IDictionary<T, double> GetRangeWithScoresFromSortedSetByLowestScore(IRedisSortedSet<T> set, double fromScore, double toScore);
+		IDictionary<T, double> GetRangeWithScoresFromSortedSetByLowestScore(IRedisSortedSet<T> set, double fromScore, double toScore, int? skip, int? take);
+		List<T> GetRangeFromSortedSetByHighestScore(IRedisSortedSet<T> set, string fromStringScore, string toStringScore);
+		List<T> GetRangeFromSortedSetByHighestScore(IRedisSortedSet<T> set, string fromStringScore, string toStringScore, int? skip, int? take);
+		List<T> GetRangeFromSortedSetByHighestScore(IRedisSortedSet<T> set, double fromScore, double toScore);
+		List<T> GetRangeFromSortedSetByHighestScore(IRedisSortedSet<T> set, double fromScore, double toScore, int? skip, int? take);
+		IDictionary<T, double> GetRangeWithScoresFromSortedSetByHighestScore(IRedisSortedSet<T> set, string fromStringScore, string toStringScore);
+		IDictionary<T, double> GetRangeWithScoresFromSortedSetByHighestScore(IRedisSortedSet<T> set, string fromStringScore, string toStringScore, int? skip, int? take);
+		IDictionary<T, double> GetRangeWithScoresFromSortedSetByHighestScore(IRedisSortedSet<T> set, double fromScore, double toScore);
+		IDictionary<T, double> GetRangeWithScoresFromSortedSetByHighestScore(IRedisSortedSet<T> set, double fromScore, double toScore, int? skip, int? take);
+		int RemoveRangeFromSortedSet(IRedisSortedSet<T> set, int minRank, int maxRank);
+		int RemoveRangeFromSortedSetByScore(IRedisSortedSet<T> set, double fromScore, double toScore);
+		int GetSortedSetCount(IRedisSortedSet<T> set);
+		double GetItemScoreInSortedSet(IRedisSortedSet<T> set, T value);
+		int StoreIntersectFromSortedSets(IRedisSortedSet<T> intoSetId, params IRedisSortedSet<T>[] setIds);
+		int StoreUnionFromSortedSets(IRedisSortedSet<T> intoSetId, params IRedisSortedSet<T>[] setIds);
+		
+		//Hash operations
+		bool HashContainsEntry<TKey>(IRedisHash<TKey, T> hash, TKey key);
+		bool SetEntryInHash<TKey>(IRedisHash<TKey, T> hash, TKey key, T value);
+		bool SetEntryInHashIfNotExists<TKey>(IRedisHash<TKey, T> hash, TKey key, T value);
+		void SetRangeInHash<TKey>(IRedisHash<TKey, T> hash, IEnumerable<KeyValuePair<TKey, T>> keyValuePairs);
+		T GetValueFromHash<TKey>(IRedisHash<TKey, T> hash, TKey key);
+		bool RemoveEntryFromHash<TKey>(IRedisHash<TKey, T> hash, TKey key);
+		int GetHashCount<TKey>(IRedisHash<TKey, T> hash);
+		List<TKey> GetHashKeys<TKey>(IRedisHash<TKey, T> hash);
+		List<T> GetHashValues<TKey>(IRedisHash<TKey, T> hash);
+		Dictionary<TKey, T> GetAllEntriesFromHash<TKey>(IRedisHash<TKey, T> hash);
+
+		//Useful common app-logic 
+		void StoreRelatedEntities<TChild>(object parentId, List<TChild> children);
+		void StoreRelatedEntities<TChild>(object parentId, params TChild[] children);
+		void DeleteRelatedEntities<TChild>(object parentId);
+		void DeleteRelatedEntity<TChild>(object parentId, object childId);
+		List<TChild> GetRelatedEntities<TChild>(object parentId);
+		int GetRelatedEntitiesCount<TChild>(object parentId);
+		void AddToRecentsList(T value);
+		List<T> GetLatestFromRecentsList(int skip, int take);
+		List<T> GetEarliestFromRecentsList(int skip, int take);
+	}
+
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Generic/IRedisTypedPipeline.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Generic/IRedisTypedPipeline.cs
new file mode 100644
index 0000000..84b551f
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Generic/IRedisTypedPipeline.cs
@@ -0,0 +1,11 @@
+using ServiceStack.Redis.Pipeline;
+
+namespace ServiceStack.Redis.Generic
+{
+    /// <summary>
+    /// Interface to redis typed pipeline
+    /// </summary>
+    public interface IRedisTypedPipeline<T> : IRedisPipelineShared, IRedisTypedQueueableOperation<T>
+    {
+    }
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Generic/IRedisTypedQueueableOperation.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Generic/IRedisTypedQueueableOperation.cs
new file mode 100644
index 0000000..198ad98
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Generic/IRedisTypedQueueableOperation.cs
@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+
+namespace ServiceStack.Redis.Generic
+{
+    /// <summary>
+    /// interface to queueable operation using typed redis client
+    /// </summary>
+    /// <typeparam name="T"></typeparam>
+    public interface IRedisTypedQueueableOperation<T>
+    {
+        void QueueCommand(Action<IRedisTypedClient<T>> command);
+        void QueueCommand(Action<IRedisTypedClient<T>> command, Action onSuccessCallback);
+        void QueueCommand(Action<IRedisTypedClient<T>> command, Action onSuccessCallback, Action<Exception> onErrorCallback);
+
+        void QueueCommand(Func<IRedisTypedClient<T>, int> command);
+        void QueueCommand(Func<IRedisTypedClient<T>, int> command, Action<int> onSuccessCallback);
+        void QueueCommand(Func<IRedisTypedClient<T>, int> command, Action<int> onSuccessCallback, Action<Exception> onErrorCallback);
+
+        void QueueCommand(Func<IRedisTypedClient<T>, long> command);
+        void QueueCommand(Func<IRedisTypedClient<T>, long> command, Action<long> onSuccessCallback);
+        void QueueCommand(Func<IRedisTypedClient<T>, long> command, Action<long> onSuccessCallback, Action<Exception> onErrorCallback);
+
+        void QueueCommand(Func<IRedisTypedClient<T>, bool> command);
+        void QueueCommand(Func<IRedisTypedClient<T>, bool> command, Action<bool> onSuccessCallback);
+        void QueueCommand(Func<IRedisTypedClient<T>, bool> command, Action<bool> onSuccessCallback, Action<Exception> onErrorCallback);
+
+        void QueueCommand(Func<IRedisTypedClient<T>, double> command);
+        void QueueCommand(Func<IRedisTypedClient<T>, double> command, Action<double> onSuccessCallback);
+        void QueueCommand(Func<IRedisTypedClient<T>, double> command, Action<double> onSuccessCallback, Action<Exception> onErrorCallback);
+
+        void QueueCommand(Func<IRedisTypedClient<T>, byte[]> command);
+        void QueueCommand(Func<IRedisTypedClient<T>, byte[]> command, Action<byte[]> onSuccessCallback);
+        void QueueCommand(Func<IRedisTypedClient<T>, byte[]> command, Action<byte[]> onSuccessCallback, Action<Exception> onErrorCallback);
+
+        void QueueCommand(Func<IRedisTypedClient<T>, string> command);
+        void QueueCommand(Func<IRedisTypedClient<T>, string> command, Action<string> onSuccessCallback);
+        void QueueCommand(Func<IRedisTypedClient<T>, string> command, Action<string> onSuccessCallback, Action<Exception> onErrorCallback);
+
+        void QueueCommand(Func<IRedisTypedClient<T>, T> command);
+        void QueueCommand(Func<IRedisTypedClient<T>, T> command, Action<T> onSuccessCallback);
+        void QueueCommand(Func<IRedisTypedClient<T>, T> command, Action<T> onSuccessCallback, Action<Exception> onErrorCallback);
+
+        void QueueCommand(Func<IRedisTypedClient<T>, List<string>> command);
+        void QueueCommand(Func<IRedisTypedClient<T>, List<string>> command, Action<List<string>> onSuccessCallback);
+        void QueueCommand(Func<IRedisTypedClient<T>, List<string>> command, Action<List<string>> onSuccessCallback, Action<Exception> onErrorCallback);
+
+        void QueueCommand(Func<IRedisTypedClient<T>, List<T>> command);
+        void QueueCommand(Func<IRedisTypedClient<T>, List<T>> command, Action<List<T>> onSuccessCallback);
+        void QueueCommand(Func<IRedisTypedClient<T>, List<T>> command, Action<List<T>> onSuccessCallback, Action<Exception> onErrorCallback);
+		
+    }
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/IRedisClient.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/IRedisClient.cs
new file mode 100644
index 0000000..b700949
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/IRedisClient.cs
@@ -0,0 +1,269 @@
+//
+// http://code.google.com/p/servicestack/wiki/ServiceStackRedis
+// ServiceStack.Redis: ECMA CLI Binding to the Redis key-value storage system
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2010 Liquidbit Ltd.
+//
+// Licensed under the same terms of Redis and ServiceStack: new BSD license.
+//
+
+using System;
+using System.Collections.Generic;
+using ServiceStack.CacheAccess;
+using ServiceStack.DataAccess;
+using ServiceStack.DesignPatterns.Model;
+using ServiceStack.Redis.Generic;
+using ServiceStack.Redis.Pipeline;
+
+namespace ServiceStack.Redis
+{
+	public interface IRedisClient
+		: IBasicPersistenceProvider, ICacheClient
+	{
+		//Basic Redis Connection operations
+		int Db { get; set; }
+		int DbSize { get; }
+		Dictionary<string, string> Info { get; }
+		DateTime LastSave { get; }
+		string Host { get; }
+		int Port { get; }
+        int ConnectTimeout { get; set; }
+		int RetryTimeout { get; set; }
+		int RetryCount { get; set; }
+		int SendTimeout { get; set; }
+		string Password { get; set; }
+		bool HadExceptions { get; }
+
+		void Save();
+		void SaveAsync();
+		void Shutdown();
+		void RewriteAppendOnlyFileAsync();
+		void FlushDb();
+
+		//Basic Redis Connection Info
+		string this[string key] { get; set; }
+
+		List<string> GetAllKeys();
+		void SetEntry(string key, string value);
+		void SetEntry(string key, string value, TimeSpan expireIn);
+		bool SetEntryIfNotExists(string key, string value);
+	    void SetAll(IEnumerable<string> keys, IEnumerable<string> values);
+	    void SetAll(Dictionary<string, string> map);
+		string GetValue(string key);
+		string GetAndSetEntry(string key, string value);
+		List<string> GetValues(List<string> keys);
+		List<T> GetValues<T>(List<string> keys);
+		Dictionary<string, string> GetValuesMap(List<string> keys);
+		Dictionary<string, T> GetValuesMap<T>(List<string> keys);
+		int AppendToValue(string key, string value);
+		void RenameKey(string fromName, string toName);
+		string GetSubstring(string key, int fromIndex, int toIndex);
+
+        //store POCOs as hash
+	    T GetFromHash<T>(object id);
+	    void StoreAsHash<T>(T entity);
+
+	    object StoreObject(object entity);
+
+		bool ContainsKey(string key);
+		bool RemoveEntry(params string[] args);
+		long IncrementValue(string key);
+		long IncrementValueBy(string key, int count);
+		long DecrementValue(string key);
+		long DecrementValueBy(string key, int count);
+		List<string> SearchKeys(string pattern);
+
+		RedisKeyType GetEntryType(string key);
+		string GetRandomKey();
+		bool ExpireEntryIn(string key, TimeSpan expireIn);
+		bool ExpireEntryAt(string key, DateTime expireAt);
+		TimeSpan GetTimeToLive(string key);
+		List<string> GetSortedEntryValues(string key, int startingFrom, int endingAt);
+
+		//Store entities without registering entity ids
+		void WriteAll<TEntity>(IEnumerable<TEntity> entities);
+
+		/// <summary>
+		/// Returns a high-level typed client API
+		/// Shorter Alias is As<T>();
+		/// </summary>
+		/// <typeparam name="T"></typeparam>
+		IRedisTypedClient<T> GetTypedClient<T>();
+
+		/// <summary>
+		/// Returns a high-level typed client API
+		/// </summary>
+		/// <typeparam name="T"></typeparam>
+		IRedisTypedClient<T> As<T>(); 
+
+		IHasNamed<IRedisList> Lists { get; set; }
+		IHasNamed<IRedisSet> Sets { get; set; }
+		IHasNamed<IRedisSortedSet> SortedSets { get; set; }
+		IHasNamed<IRedisHash> Hashes { get; set; }
+
+		IRedisTransaction CreateTransaction();
+	    IRedisPipeline CreatePipeline();
+
+		IDisposable AcquireLock(string key);
+		IDisposable AcquireLock(string key, TimeSpan timeOut);
+
+		#region Redis pubsub
+
+		void Watch(params string[] keys);
+		void UnWatch();
+		IRedisSubscription CreateSubscription();
+		int PublishMessage(string toChannel, string message);
+
+		#endregion
+
+
+		#region Set operations
+
+		HashSet<string> GetAllItemsFromSet(string setId);
+		void AddItemToSet(string setId, string item);
+		void AddRangeToSet(string setId, List<string> items);
+		void RemoveItemFromSet(string setId, string item);
+		string PopItemFromSet(string setId);
+		void MoveBetweenSets(string fromSetId, string toSetId, string item);
+		int GetSetCount(string setId);
+		bool SetContainsItem(string setId, string item);
+		HashSet<string> GetIntersectFromSets(params string[] setIds);
+		void StoreIntersectFromSets(string intoSetId, params string[] setIds);
+		HashSet<string> GetUnionFromSets(params string[] setIds);
+		void StoreUnionFromSets(string intoSetId, params string[] setIds);
+		HashSet<string> GetDifferencesFromSet(string fromSetId, params string[] withSetIds);
+		void StoreDifferencesFromSet(string intoSetId, string fromSetId, params string[] withSetIds);
+		string GetRandomItemFromSet(string setId);
+
+		#endregion
+
+
+		#region List operations
+
+		List<string> GetAllItemsFromList(string listId);
+		List<string> GetRangeFromList(string listId, int startingFrom, int endingAt);
+		List<string> GetRangeFromSortedList(string listId, int startingFrom, int endingAt);
+		List<string> GetSortedItemsFromList(string listId, SortOptions sortOptions);
+		void AddItemToList(string listId, string value);
+		void AddRangeToList(string listId, List<string> values);
+		void PrependItemToList(string listId, string value);
+		void PrependRangeToList(string listId, List<string> values);
+
+		void RemoveAllFromList(string listId);
+		string RemoveStartFromList(string listId);
+		string BlockingRemoveStartFromList(string listId, TimeSpan? timeOut);
+        ItemRef BlockingRemoveStartFromLists(string []listIds, TimeSpan? timeOut);
+		string RemoveEndFromList(string listId);
+		void TrimList(string listId, int keepStartingFrom, int keepEndingAt);
+		int RemoveItemFromList(string listId, string value);
+		int RemoveItemFromList(string listId, string value, int noOfMatches);
+		int GetListCount(string listId);
+		string GetItemFromList(string listId, int listIndex);
+		void SetItemInList(string listId, int listIndex, string value);
+
+		//Queue operations
+		void EnqueueItemOnList(string listId, string value);
+		string DequeueItemFromList(string listId);
+		string BlockingDequeueItemFromList(string listId, TimeSpan? timeOut);
+        ItemRef BlockingDequeueItemFromLists(string []listIds, TimeSpan? timeOut);
+
+		//Stack operations
+		void PushItemToList(string listId, string value);
+		string PopItemFromList(string listId);
+		string BlockingPopItemFromList(string listId, TimeSpan? timeOut);
+        ItemRef BlockingPopItemFromLists(string []listIds, TimeSpan? timeOut);
+		string PopAndPushItemBetweenLists(string fromListId, string toListId);
+
+		#endregion
+
+
+		#region Sorted Set operations
+
+		bool AddItemToSortedSet(string setId, string value);
+		bool AddItemToSortedSet(string setId, string value, double score);
+		bool AddRangeToSortedSet(string setId, List<string> values, double score);
+		bool AddRangeToSortedSet(string setId, List<string> values, long score);
+		bool RemoveItemFromSortedSet(string setId, string value);
+		string PopItemWithLowestScoreFromSortedSet(string setId);
+		string PopItemWithHighestScoreFromSortedSet(string setId);
+		bool SortedSetContainsItem(string setId, string value);
+		double IncrementItemInSortedSet(string setId, string value, double incrementBy);
+		double IncrementItemInSortedSet(string setId, string value, long incrementBy);
+		int GetItemIndexInSortedSet(string setId, string value);
+		int GetItemIndexInSortedSetDesc(string setId, string value);
+		List<string> GetAllItemsFromSortedSet(string setId);
+		List<string> GetAllItemsFromSortedSetDesc(string setId);
+		List<string> GetRangeFromSortedSet(string setId, int fromRank, int toRank);
+		List<string> GetRangeFromSortedSetDesc(string setId, int fromRank, int toRank);
+		IDictionary<string, double> GetAllWithScoresFromSortedSet(string setId);
+		IDictionary<string, double> GetRangeWithScoresFromSortedSet(string setId, int fromRank, int toRank);
+		IDictionary<string, double> GetRangeWithScoresFromSortedSetDesc(string setId, int fromRank, int toRank);
+		List<string> GetRangeFromSortedSetByLowestScore(string setId, string fromStringScore, string toStringScore);
+		List<string> GetRangeFromSortedSetByLowestScore(string setId, string fromStringScore, string toStringScore, int? skip, int? take);
+		List<string> GetRangeFromSortedSetByLowestScore(string setId, double fromScore, double toScore);
+		List<string> GetRangeFromSortedSetByLowestScore(string setId, long fromScore, long toScore);
+		List<string> GetRangeFromSortedSetByLowestScore(string setId, double fromScore, double toScore, int? skip, int? take);
+		List<string> GetRangeFromSortedSetByLowestScore(string setId, long fromScore, long toScore, int? skip, int? take);
+		IDictionary<string, double> GetRangeWithScoresFromSortedSetByLowestScore(string setId, string fromStringScore, string toStringScore);
+		IDictionary<string, double> GetRangeWithScoresFromSortedSetByLowestScore(string setId, string fromStringScore, string toStringScore, int? skip, int? take);
+		IDictionary<string, double> GetRangeWithScoresFromSortedSetByLowestScore(string setId, double fromScore, double toScore);
+		IDictionary<string, double> GetRangeWithScoresFromSortedSetByLowestScore(string setId, long fromScore, long toScore);
+		IDictionary<string, double> GetRangeWithScoresFromSortedSetByLowestScore(string setId, double fromScore, double toScore, int? skip, int? take);
+		IDictionary<string, double> GetRangeWithScoresFromSortedSetByLowestScore(string setId, long fromScore, long toScore, int? skip, int? take);
+		List<string> GetRangeFromSortedSetByHighestScore(string setId, string fromStringScore, string toStringScore);
+		List<string> GetRangeFromSortedSetByHighestScore(string setId, string fromStringScore, string toStringScore, int? skip, int? take);
+		List<string> GetRangeFromSortedSetByHighestScore(string setId, double fromScore, double toScore);
+		List<string> GetRangeFromSortedSetByHighestScore(string setId, long fromScore, long toScore);
+		List<string> GetRangeFromSortedSetByHighestScore(string setId, double fromScore, double toScore, int? skip, int? take);
+		List<string> GetRangeFromSortedSetByHighestScore(string setId, long fromScore, long toScore, int? skip, int? take);
+		IDictionary<string, double> GetRangeWithScoresFromSortedSetByHighestScore(string setId, string fromStringScore, string toStringScore);
+		IDictionary<string, double> GetRangeWithScoresFromSortedSetByHighestScore(string setId, string fromStringScore, string toStringScore, int? skip, int? take);
+		IDictionary<string, double> GetRangeWithScoresFromSortedSetByHighestScore(string setId, double fromScore, double toScore);
+		IDictionary<string, double> GetRangeWithScoresFromSortedSetByHighestScore(string setId, long fromScore, long toScore);
+		IDictionary<string, double> GetRangeWithScoresFromSortedSetByHighestScore(string setId, double fromScore, double toScore, int? skip, int? take);
+		IDictionary<string, double> GetRangeWithScoresFromSortedSetByHighestScore(string setId, long fromScore, long toScore, int? skip, int? take);
+		int RemoveRangeFromSortedSet(string setId, int minRank, int maxRank);
+		int RemoveRangeFromSortedSetByScore(string setId, double fromScore, double toScore);
+		int RemoveRangeFromSortedSetByScore(string setId, long fromScore, long toScore);
+        int GetSortedSetCount(string setId);
+        int GetSortedSetCount(string setId, string fromStringScore, string toStringScore);
+        int GetSortedSetCount(string setId, long fromScore, long toScore);
+        int GetSortedSetCount(string setId, double fromScore, double toScore);
+		double GetItemScoreInSortedSet(string setId, string value);
+		int StoreIntersectFromSortedSets(string intoSetId, params string[] setIds);
+		int StoreUnionFromSortedSets(string intoSetId, params string[] setIds);
+
+		#endregion
+
+
+		#region Hash operations
+
+		bool HashContainsEntry(string hashId, string key);
+		bool SetEntryInHash(string hashId, string key, string value);
+		bool SetEntryInHashIfNotExists(string hashId, string key, string value);
+		void SetRangeInHash(string hashId, IEnumerable<KeyValuePair<string, string>> keyValuePairs);
+		int IncrementValueInHash(string hashId, string key, int incrementBy);
+		string GetValueFromHash(string hashId, string key);
+		List<string> GetValuesFromHash(string hashId, params string[] keys);
+		bool RemoveEntryFromHash(string hashId, string key);
+		int GetHashCount(string hashId);
+		List<string> GetHashKeys(string hashId);
+		List<string> GetHashValues(string hashId);
+		Dictionary<string, string> GetAllEntriesFromHash(string hashId);
+
+		#endregion
+
+
+		#region Eval/Lua operations
+
+		string GetEvalStr(string body, int numOfArgs, params string[] args);
+		int GetEvalInt(string body, int numOfArgs, params string[] args);
+		List<string> GetEvalMultiData(string body, int numOfArgs, params string[] args);
+
+		#endregion
+
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/IRedisClientCacheManager.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/IRedisClientCacheManager.cs
new file mode 100644
index 0000000..a900e73
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/IRedisClientCacheManager.cs
@@ -0,0 +1,45 @@
+//
+// https://github.com/mythz/ServiceStack.Redis
+// ServiceStack.Redis: ECMA CLI Binding to the Redis key-value storage system
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2010 Liquidbit Ltd.
+//
+// Licensed under the same terms of Redis and ServiceStack: new BSD license.
+//
+
+using System;
+using ServiceStack.CacheAccess;
+
+namespace ServiceStack.Redis
+{
+	public interface IRedisClientCacheManager 
+		: IDisposable
+	{
+		/// <summary>
+		/// Returns a Read/Write client (The default) using the hosts defined in ReadWriteHosts
+		/// </summary>
+		/// <returns></returns>
+		IRedisClient GetClient();
+
+		/// <summary>
+		/// Returns a ReadOnly client using the hosts defined in ReadOnlyHosts.
+		/// </summary>
+		/// <returns></returns>
+		IRedisClient GetReadOnlyClient();
+
+		/// <summary>
+		/// Returns a Read/Write ICacheClient (The default) using the hosts defined in ReadWriteHosts
+		/// </summary>
+		/// <returns></returns>
+		ICacheClient GetCacheClient();
+
+		/// <summary>
+		/// Returns a ReadOnly ICacheClient using the hosts defined in ReadOnlyHosts.
+		/// </summary>
+		/// <returns></returns>
+		ICacheClient GetReadOnlyCacheClient();
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/IRedisClientsManager.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/IRedisClientsManager.cs
new file mode 100644
index 0000000..6e40ef4
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/IRedisClientsManager.cs
@@ -0,0 +1,44 @@
+//
+// https://github.com/mythz/ServiceStack.Redis
+// ServiceStack.Redis: ECMA CLI Binding to the Redis key-value storage system
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2010 Liquidbit Ltd.
+//
+// Licensed under the same terms of Redis and ServiceStack: new BSD license.
+//
+
+using System;
+using ServiceStack.CacheAccess;
+
+namespace ServiceStack.Redis
+{
+	public interface IRedisClientsManager : IDisposable 
+	{
+		/// <summary>
+		/// Returns a Read/Write client (The default) using the hosts defined in ReadWriteHosts
+		/// </summary>
+		/// <returns></returns>
+		IRedisClient GetClient();
+
+		/// <summary>
+		/// Returns a ReadOnly client using the hosts defined in ReadOnlyHosts.
+		/// </summary>
+		/// <returns></returns>
+		IRedisClient GetReadOnlyClient();
+
+		/// <summary>
+		/// Returns a Read/Write ICacheClient (The default) using the hosts defined in ReadWriteHosts
+		/// </summary>
+		/// <returns></returns>
+		ICacheClient GetCacheClient();
+
+		/// <summary>
+		/// Returns a ReadOnly ICacheClient using the hosts defined in ReadOnlyHosts.
+		/// </summary>
+		/// <returns></returns>
+		ICacheClient GetReadOnlyCacheClient();
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/IRedisHash.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/IRedisHash.cs
new file mode 100644
index 0000000..cf508bd
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/IRedisHash.cs
@@ -0,0 +1,13 @@
+using System.Collections.Generic;
+using ServiceStack.DesignPatterns.Model;
+
+namespace ServiceStack.Redis
+{
+	public interface IRedisHash
+		: IDictionary<string, string>, IHasStringId
+	{
+		bool AddIfNotExists(KeyValuePair<string, string> item);
+		void AddRange(IEnumerable<KeyValuePair<string, string>> items);
+		int IncrementValue(string key, int incrementBy);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/IRedisList.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/IRedisList.cs
new file mode 100644
index 0000000..1116dac
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/IRedisList.cs
@@ -0,0 +1,45 @@
+//
+// https://github.com/mythz/ServiceStack.Redis
+// ServiceStack.Redis: ECMA CLI Binding to the Redis key-value storage system
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2010 Liquidbit Ltd.
+//
+// Licensed under the same terms of Redis and ServiceStack: new BSD license.
+//
+
+using System;
+using System.Collections.Generic;
+using ServiceStack.DesignPatterns.Model;
+
+namespace ServiceStack.Redis
+{
+	public interface IRedisList
+		: IList<string>, IHasStringId
+	{
+		List<string> GetAll();
+		List<string> GetRange(int startingFrom, int endingAt);
+		List<string> GetRangeFromSortedList(int startingFrom, int endingAt);
+		void RemoveAll();
+		void Trim(int keepStartingFrom, int keepEndingAt);
+		int RemoveValue(string value);
+		int RemoveValue(string value, int noOfMatches);
+
+		void Prepend(string value);
+		void Append(string value);
+		string RemoveStart();
+		string BlockingRemoveStart(TimeSpan? timeOut);
+		string RemoveEnd();
+
+		void Enqueue(string value);
+		string Dequeue();
+		string BlockingDequeue(TimeSpan? timeOut);
+
+		void Push(string value);
+		string Pop();
+		string BlockingPop(TimeSpan? timeOut);
+		string PopAndPush(IRedisList toList);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/IRedisNativeClient.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/IRedisNativeClient.cs
new file mode 100644
index 0000000..a3e5b26
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/IRedisNativeClient.cs
@@ -0,0 +1,194 @@
+//
+// http://code.google.com/p/servicestack/wiki/ServiceStackRedis
+// ServiceStack.Redis: ECMA CLI Binding to the Redis key-value storage system
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2010 Liquidbit Ltd.
+//
+// Licensed under the same terms of Redis and ServiceStack: new BSD license.
+//
+
+using System;
+using System.Collections.Generic;
+
+namespace ServiceStack.Redis
+{
+	public interface IRedisNativeClient
+		: IDisposable
+	{
+		//Redis utility operations
+		Dictionary<string, string> Info { get; }
+		int Db { get; set; }
+		int DbSize { get; }
+		DateTime LastSave { get; }
+		void Save();
+		void BgSave();
+		void Shutdown();
+		void BgRewriteAof();
+		void Quit();
+		void FlushDb();
+		void FlushAll();
+		bool Ping();
+		string Echo(string text);
+		void SlaveOf(string hostname, int port);
+		void SlaveOfNoOne();
+		byte[][] ConfigGet(string pattern);
+		void ConfigSet(string item, byte[] value);
+		void ConfigResetStat();
+		byte[][] Time();
+		void DebugSegfault();
+		byte[] Dump(string key);
+		byte[] Restore(string key, long expireMs, byte[] dumpValue);
+		void Migrate(string host, int port, int destinationDb, long timeoutMs);
+		bool Move(string key, int db);
+		int ObjectIdleTime(string key);
+
+		//Common key-value Redis operations
+		byte[][] Keys(string pattern);
+		int Exists(string key);
+		int StrLen(string key);
+		void Set(string key, byte[] value);
+		void SetEx(string key, int expireInSeconds, byte[] value);
+		bool Persist(string key);
+		void PSetEx(string key, long expireInMs, byte[] value);
+		int SetNX(string key, byte[] value);
+		void MSet(byte[][] keys, byte[][] values);
+		void MSet(string[] keys, byte[][] values);
+		bool MSetNx(byte[][] keys, byte[][] values);
+		bool MSetNx(string[] keys, byte[][] values);
+		byte[] Get(string key);
+		byte[] GetSet(string key, byte[] value);
+		byte[][] MGet(params byte[][] keys);
+		byte[][] MGet(params string[] keys);
+		int Del(string key);
+		int Del(params string[] keys);
+		long Incr(string key);
+		long IncrBy(string key, int incrBy);
+		double IncrByFloat(string key, double incrBy);
+		long Decr(string key);
+		long DecrBy(string key, int decrBy);
+		int Append(string key, byte[] value);
+		[Obsolete("Was renamed to GetRange in 2.4")]
+		byte[] Substr(string key, int fromIndex, int toIndex);
+		byte[] GetRange(string key, int fromIndex, int toIndex);
+		int SetRange(string key, int offset, byte[] value);
+		int GetBit(string key, int offset);
+		int SetBit(string key, int offset, int value);
+		
+		string RandomKey();
+		void Rename(string oldKeyname, string newKeyname);
+		bool RenameNx(string oldKeyname, string newKeyname);
+		bool Expire(string key, int seconds);
+		bool PExpire(string key, long ttlMs);
+		bool ExpireAt(string key, long unixTime);
+		bool PExpireAt(string key, long unixTimeMs);
+		int Ttl(string key);
+		long PTtl(string key);
+
+		//Redis Sort operation (works on lists, sets or hashes)
+		byte[][] Sort(string listOrSetId, SortOptions sortOptions);
+
+		//Redis List operations
+		byte[][] LRange(string listId, int startingFrom, int endingAt);
+		int RPush(string listId, byte[] value);
+		int RPushX(string listId, byte[] value);
+		int LPush(string listId, byte[] value);
+		int LPushX(string listId, byte[] value);
+		void LTrim(string listId, int keepStartingFrom, int keepEndingAt);
+		int LRem(string listId, int removeNoOfMatches, byte[] value);
+		int LLen(string listId);
+		byte[] LIndex(string listId, int listIndex);
+		void LSet(string listId, int listIndex, byte[] value);
+		byte[] LPop(string listId);
+		byte[] RPop(string listId);
+		byte[][] BLPop(string listId, int timeOutSecs);
+	    byte[][] BLPop(string[] listIds, int timeOutSecs);
+		byte[] BLPopValue(string listId, int timeOutSecs);
+	    byte[][] BLPopValue(string[] listIds, int timeOutSecs);
+		byte[][] BRPop(string listId, int timeOutSecs);
+	    byte[][] BRPop(string[] listIds, int timeOutSecs);
+		byte[] RPopLPush(string fromListId, string toListId);
+		byte[] BRPopValue(string listId, int timeOutSecs);
+	    byte[][] BRPopValue(string[] listIds, int timeOutSecs);
+
+		//Redis Set operations
+		byte[][] SMembers(string setId);
+		int SAdd(string setId, byte[] value);
+		int SRem(string setId, byte[] value);
+		byte[] SPop(string setId);
+		void SMove(string fromSetId, string toSetId, byte[] value);
+		int SCard(string setId);
+		int SIsMember(string setId, byte[] value);
+		byte[][] SInter(params string[] setIds);
+		void SInterStore(string intoSetId, params string[] setIds);
+		byte[][] SUnion(params string[] setIds);
+		void SUnionStore(string intoSetId, params string[] setIds);
+		byte[][] SDiff(string fromSetId, params string[] withSetIds);
+		void SDiffStore(string intoSetId, string fromSetId, params string[] withSetIds);
+		byte[] SRandMember(string setId);
+
+
+		//Redis Sorted Set operations
+		int ZAdd(string setId, double score, byte[] value);
+		int ZAdd(string setId, long score, byte[] value);
+		int ZRem(string setId, byte[] value);
+		double ZIncrBy(string setId, double incrBy, byte[] value);
+		double ZIncrBy(string setId, long incrBy, byte[] value);
+		int ZRank(string setId, byte[] value);
+		int ZRevRank(string setId, byte[] value);
+		byte[][] ZRange(string setId, int min, int max);
+		byte[][] ZRangeWithScores(string setId, int min, int max);
+		byte[][] ZRevRange(string setId, int min, int max);
+		byte[][] ZRevRangeWithScores(string setId, int min, int max);
+		byte[][] ZRangeByScore(string setId, double min, double max, int? skip, int? take);
+		byte[][] ZRangeByScore(string setId, long min, long max, int? skip, int? take);
+		byte[][] ZRangeByScoreWithScores(string setId, double min, double max, int? skip, int? take);
+		byte[][] ZRangeByScoreWithScores(string setId, long min, long max, int? skip, int? take);
+		byte[][] ZRevRangeByScore(string setId, double min, double max, int? skip, int? take);
+		byte[][] ZRevRangeByScore(string setId, long min, long max, int? skip, int? take);
+		byte[][] ZRevRangeByScoreWithScores(string setId, double min, double max, int? skip, int? take);
+		byte[][] ZRevRangeByScoreWithScores(string setId, long min, long max, int? skip, int? take);
+		int ZRemRangeByRank(string setId, int min, int max);
+		int ZRemRangeByScore(string setId, double fromScore, double toScore);
+		int ZRemRangeByScore(string setId, long fromScore, long toScore);
+		int ZCard(string setId);
+		double ZScore(string setId, byte[] value);
+		int ZUnionStore(string intoSetId, params string[] setIds);
+		int ZInterStore(string intoSetId, params string[] setIds);
+
+		//Redis Hash operations
+		int HSet(string hashId, byte[] key, byte[] value);
+		void HMSet(string hashId, byte[][] keys, byte[][] values);
+		int HSetNX(string hashId, byte[] key, byte[] value);
+		int HIncrby(string hashId, byte[] key, int incrementBy);
+		double HIncrbyFloat(string hashId, byte[] key, double incrementBy);
+		byte[] HGet(string hashId, byte[] key);
+		byte[][] HMGet(string hashId, params byte[][] keys);
+		int HDel(string hashId, byte[] key);
+		int HExists(string hashId, byte[] key);
+		int HLen(string hashId);
+		byte[][] HKeys(string hashId);
+		byte[][] HVals(string hashId);
+		byte[][] HGetAll(string hashId);
+
+		//Redis Pub/Sub operations
+		void Watch(params string[] keys);
+		void UnWatch();
+		int Publish(string toChannel, byte[] message);
+		byte[][] Subscribe(params string[] toChannels);
+		byte[][] UnSubscribe(params string[] toChannels);
+		byte[][] PSubscribe(params string[] toChannelsMatchingPatterns);
+		byte[][] PUnSubscribe(params string[] toChannelsMatchingPatterns);
+		byte[][] ReceiveMessages();
+
+		int EvalInt(string body, int numberKeysInArgs, params byte[][] keys);
+		string EvalStr(string body, int numberKeysInArgs, params byte[][] keys);
+		byte[][] Eval(string body, int numberKeysInArgs, params byte[][] keys);
+		byte[][] ScriptExists(params byte[][] sha1Refs);
+		void ScriptFlush();
+		void ScriptKill();
+		byte[] ScriptLoad(string body);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/IRedisSet.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/IRedisSet.cs
new file mode 100644
index 0000000..983ebe4
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/IRedisSet.cs
@@ -0,0 +1,33 @@
+//
+// https://github.com/mythz/ServiceStack.Redis
+// ServiceStack.Redis: ECMA CLI Binding to the Redis key-value storage system
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2010 Liquidbit Ltd.
+//
+// Licensed under the same terms of Redis and ServiceStack: new BSD license.
+//
+
+using System.Collections.Generic;
+using ServiceStack.DesignPatterns.Model;
+
+namespace ServiceStack.Redis
+{
+	public interface IRedisSet
+		: ICollection<string>, IHasStringId
+	{
+		List<string> GetRangeFromSortedSet(int startingFrom, int endingAt);
+		HashSet<string> GetAll();
+		string Pop();
+		void Move(string value, IRedisSet toSet);
+		HashSet<string> Intersect(params IRedisSet[] withSets);
+		void StoreIntersect(params IRedisSet[] withSets);
+		HashSet<string> Union(params IRedisSet[] withSets);
+		void StoreUnion(params IRedisSet[] withSets);
+		HashSet<string> Diff(IRedisSet[] withSets);
+		void StoreDiff(IRedisSet fromSet, params IRedisSet[] withSets);
+		string GetRandomEntry();
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/IRedisSortedSet.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/IRedisSortedSet.cs
new file mode 100644
index 0000000..955b02e
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/IRedisSortedSet.cs
@@ -0,0 +1,37 @@
+//
+// https://github.com/mythz/ServiceStack.Redis
+// ServiceStack.Redis: ECMA CLI Binding to the Redis key-value storage system
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2010 Liquidbit Ltd.
+//
+// Licensed under the same terms of Redis and ServiceStack: new BSD license.
+//
+
+using System.Collections.Generic;
+using ServiceStack.DesignPatterns.Model;
+
+namespace ServiceStack.Redis
+{
+	public interface IRedisSortedSet
+		: ICollection<string>, IHasStringId
+	{
+		List<string> GetAll();
+		List<string> GetRange(int startingRank, int endingRank);
+		List<string> GetRangeByScore(string fromStringScore, string toStringScore);
+		List<string> GetRangeByScore(string fromStringScore, string toStringScore, int? skip, int? take);
+		List<string> GetRangeByScore(double fromScore, double toScore);
+		List<string> GetRangeByScore(double fromScore, double toScore, int? skip, int? take);
+		void RemoveRange(int fromRank, int toRank);
+		void RemoveRangeByScore(double fromScore, double toScore);
+		void StoreFromIntersect(params IRedisSortedSet[] ofSets);
+		void StoreFromUnion(params IRedisSortedSet[] ofSets);
+		int GetItemIndex(string value);
+		double GetItemScore(string value);
+		void IncrementItemScore(string value, double incrementByScore);
+		string PopItemWithHighestScore();
+		string PopItemWithLowestScore();
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/IRedisSubscription.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/IRedisSubscription.cs
new file mode 100644
index 0000000..7c9e6ca
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/IRedisSubscription.cs
@@ -0,0 +1,44 @@
+using System;
+
+namespace ServiceStack.Redis
+{
+	public interface IRedisSubscription 
+		: IDisposable
+	{
+		/// <summary>
+		/// The number of active subscriptions this client has
+		/// </summary>
+		int SubscriptionCount { get; }
+		
+		/// <summary>
+		/// Registered handler called after client *Subscribes* to each new channel
+		/// </summary>
+		Action<string> OnSubscribe { get; set; }
+		
+		/// <summary>
+		/// Registered handler called when each message is received
+		/// </summary>
+		Action<string, string> OnMessage { get; set; }
+
+		/// <summary>
+		/// Registered handler called when each channel is unsubscribed
+		/// </summary>
+		Action<string> OnUnSubscribe { get; set; }
+
+		/// <summary>
+		/// Subscribe to channels by name
+		/// </summary>
+		/// <param name="channels"></param>
+		void SubscribeToChannels(params string[] channels);
+
+		/// <summary>
+		/// Subscribe to channels matching the supplied patterns
+		/// </summary>
+		/// <param name="patterns"></param>
+		void SubscribeToChannelsMatching(params string[] patterns);
+		
+		void UnSubscribeFromAllChannels();
+		void UnSubscribeFromChannels(params string[] channels);
+		void UnSubscribeFromChannelsMatching(params string[] patterns);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/IRedisTransaction.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/IRedisTransaction.cs
new file mode 100644
index 0000000..69dc7bf
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/IRedisTransaction.cs
@@ -0,0 +1,27 @@
+//
+// https://github.com/mythz/ServiceStack.Redis
+// ServiceStack.Redis: ECMA CLI Binding to the Redis key-value storage system
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2010 Liquidbit Ltd.
+//
+// Licensed under the same terms of Redis and ServiceStack: new BSD license.
+//
+
+using System;
+using ServiceStack.Redis.Pipeline;
+
+namespace ServiceStack.Redis
+{
+    /// <summary>
+    /// Interface to redis transaction
+    /// </summary>
+	public interface IRedisTransaction
+        : IRedisTransactionBase, IRedisQueueableOperation, IDisposable
+	{
+		bool Commit();
+		void Rollback();
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/IRedisTransactionBase.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/IRedisTransactionBase.cs
new file mode 100644
index 0000000..478f60c
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/IRedisTransactionBase.cs
@@ -0,0 +1,11 @@
+using ServiceStack.Redis.Pipeline;
+
+namespace ServiceStack.Redis
+{
+    /// <summary>
+    /// Base transaction interface, shared by typed and non-typed transactions
+    /// </summary>
+    public interface IRedisTransactionBase : IRedisPipelineShared
+    {
+    }
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/ItemRef.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/ItemRef.cs
new file mode 100644
index 0000000..b3ba827
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/ItemRef.cs
@@ -0,0 +1,8 @@
+namespace ServiceStack.Redis
+{
+    public class ItemRef
+    {
+        public string Id { get; set; }
+        public string Item { get; set; }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Pipeline/IRedisPipeline.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Pipeline/IRedisPipeline.cs
new file mode 100644
index 0000000..7a144e3
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Pipeline/IRedisPipeline.cs
@@ -0,0 +1,9 @@
+namespace ServiceStack.Redis.Pipeline
+{
+	/// <summary>
+	/// Interface to redis pipeline
+	/// </summary>
+	public interface IRedisPipeline : IRedisPipelineShared, IRedisQueueableOperation
+	{
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Pipeline/IRedisPipelineShared.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Pipeline/IRedisPipelineShared.cs
new file mode 100644
index 0000000..66c5870
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Pipeline/IRedisPipelineShared.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace ServiceStack.Redis.Pipeline
+{
+	/// <summary>
+	/// Pipeline interface shared by typed and non-typed pipelines
+	/// </summary>
+	public interface IRedisPipelineShared : IDisposable, IRedisQueueCompletableOperation
+	{
+		void Flush();
+		bool Replay();
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Pipeline/IRedisQueueCompletableOperation.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Pipeline/IRedisQueueCompletableOperation.cs
new file mode 100644
index 0000000..3a0e477
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Pipeline/IRedisQueueCompletableOperation.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+
+namespace ServiceStack.Redis.Pipeline
+{
+	/// <summary>
+	/// Interface to operations that allow queued commands to be completed
+	/// </summary>
+	public interface IRedisQueueCompletableOperation
+	{
+		void CompleteVoidQueuedCommand(Action voidReadCommand);
+		void CompleteIntQueuedCommand(Func<int> intReadCommand);
+		void CompleteLongQueuedCommand(Func<long> longReadCommand);
+		void CompleteBytesQueuedCommand(Func<byte[]> bytesReadCommand);
+		void CompleteMultiBytesQueuedCommand(Func<byte[][]> multiBytesReadCommand);
+		void CompleteStringQueuedCommand(Func<string> stringReadCommand);
+		void CompleteMultiStringQueuedCommand(Func<List<string>> multiStringReadCommand);
+		void CompleteDoubleQueuedCommand(Func<double> doubleReadCommand);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Pipeline/IRedisQueueableOperation.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Pipeline/IRedisQueueableOperation.cs
new file mode 100644
index 0000000..d023e41
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/Pipeline/IRedisQueueableOperation.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+
+namespace ServiceStack.Redis.Pipeline
+{
+	/// <summary>
+	/// interface to operation that can queue commands
+	/// </summary>
+	public interface IRedisQueueableOperation
+	{
+		void QueueCommand(Action<IRedisClient> command);
+		void QueueCommand(Action<IRedisClient> command, Action onSuccessCallback);
+		void QueueCommand(Action<IRedisClient> command, Action onSuccessCallback, Action<Exception> onErrorCallback);
+
+		void QueueCommand(Func<IRedisClient, int> command);
+		void QueueCommand(Func<IRedisClient, int> command, Action<int> onSuccessCallback);
+		void QueueCommand(Func<IRedisClient, int> command, Action<int> onSuccessCallback, Action<Exception> onErrorCallback);
+
+		void QueueCommand(Func<IRedisClient, long> command);
+		void QueueCommand(Func<IRedisClient, long> command, Action<long> onSuccessCallback);
+		void QueueCommand(Func<IRedisClient, long> command, Action<long> onSuccessCallback, Action<Exception> onErrorCallback);
+
+		void QueueCommand(Func<IRedisClient, bool> command);
+		void QueueCommand(Func<IRedisClient, bool> command, Action<bool> onSuccessCallback);
+		void QueueCommand(Func<IRedisClient, bool> command, Action<bool> onSuccessCallback, Action<Exception> onErrorCallback);
+
+		void QueueCommand(Func<IRedisClient, double> command);
+		void QueueCommand(Func<IRedisClient, double> command, Action<double> onSuccessCallback);
+		void QueueCommand(Func<IRedisClient, double> command, Action<double> onSuccessCallback, Action<Exception> onErrorCallback);
+
+		void QueueCommand(Func<IRedisClient, byte[]> command);
+		void QueueCommand(Func<IRedisClient, byte[]> command, Action<byte[]> onSuccessCallback);
+		void QueueCommand(Func<IRedisClient, byte[]> command, Action<byte[]> onSuccessCallback, Action<Exception> onErrorCallback);
+
+        void QueueCommand(Func<IRedisClient, byte[][]> command);
+        void QueueCommand(Func<IRedisClient, byte[][]> command, Action<byte[][]> onSuccessCallback);
+        void QueueCommand(Func<IRedisClient, byte[][]> command, Action<byte[][]> onSuccessCallback, Action<Exception> onErrorCallback);
+
+
+		void QueueCommand(Func<IRedisClient, string> command);
+		void QueueCommand(Func<IRedisClient, string> command, Action<string> onSuccessCallback);
+		void QueueCommand(Func<IRedisClient, string> command, Action<string> onSuccessCallback, Action<Exception> onErrorCallback);
+
+		void QueueCommand(Func<IRedisClient, List<string>> command);
+		void QueueCommand(Func<IRedisClient, List<string>> command, Action<List<string>> onSuccessCallback);
+		void QueueCommand(Func<IRedisClient, List<string>> command, Action<List<string>> onSuccessCallback, Action<Exception> onErrorCallback);
+		
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/RedisKeyType.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/RedisKeyType.cs
new file mode 100644
index 0000000..b0f21e9
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/RedisKeyType.cs
@@ -0,0 +1,24 @@
+//
+// https://github.com/mythz/ServiceStack.Redis
+// ServiceStack.Redis: ECMA CLI Binding to the Redis key-value storage system
+//
+// Authors:
+//   Demis Bellot (demis.bellot at gmail.com)
+//
+// Copyright 2010 Liquidbit Ltd.
+//
+// Licensed under the same terms of Redis and ServiceStack: new BSD license.
+//
+
+namespace ServiceStack.Redis
+{
+	public enum RedisKeyType
+	{
+		None, 
+		String, 
+		List, 
+		Set,
+		SortedSet,
+		Hash
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/SortOptions.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/SortOptions.cs
new file mode 100644
index 0000000..e1f2c41
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Redis/SortOptions.cs
@@ -0,0 +1,13 @@
+namespace ServiceStack.Redis
+{
+	public class SortOptions
+	{
+		public string SortPattern { get; set; }
+		public int? Skip { get; set; }
+		public int? Take { get; set; }
+		public string GetPattern { get; set; }
+		public bool SortAlpha { get; set; }
+		public bool SortDesc { get; set; }
+		public string StoreAtKey { get; set; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/SearchIndex/FullTextIndexAttribute.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/SearchIndex/FullTextIndexAttribute.cs
new file mode 100644
index 0000000..567447b
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/SearchIndex/FullTextIndexAttribute.cs
@@ -0,0 +1,18 @@
+using System;
+
+namespace ServiceStack.SearchIndex
+{
+	[Flags]
+	public enum FullTextIndexAttribute
+	{
+		IsDefault = 1,
+		IsKey = 2,
+		NoIndex = 4,
+		IndexTokenized = 8,
+		IndexUnTokenized = 16,
+		//IndexNoNorms,
+		NoStore = 32,
+		StoreCompressed = 64,
+		StoreUncompressed = 128,
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/SearchIndex/FullTextIndexDocumentAttribute.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/SearchIndex/FullTextIndexDocumentAttribute.cs
new file mode 100644
index 0000000..cde425a
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/SearchIndex/FullTextIndexDocumentAttribute.cs
@@ -0,0 +1,17 @@
+using System;
+
+namespace ServiceStack.SearchIndex
+{
+	public class FullTextIndexDocumentAttribute : Attribute
+	{
+		public Type ForType { get; set; }
+
+		public FullTextIndexDocumentAttribute()
+		{}
+
+		public FullTextIndexDocumentAttribute(Type forType)
+		{
+			this.ForType = forType;
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/SearchIndex/FullTextIndexFieldAttribute.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/SearchIndex/FullTextIndexFieldAttribute.cs
new file mode 100644
index 0000000..f65862d
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/SearchIndex/FullTextIndexFieldAttribute.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using ServiceStack.SearchIndex;
+
+namespace ServiceStack.SearchIndex
+{
+	public class FullTextIndexFieldAttribute : Attribute
+	{
+		public FullTextIndexAttribute FieldAttributes { get; private set; }
+		public string MemberPath { get; set; }
+
+		public FullTextIndexFieldAttribute() 
+				:this(FullTextIndexAttribute.StoreUncompressed | FullTextIndexAttribute.IndexTokenized)
+		{}
+
+		public FullTextIndexFieldAttribute(FullTextIndexAttribute fieldAttributes)
+		{
+			this.FieldAttributes = fieldAttributes;
+		}
+
+		public FullTextIndexFieldAttribute(FullTextIndexAttribute fieldAttributes, string memberPath)
+				: this(fieldAttributes)
+		{
+			this.MemberPath = memberPath;
+		}
+
+		public FullTextIndexFieldAttribute(string memberTypePropertyName)
+				: this()
+		{
+			this.MemberPath = memberTypePropertyName;
+		}
+
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Service/IOneWayClient.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Service/IOneWayClient.cs
new file mode 100644
index 0000000..1a519e2
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Service/IOneWayClient.cs
@@ -0,0 +1,9 @@
+namespace ServiceStack.Service
+{
+	public interface IOneWayClient
+	{
+        void SendOneWay(object request);
+        
+        void SendOneWay(string relativeOrAbsoluteUrl, object request);
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Service/IReplyClient.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Service/IReplyClient.cs
new file mode 100644
index 0000000..293d1f9
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Service/IReplyClient.cs
@@ -0,0 +1,22 @@
+using System.IO;
+
+namespace ServiceStack.Service
+{
+	public interface IReplyClient
+	{
+		/// <summary>
+		/// Sends the specified request.
+		/// </summary>
+		/// <param name="request">The request.</param>
+		/// <returns></returns>
+		TResponse Send<TResponse>(object request);
+
+		TResponse PostFile<TResponse>(string relativeOrAbsoluteUrl, FileInfo fileToUpload, string mimeType);
+
+        TResponse PostFile<TResponse>(string relativeOrAbsoluteUrl, Stream fileToUpload, string fileName, string mimeType);
+
+        TResponse PostFileWithRequest<TResponse>(string relativeOrAbsoluteUrl, FileInfo fileToUpload, object request);
+
+        TResponse PostFileWithRequest<TResponse>(string relativeOrAbsoluteUrl, Stream fileToUpload, string fileName, object request);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Service/IResponseBase.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Service/IResponseBase.cs
new file mode 100644
index 0000000..89ec343
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Service/IResponseBase.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Runtime.Serialization;
+
+namespace ServiceStack.Service
+{
+	public interface IResponseBase<TData, TResponseStatus> 
+	{
+		int Version { get; set; }
+
+		TResponseStatus ResponseStatus { get; set; }
+
+		TData ResponseData { get; set; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Service/IResponseStatus.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Service/IResponseStatus.cs
new file mode 100644
index 0000000..6d34a93
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Service/IResponseStatus.cs
@@ -0,0 +1,13 @@
+namespace ServiceStack.Service
+{
+	public interface IResponseStatus
+	{
+		string ErrorCode { get; set; }
+
+		string ErrorMessage { get; set; }
+
+		string StackTrace { get; set; }
+
+		bool IsSuccess { get; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Service/IRestClient.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Service/IRestClient.cs
new file mode 100644
index 0000000..fdbe6f8
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Service/IRestClient.cs
@@ -0,0 +1,17 @@
+using System.IO;
+
+namespace ServiceStack.Service
+{
+	public interface IRestClient 
+	{
+		TResponse Get<TResponse>(string relativeOrAbsoluteUrl);
+		TResponse Delete<TResponse>(string relativeOrAbsoluteUrl);
+
+		TResponse Post<TResponse>(string relativeOrAbsoluteUrl, object request);
+		TResponse Put<TResponse>(string relativeOrAbsoluteUrl, object request);
+
+		TResponse Patch<TResponse>(string relativeOrAbsoluteUrl, object request);
+
+		TResponse PostFile<TResponse>(string relativeOrAbsoluteUrl, FileInfo fileToUpload, string mimeType);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Service/IRestClientAsync.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Service/IRestClientAsync.cs
new file mode 100644
index 0000000..dd8879c
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Service/IRestClientAsync.cs
@@ -0,0 +1,17 @@
+using System;
+using System.IO;
+
+namespace ServiceStack.Service
+{
+	public interface IRestClientAsync : IDisposable
+	{
+		void SetCredentials(string userName, string password);
+
+		void GetAsync<TResponse>(string relativeOrAbsoluteUrl, Action<TResponse> onSuccess, Action<TResponse, Exception> onError);
+		void DeleteAsync<TResponse>(string relativeOrAbsoluteUrl, Action<TResponse> onSuccess, Action<TResponse, Exception> onError);
+
+		void PostAsync<TResponse>(string relativeOrAbsoluteUrl, object request, Action<TResponse> onSuccess, Action<TResponse, Exception> onError);
+		void PutAsync<TResponse>(string relativeOrAbsoluteUrl, object request, Action<TResponse> onSuccess, Action<TResponse, Exception> onError);
+	}
+
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Service/IServiceClient.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Service/IServiceClient.cs
new file mode 100644
index 0000000..13258fc
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Service/IServiceClient.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace ServiceStack.Service
+{
+	public interface IServiceClient : IServiceClientAsync, IOneWayClient
+#if !SILVERLIGHT
+		, IReplyClient
+#endif
+	{
+	}
+
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Service/IServiceClientAsync.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Service/IServiceClientAsync.cs
new file mode 100644
index 0000000..00c3810
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Service/IServiceClientAsync.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace ServiceStack.Service
+{
+	public interface IServiceClientAsync : IRestClientAsync
+	{
+		void SendAsync<TResponse>(object request, Action<TResponse> onSuccess, Action<TResponse, Exception> onError);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Service/IStreamWriter.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Service/IStreamWriter.cs
new file mode 100644
index 0000000..71e6e79
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Service/IStreamWriter.cs
@@ -0,0 +1,9 @@
+using System.IO;
+
+namespace ServiceStack.Service
+{
+	public interface IStreamWriter
+	{
+		void WriteTo(Stream responseStream);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/EndpointAttributes.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/EndpointAttributes.cs
new file mode 100644
index 0000000..e3ff917
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/EndpointAttributes.cs
@@ -0,0 +1,59 @@
+using System;
+
+namespace ServiceStack.ServiceHost
+{
+	[Flags]
+	public enum EndpointAttributes
+	{
+		None = 0,
+
+		All = AllNetworkAccessTypes | AllSecurityModes | AllHttpMethods | AllCallStyles | AllEndpointTypes,
+		AllNetworkAccessTypes = External | Localhost | LocalSubnet,
+		AllSecurityModes = Secure | InSecure,
+		AllHttpMethods = HttpHead | HttpGet | HttpPost | HttpPut | HttpDelete,
+		AllCallStyles = AsyncOneWay | SyncReply,
+		AllEndpointTypes = Soap11 | Soap12 | Xml | Json | Jsv | ProtoBuf | Csv,
+		
+		InternalNetworkAccess = Localhost | LocalSubnet,
+
+		//Whether it came from an Internal or External address
+		Localhost = 1 << 0,
+		LocalSubnet = 1 << 1,
+		External = 1 << 2,
+
+		//Called over a secure or insecure channel
+		Secure = 1 << 3,
+		InSecure = 1 << 4,
+
+		//HTTP request type
+		HttpHead = 1 << 5,
+		HttpGet = 1 << 6,
+		HttpPost = 1 << 7,
+		HttpPut = 1 << 8,
+		HttpDelete = 1 << 9,
+		HttpPatch = 1 << 10,
+		//Future 11,12
+
+		//Call Styles
+		AsyncOneWay = 1 << 13,
+		SyncReply = 1 << 14,
+
+		//Different endpoints
+		Soap11 = 1 << 15,
+		Soap12 = 1 << 16,
+		//POX
+		Xml = 1 << 17,
+		//Javascript
+		Json = 1 << 18,
+		//Jsv i.e. TypeSerializer
+		Jsv = 1 << 19,
+		//e.g. protobuf-net
+		ProtoBuf = 1 << 20,
+		//e.g. text/csv
+		Csv = 1 << 21,
+
+		Html = 1 << 22,
+		Yaml = 1 << 23,
+	}
+
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/Feature.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/Feature.cs
new file mode 100644
index 0000000..61f80af
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/Feature.cs
@@ -0,0 +1,25 @@
+using System;
+
+namespace ServiceStack.ServiceHost
+{
+	[Flags]
+	public enum Feature : int
+	{
+		None         = 0,
+		All          = int.MaxValue,
+		Soap         = Soap11 | Soap12,
+
+		Json         = 1 << 0,
+		Xml          = 1 << 1,
+		Jsv          = 1 << 2,
+		Soap11       = 1 << 3,
+		Soap12       = 1 << 4,
+		Csv          = 1 << 5,
+		Html         = 1 << 6,
+		CustomFormat = 1 << 7,
+		Metadata     = 1 << 8,
+		Markdown     = 1 << 9,
+		Razor        = 1 << 10,
+		ProtoBuf     = 1 << 11,
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IAsyncService.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IAsyncService.cs
new file mode 100644
index 0000000..2d191ed
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IAsyncService.cs
@@ -0,0 +1,13 @@
+namespace ServiceStack.ServiceHost
+{
+	/// <summary>
+	/// If the Service also implements this interface,
+	/// IAsyncService.ExecuteAsync() will be used instead of IService.Execute() for 
+	/// EndpointAttributes.AsyncOneWay requests
+	/// </summary>
+	/// <typeparam name="T"></typeparam>
+	public interface IAsyncService<T>
+	{
+		object ExecuteAsync(T request);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IContentTypeFilter.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IContentTypeFilter.cs
new file mode 100644
index 0000000..ceddfed
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IContentTypeFilter.cs
@@ -0,0 +1,19 @@
+using System.Collections.Generic;
+
+namespace ServiceStack.ServiceHost
+{
+	public interface IContentTypeFilter
+		: IContentTypeWriter, IContentTypeReader
+	{
+		Dictionary<string, string> ContentTypeFormats { get; }
+
+		void Register(string contentType,
+			StreamSerializerDelegate streamSerializer, StreamDeserializerDelegate streamDeserializer);
+
+		void Register(string contentType,
+			ResponseSerializerDelegate responseSerializer, StreamDeserializerDelegate streamDeserializer);
+
+		void ClearCustomFilters();
+	}
+
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IContentTypeReader.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IContentTypeReader.cs
new file mode 100644
index 0000000..f1655c4
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IContentTypeReader.cs
@@ -0,0 +1,19 @@
+using System;
+using System.IO;
+
+namespace ServiceStack.ServiceHost
+{
+	public interface IContentTypeReader
+	{
+		object DeserializeFromString(string contentType, Type type, string request);
+
+		object DeserializeFromStream(string contentType, Type type, Stream requestStream);
+
+		StreamDeserializerDelegate GetStreamDeserializer(string contentType);
+	}
+
+	public delegate object TextDeserializerDelegate(Type type, string dto);
+
+	public delegate object StreamDeserializerDelegate(Type type, Stream fromStream);
+
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IContentTypeWriter.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IContentTypeWriter.cs
new file mode 100644
index 0000000..d3f3981
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IContentTypeWriter.cs
@@ -0,0 +1,23 @@
+using System.IO;
+
+namespace ServiceStack.ServiceHost
+{
+	public interface IContentTypeWriter
+	{
+        byte[] SerializeToBytes(IRequestContext requestContext, object response);
+
+        string SerializeToString(IRequestContext requestContext, object response);
+
+        void SerializeToStream(IRequestContext requestContext, object response, Stream toStream);
+		
+		void SerializeToResponse(IRequestContext requestContext, object response, IHttpResponse httpRes);
+
+		ResponseSerializerDelegate GetResponseSerializer(string contentType);
+	}
+
+	public delegate string TextSerializerDelegate(object dto);
+
+	public delegate void StreamSerializerDelegate(IRequestContext requestContext, object dto, Stream outputStream);
+
+	public delegate void ResponseSerializerDelegate(IRequestContext requestContext, object dto, IHttpResponse httpRes);
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/ICookies.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/ICookies.cs
new file mode 100644
index 0000000..500eca9
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/ICookies.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Net;
+
+namespace ServiceStack.ServiceHost
+{
+	public interface ICookies
+	{
+		void DeleteCookie(string cookieName);
+		void AddCookie(Cookie cookie);
+		void AddPermanentCookie(string cookieName, string cookieValue);
+		void AddSessionCookie(string cookieName, string cookieValue);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IExpirable.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IExpirable.cs
new file mode 100644
index 0000000..ff623fa
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IExpirable.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace ServiceStack.WebHost.Endpoints.Support.Markdown
+{
+	public interface IExpirable
+	{
+		DateTime? LastModified { get; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IFile.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IFile.cs
new file mode 100644
index 0000000..fb16ab1
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IFile.cs
@@ -0,0 +1,12 @@
+using System.IO;
+
+namespace ServiceStack.ServiceHost
+{
+	public interface IFile
+	{
+		string FileName { get; }
+		long ContentLength { get; }
+		string ContentType { get; }
+		Stream InputStream { get; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IHasOptions.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IHasOptions.cs
new file mode 100644
index 0000000..2d5a89f
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IHasOptions.cs
@@ -0,0 +1,9 @@
+using System.Collections.Generic;
+
+namespace ServiceStack.ServiceHost
+{
+	public interface IHasOptions
+	{
+		IDictionary<string, string> Options { get; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IHasRequestFilter.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IHasRequestFilter.cs
new file mode 100644
index 0000000..7cbaeb5
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IHasRequestFilter.cs
@@ -0,0 +1,32 @@
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+namespace ServiceStack.ServiceHost
+{
+    /// <summary>
+    /// This interface can be implemented by an attribute
+    /// which adds an request filter for the specific request DTO the attribute marked.
+    /// </summary>
+    public interface IHasRequestFilter
+    {
+    	/// <summary>
+    	/// Order in which Request Filters are executed. 
+    	/// <0 Executed before global request filters
+		/// >0 Executed after global request filters
+    	/// </summary>
+    	int Priority { get; }
+
+        /// <summary>
+        /// The request filter is executed before the service.
+        /// </summary>
+        /// <param name="req">The http request wrapper</param>
+        /// <param name="res">The http response wrapper</param>
+        /// <param name="requestDto">The request DTO</param>
+        void RequestFilter(IHttpRequest req, IHttpResponse res, object requestDto);
+
+        /// <summary>
+        /// A new shallow copy of this filter is used on every request.
+        /// </summary>
+        /// <returns></returns>
+        IHasRequestFilter Copy();
+    }
+}
+#endif
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IHasResponseFilter.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IHasResponseFilter.cs
new file mode 100644
index 0000000..1a15b3a
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IHasResponseFilter.cs
@@ -0,0 +1,31 @@
+#if !SILVERLIGHT && !MONOTOUCH && !XBOX
+namespace ServiceStack.ServiceHost
+{
+    /// <summary>
+    /// This interface can be implemented by an attribute
+    /// which adds an response filter for the specific response DTO the attribute marked.
+    /// </summary>
+    public interface IHasResponseFilter
+    {
+		/// <summary>
+		/// Order in which Response Filters are executed. 
+		/// <0 Executed before global response filters
+		/// >0 Executed after global response filters
+		/// </summary>
+		int Priority { get; }
+
+        /// <summary>
+        /// The response filter is executed after the service
+        /// </summary>
+        /// <param name="req">The http request wrapper</param>
+        /// <param name="res">The http response wrapper</param>
+        void ResponseFilter(IHttpRequest req, IHttpResponse res, object response);
+
+        /// <summary>
+        /// A new shallow copy of this filter is used on every request.
+        /// </summary>
+        /// <returns></returns>
+        IHasResponseFilter Copy();
+    }
+}
+#endif
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IHttpError.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IHttpError.cs
new file mode 100644
index 0000000..5b7a719
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IHttpError.cs
@@ -0,0 +1,8 @@
+namespace ServiceStack.ServiceHost
+{
+	public interface IHttpError : IHttpResult
+	{
+		string Message { get; }
+		string ErrorCode { get; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IHttpRequest.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IHttpRequest.cs
new file mode 100644
index 0000000..9cd5df4
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IHttpRequest.cs
@@ -0,0 +1,93 @@
+#if !SILVERLIGHT && !XBOX
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.IO;
+using System.Net;
+
+namespace ServiceStack.ServiceHost
+{
+	/// <summary>
+	/// A thin wrapper around ASP.NET or HttpListener's HttpRequest
+	/// </summary>
+	public interface IHttpRequest : IResolver
+	{
+		/// <summary>
+		/// The underlying ASP.NET or HttpListener HttpRequest
+		/// </summary>
+		object OriginalRequest { get; }
+
+		/// <summary>
+		/// The name of the service being called (e.g. Request DTO Name)
+		/// </summary>
+		string OperationName { get; }
+
+		/// <summary>
+		/// The request ContentType
+		/// </summary>
+		string ContentType { get; }
+
+		string HttpMethod { get; }
+
+		string UserAgent { get; }
+
+		IDictionary<string, System.Net.Cookie> Cookies { get; }
+
+		/// <summary>
+		/// The expected Response ContentType for this request
+		/// </summary>
+		string ResponseContentType { get; set; }
+
+		/// <summary>
+		/// Attach any data to this request that all filters and services can access.
+		/// </summary>
+		Dictionary<string, object> Items { get; }
+
+		NameValueCollection Headers { get; }
+
+		NameValueCollection QueryString { get; }
+
+		NameValueCollection FormData { get; }
+
+		/// <summary>
+		/// The entire string contents of Request.InputStream
+		/// </summary>
+		/// <returns></returns>
+		string GetRawBody();
+
+		string RawUrl { get; }
+
+		string AbsoluteUri { get; }
+
+        /// <summary>
+        /// The Remote Ip as reported by Request.UserHostAddress
+        /// </summary>
+        string UserHostAddress { get; }
+
+        /// <summary>
+        /// The Remote Ip as reported by X-Forwarded-For, X-Real-IP or Request.UserHostAddress
+        /// </summary>
+        string RemoteIp { get; }
+
+		/// <summary>
+		/// e.g. is https or not
+		/// </summary>
+		bool IsSecureConnection { get; }
+
+		string[] AcceptTypes { get; }
+
+		string PathInfo { get; }
+
+		Stream InputStream { get; }
+
+		long ContentLength { get; }
+
+		/// <summary>
+		/// Access to the multi-part/formdata files posted on this request
+		/// </summary>
+		IFile[] Files { get; }
+
+		string ApplicationFilePath { get; }
+	}
+}
+#endif
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IHttpResponse.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IHttpResponse.cs
new file mode 100644
index 0000000..3e9bfa5
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IHttpResponse.cs
@@ -0,0 +1,53 @@
+using System.IO;
+
+namespace ServiceStack.ServiceHost
+{
+	/// <summary>
+	/// A thin wrapper around ASP.NET or HttpListener's HttpResponse
+	/// </summary>
+	public interface IHttpResponse
+	{
+		/// <summary>
+		/// The underlying ASP.NET or HttpListener HttpResponse
+		/// </summary>
+		object OriginalResponse { get; }
+
+		int StatusCode { set; }
+
+        string StatusDescription { set; }
+
+		string ContentType { get; set; }
+
+		ICookies Cookies { get; }
+
+		void AddHeader(string name, string value);
+
+		void Redirect(string url);
+
+		Stream OutputStream { get; }
+
+		void Write(string text);
+
+		/// <summary>
+		/// Signal that this response has been handled and no more processing should be done.
+		/// When used in a request or response filter, no more filters or processing is done on this request.
+		/// </summary>
+		void Close();
+		
+		/// <summary>
+		/// Calls Response.End() on ASP.NET HttpResponse otherwise is an alias for Close().
+		/// Useful when you want to prevent ASP.NET to provide it's own custom error page.
+		/// </summary>
+		void End();
+
+		/// <summary>
+		/// Response.Flush() and OutputStream.Flush() seem to have different behaviour in ASP.NET
+		/// </summary>
+		void Flush();
+
+		/// <summary>
+		/// Gets a value indicating whether this instance is closed.
+		/// </summary>
+		bool IsClosed { get; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IHttpResult.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IHttpResult.cs
new file mode 100644
index 0000000..2f71619
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IHttpResult.cs
@@ -0,0 +1,48 @@
+using System.Collections.Generic;
+using System.Net;
+
+namespace ServiceStack.ServiceHost
+{
+	public interface IHttpResult : IHasOptions
+	{
+        /// <summary>
+        /// The HTTP Response Status
+        /// </summary>
+        int Status { get; set; }
+
+		/// <summary>
+		/// The HTTP Response Status Code
+		/// </summary>
+		HttpStatusCode StatusCode { get; set; }
+
+        /// <summary>
+        /// The HTTP Status Description
+        /// </summary>
+        string StatusDescription { get; set; }
+
+		/// <summary>
+		/// The HTTP Response ContentType
+		/// </summary>
+		string ContentType { get; set; }
+
+		/// <summary>
+		/// Additional HTTP Headers
+		/// </summary>
+		Dictionary<string, string> Headers { get; }
+
+		/// <summary>
+		/// Response DTO
+		/// </summary>
+		object Response { get; set; }
+
+		/// <summary>
+		/// if not provided, get's injected by ServiceStack
+		/// </summary>
+		IContentTypeWriter ResponseFilter { get; set; }
+
+		/// <summary>
+		/// Holds the request call context
+		/// </summary>
+		IRequestContext RequestContext { get; set; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRequestAttributes.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRequestAttributes.cs
new file mode 100644
index 0000000..2fb7777
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRequestAttributes.cs
@@ -0,0 +1,11 @@
+using System;
+
+namespace ServiceStack.ServiceHost
+{
+	public interface IRequestAttributes
+	{
+		bool AcceptsGzip { get; }
+
+		bool AcceptsDeflate { get; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRequestContext.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRequestContext.cs
new file mode 100644
index 0000000..e677b8b
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRequestContext.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Net;
+
+namespace ServiceStack.ServiceHost
+{
+	public interface IRequestContext : IDisposable
+	{
+		T Get<T>() where T : class;
+		
+		string IpAddress { get; }
+
+		string GetHeader(string headerName);
+
+		IDictionary<string, System.Net.Cookie> Cookies { get; }
+
+		EndpointAttributes EndpointAttributes { get; }
+		
+		IRequestAttributes RequestAttributes { get; }
+
+		string ContentType { get; }
+
+		string ResponseContentType { get; }
+
+		string CompressionType { get; }
+
+		string AbsoluteUri { get; }
+
+		string PathInfo { get; }
+
+		IFile[] Files { get; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRequestLogger.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRequestLogger.cs
new file mode 100644
index 0000000..90e8367
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRequestLogger.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Collections.Generic;
+using ServiceStack.ServiceInterface.ServiceModel;
+
+namespace ServiceStack.ServiceHost
+{
+	/// <summary>
+	/// Log every service request
+	/// </summary>
+	public interface IRequestLogger
+	{
+		/// <summary>
+		/// Turn On/Off Session Tracking
+		/// </summary>
+		bool EnableSessionTracking { get; set; }
+
+		/// <summary>
+		/// Turn On/Off Tracking of Responses
+		/// </summary>
+		bool EnableResponseTracking { get; set; }
+
+		/// <summary>
+		/// Turn On/Off Tracking of Exceptions
+		/// </summary>
+		bool EnableErrorTracking { get; set; }
+
+		/// <summary>
+		/// Limit access to /requestlogs service to role
+		/// </summary>
+		string[] RequiredRoles { get; set; }
+
+		/// <summary>
+		/// Don't log requests of these types.
+		/// </summary>
+		Type[] ExcludeRequestDtoTypes { get; set; }
+
+		/// <summary>
+		/// Don't log request bodys for services with sensitive information.
+		/// By default Auth and Registration requests are hidden.
+		/// </summary>
+		Type[] HideRequestBodyForRequestDtoTypes { get; set; }
+
+		/// <summary>
+		/// Log a request
+		/// </summary>
+		/// <param name="requestContext">The RequestContext</param>
+		/// <param name="requestDto">Request DTO</param>
+		/// <param name="response">Response DTO or Exception</param>
+		/// <param name="elapsed">How long did the Request take</param>
+		void Log(IRequestContext requestContext, object requestDto, object response, TimeSpan elapsed);
+
+		/// <summary>
+		/// View the most recent logs
+		/// </summary>
+		/// <param name="take"></param>
+		/// <returns></returns>
+		List<RequestLogEntry> GetLatestLogs(int? take);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRequiresHttpRequest.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRequiresHttpRequest.cs
new file mode 100644
index 0000000..be68948
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRequiresHttpRequest.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace ServiceStack.ServiceHost
+{
+	public interface IRequiresHttpRequest
+	{
+		IHttpRequest HttpRequest { get; set; }
+	}
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRequiresRequestContext.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRequiresRequestContext.cs
new file mode 100644
index 0000000..3cfe71e
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRequiresRequestContext.cs
@@ -0,0 +1,10 @@
+namespace ServiceStack.ServiceHost
+{
+	/// <summary>
+	/// Implement on services that need access to the RequestContext
+	/// </summary>
+	public interface IRequiresRequestContext
+	{
+		IRequestContext RequestContext { get; set; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRequiresRequestStream.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRequiresRequestStream.cs
new file mode 100644
index 0000000..ce9eedd
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRequiresRequestStream.cs
@@ -0,0 +1,15 @@
+using System.IO;
+
+namespace ServiceStack.ServiceHost
+{
+	/// <summary>
+	/// Implement on Request DTOs that need access to the raw Request Stream
+	/// </summary>
+	public interface IRequiresRequestStream
+	{
+		/// <summary>
+		/// The raw Http Request Input Stream
+		/// </summary>
+		Stream RequestStream { get; set; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IResolver.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IResolver.cs
new file mode 100644
index 0000000..2184c45
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IResolver.cs
@@ -0,0 +1,12 @@
+namespace ServiceStack.ServiceHost
+{
+	public interface IResolver
+	{
+		/// <summary>
+		/// Resolve a dependency from the AppHost's IOC
+		/// </summary>
+		/// <typeparam name="T"></typeparam>
+		/// <returns></returns>
+		T TryResolve<T>();
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRestDeleteService.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRestDeleteService.cs
new file mode 100644
index 0000000..11b87b3
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRestDeleteService.cs
@@ -0,0 +1,13 @@
+namespace ServiceStack.ServiceHost
+{
+	/// <summary>
+	/// If the Service also implements this interface,
+	/// IRestDeleteService.Delete() will be used instead of IService.Execute() for 
+	/// EndpointAttributes.HttpDelete requests
+	/// </summary>
+	/// <typeparam name="T"></typeparam>
+	public interface IRestDeleteService<T>
+	{
+		object Delete(T request);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRestGetService.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRestGetService.cs
new file mode 100644
index 0000000..b165712
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRestGetService.cs
@@ -0,0 +1,13 @@
+namespace ServiceStack.ServiceHost
+{
+	/// <summary>
+	/// If the Service also implements this interface,
+	/// IRestGetService.Get() will be used instead of IService.Execute() for 
+	/// EndpointAttributes.HttpGet requests
+	/// </summary>
+	/// <typeparam name="T"></typeparam>
+	public interface IRestGetService<T>
+	{
+		object Get(T request);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRestPatchService.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRestPatchService.cs
new file mode 100644
index 0000000..500be50
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRestPatchService.cs
@@ -0,0 +1,13 @@
+namespace ServiceStack.ServiceHost
+{
+	/// <summary>
+	/// If the Service also implements this interface,
+	/// IRestPutService.Patch() will be used instead of IService.Execute() for 
+	/// EndpointAttributes.HttpPatch requests
+	/// </summary>
+	/// <typeparam name="T"></typeparam>
+	public interface IRestPatchService<T>
+	{
+		object Patch(T request);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRestPath.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRestPath.cs
new file mode 100644
index 0000000..3609a82
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRestPath.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+
+namespace ServiceStack.ServiceHost
+{
+	public interface IRestPath
+	{
+		Type RequestType { get; }
+
+		object CreateRequest(string pathInfo, Dictionary<string, string> queryStringAndFormData, object fromInstance);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRestPostService.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRestPostService.cs
new file mode 100644
index 0000000..f6386f2
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRestPostService.cs
@@ -0,0 +1,13 @@
+namespace ServiceStack.ServiceHost
+{
+	/// <summary>
+	/// If the Service also implements this interface,
+	/// IRestPostService.Post() will be used instead of IService.Execute() for 
+	/// EndpointAttributes.HttpPost requests
+	/// </summary>
+	/// <typeparam name="T"></typeparam>
+	public interface IRestPostService<T>
+	{
+		object Post(T request);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRestPutService.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRestPutService.cs
new file mode 100644
index 0000000..89da272
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRestPutService.cs
@@ -0,0 +1,13 @@
+namespace ServiceStack.ServiceHost
+{
+	/// <summary>
+	/// If the Service also implements this interface,
+	/// IRestPutService.Put() will be used instead of IService.Execute() for 
+	/// EndpointAttributes.HttpPut requests
+	/// </summary>
+	/// <typeparam name="T"></typeparam>
+	public interface IRestPutService<T>
+	{
+		object Put(T request);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRestService.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRestService.cs
new file mode 100644
index 0000000..840408b
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IRestService.cs
@@ -0,0 +1,15 @@
+namespace ServiceStack.ServiceHost
+{
+	/// <summary>
+	/// Utility interface that implements all Rest operations
+	/// </summary>
+	/// <typeparam name="T"></typeparam>
+	public interface IRestService<T> :
+		IRestGetService<T>,
+		IRestPostService<T>,
+		IRestPutService<T>,
+		IRestDeleteService<T>,
+		IRestPatchService<T>
+	{
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IService.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IService.cs
new file mode 100644
index 0000000..250b9c6
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IService.cs
@@ -0,0 +1,12 @@
+namespace ServiceStack.ServiceHost
+{
+	/// <summary>
+	/// Base interface all webservices need to implement.
+	/// For simplicity this is the only interface you need to implement
+	/// </summary>
+	/// <typeparam name="T"></typeparam>
+	public interface IService<T> 
+	{
+		object Execute(T request);
+	}
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IServiceController.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IServiceController.cs
new file mode 100644
index 0000000..f5c189c
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IServiceController.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+
+namespace ServiceStack.ServiceHost
+{
+	/// <summary>
+	/// Responsible for executing the operation within the specified context.
+	/// </summary>
+	/// <value>The operation types.</value>
+	public interface IServiceController
+	{
+		/// <summary>
+		/// Returns a list of operation types available in this service
+		/// </summary>
+		/// <value>The operation types.</value>
+		IList<Type> OperationTypes { get; }
+
+		/// <summary>
+		/// Returns a list of ALL operation types available in this service
+		/// </summary>
+		/// <value>The operation types.</value>
+		IList<Type> AllOperationTypes { get; }
+
+		/// <summary>
+		/// Returns the first matching RestPath
+		/// </summary>
+		/// <param name="httpMethod"></param>
+		/// <param name="pathInfo"></param>
+		/// <returns></returns>
+		IRestPath GetRestPathForRequest(string httpMethod, string pathInfo);
+
+		/// <summary>
+		/// Allow the registration of custom routes
+		/// </summary>
+		IServiceRoutes Routes { get; }
+
+		/// <summary>
+		/// Executes the DTO request under the supplied requestContext.
+		/// </summary>
+		/// <param name="request"></param>
+		/// <param name="requestContext"></param>
+		/// <returns></returns>
+		object Execute(object request, IRequestContext requestContext);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IServiceRoutes.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IServiceRoutes.cs
new file mode 100644
index 0000000..525a978
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/IServiceRoutes.cs
@@ -0,0 +1,57 @@
+namespace ServiceStack.ServiceHost
+{
+	/// <summary>
+	/// Allow the registration of user-defined routes for services
+	/// </summary>
+	public interface IServiceRoutes
+	{
+		/// <summary>
+		///		Maps the specified REST path to the specified request DTO.
+		/// </summary>
+		/// <typeparam name="TRequest">The type of request DTO to map 
+		///		the path to.</typeparam>
+		/// <param name="restPath">The path to map the request DTO to.
+		///		See <see cref="RestServiceAttribute.Path">RestServiceAttribute.Path</see>
+		///		for details on the correct format.</param>
+		/// <returns>The same <see cref="IServiceRoutes"/> instance;
+		///		never <see langword="null"/>.</returns>
+		IServiceRoutes Add<TRequest>(string restPath);
+
+		/// <summary>
+		///		Maps the specified REST path to the specified request DTO, and
+		///		specifies the HTTP verbs supported by the path.
+		/// </summary>
+		/// <typeparam name="TRequest">The type of request DTO to map 
+		///		the path to.</typeparam>
+		/// <param name="restPath">The path to map the request DTO to.
+		///		See <see cref="RestServiceAttribute.Path">RestServiceAttribute.Path</see>
+		///		for details on the correct format.</param>
+		/// <param name="verbs">
+		///		The comma-delimited list of HTTP verbs supported by the path, 
+		///		such as "GET,PUT,DELETE".  Specify empty or <see langword="null"/>
+		///		to indicate that all verbs are supported.
+		/// </param>
+		/// <returns>The same <see cref="IServiceRoutes"/> instance;
+		///		never <see langword="null"/>.</returns>
+		IServiceRoutes Add<TRequest>(string restPath, string verbs);
+
+		/// <summary>
+		///		Maps the specified REST path to the specified request DTO, 
+		///		specifies the HTTP verbs supported by the path, and indicates
+		///		the default MIME type of the returned response.
+		/// </summary>
+		/// <param name="requestType">
+		///		The type of request DTO to map the path to.
+		/// </param>
+		/// <param name="restPath">The path to map the request DTO to.
+		///		See <see cref="RestServiceAttribute.Path">RestServiceAttribute.Path</see>
+		///		for details on the correct format.</param>
+		/// <param name="verbs">
+		///		The comma-delimited list of HTTP verbs supported by the path, 
+		///		such as "GET,PUT,DELETE".
+		/// </param>
+		/// <returns>The same <see cref="IServiceRoutes"/> instance;
+		///		never <see langword="null"/>.</returns>
+		IServiceRoutes Add(System.Type requestType, string restPath, string verbs);
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/RestServiceAttribute.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/RestServiceAttribute.cs
new file mode 100644
index 0000000..3a13508
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/RestServiceAttribute.cs
@@ -0,0 +1,43 @@
+using System;
+
+namespace ServiceStack.ServiceHost
+{
+	/// <summary>
+	///		Used to decorate Request DTO's to associate a RESTful request 
+	///		path mapping with a service.  Multiple attributes can be applied to 
+	///		each request DTO, to map multiple paths to the service.
+	/// </summary>
+    [Obsolete("Use [Route] instead of [RestService].")]
+    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
+    public class RestServiceAttribute
+        : RouteAttribute
+    {
+        /// <summary>
+        /// 	<para>Initializes an instance of the <see cref="RestServiceAttribute"/> class.</para>
+        /// </summary>
+        /// <param name="path">
+        /// 	<para>The path template to map to the request.  See 
+        ///		<see cref="Path">RestServiceAttribute.Path</see>
+        ///		for details on the correct format.</para>
+        /// </param>
+        public RestServiceAttribute(string path)
+            : base(path, null)
+        {
+        }
+
+        /// <summary>
+        /// 	<para>Initializes an instance of the <see cref="RestServiceAttribute"/> class.</para>
+        /// </summary>
+        /// <param name="path">
+        /// 	<para>The path template to map to the request.  See 
+        ///		<see cref="Path">RestServiceAttribute.Path</see>
+        ///		for details on the correct format.</para>
+        /// </param>
+        /// <param name="verbs">A comma-delimited list of HTTP verbs supported by the 
+        ///		service.  If unspecified, all verbs are assumed to be supported.</param>
+        public RestServiceAttribute(string path, string verbs)
+            : base(path, verbs)
+        {
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/RouteAttribute.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/RouteAttribute.cs
new file mode 100644
index 0000000..ec2702f
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/RouteAttribute.cs
@@ -0,0 +1,104 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace ServiceStack.ServiceHost
+{
+    /// <summary>
+    ///		Used to decorate Request DTO's to associate a RESTful request 
+    ///		path mapping with a service.  Multiple attributes can be applied to 
+    ///		each request DTO, to map multiple paths to the service.
+    /// </summary>
+    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
+    public class RouteAttribute : Attribute
+    {
+        /// <summary>
+		/// 	<para>Initializes an instance of the <see cref="RouteAttribute"/> class.</para>
+		/// </summary>
+		/// <param name="path">
+		/// 	<para>The path template to map to the request.  See 
+		///		<see cref="Path">RouteAttribute.Path</see>
+		///		for details on the correct format.</para>
+		/// </param>
+		public RouteAttribute(string path)
+			: this(path, null)
+		{
+		}
+
+		/// <summary>
+		/// 	<para>Initializes an instance of the <see cref="RouteAttribute"/> class.</para>
+		/// </summary>
+		/// <param name="path">
+		/// 	<para>The path template to map to the request.  See 
+		///		<see cref="Path">RouteAttribute.Path</see>
+		///		for details on the correct format.</para>
+		/// </param>
+		/// <param name="verbs">A comma-delimited list of HTTP verbs supported by the 
+		///		service.  If unspecified, all verbs are assumed to be supported.</param>
+		public RouteAttribute(string path, string verbs)
+		{
+            Path = path;
+            Verbs = verbs;
+		}
+
+		/// <summary>
+		///		Gets or sets the path template to be mapped to the request.
+		/// </summary>
+		/// <value>
+		///		A <see cref="String"/> value providing the path mapped to
+		///		the request.  Never <see langword="null"/>.
+		/// </value>
+		/// <remarks>
+		///		<para>Some examples of valid paths are:</para>
+		/// 
+		///		<list>
+		///			<item>"/Inventory"</item>
+		///			<item>"/Inventory/{Category}/{ItemId}"</item>
+		///			<item>"/Inventory/{ItemPath*}"</item>
+		///		</list>
+		/// 
+		///		<para>Variables are specified within "{}"
+		///		brackets.  Each variable in the path is mapped to the same-named property 
+		///		on the request DTO.  At runtime, ServiceStack will parse the 
+		///		request URL, extract the variable values, instantiate the request DTO,
+		///		and assign the variable values into the corresponding request properties,
+		///		prior to passing the request DTO to the service object for processing.</para>
+		/// 
+		///		<para>It is not necessary to specify all request properties as
+		///		variables in the path.  For unspecified properties, callers may provide 
+		///		values in the query string.  For example: the URL 
+		///		"http://services/Inventory?Category=Books&ItemId=12345" causes the same 
+		///		request DTO to be processed as "http://services/Inventory/Books/12345", 
+		///		provided that the paths "/Inventory" (which supports the first URL) and 
+		///		"/Inventory/{Category}/{ItemId}" (which supports the second URL)
+		///		are both mapped to the request DTO.</para>
+		/// 
+		///		<para>Please note that while it is possible to specify property values
+		///		in the query string, it is generally considered to be less RESTful and
+		///		less desirable than to specify them as variables in the path.  Using the 
+		///		query string to specify property values may also interfere with HTTP
+		///		caching.</para>
+		/// 
+		///		<para>The final variable in the path may contain a "*" suffix
+		///		to grab all remaining segments in the path portion of the request URL and assign
+		///		them to a single property on the request DTO.
+		///		For example, if the path "/Inventory/{ItemPath*}" is mapped to the request DTO,
+		///		then the request URL "http://services/Inventory/Books/12345" will result
+		///		in a request DTO whose ItemPath property contains "Books/12345".
+		///		You may only specify one such variable in the path, and it must be positioned at
+		///		the end of the path.</para>
+		/// </remarks>
+		public string Path { get; set; }
+
+		/// <summary>
+		///		Gets or sets a comma-delimited list of HTTP verbs supported by the service, such as
+		///		"GET,PUT,POST,DELETE".
+		/// </summary>
+		/// <value>
+		///		A <see cref="String"/> providing a comma-delimited list of HTTP verbs supported
+		///		by the service, <see langword="null"/> or empty if all verbs are supported.
+		/// </value>
+		public string Verbs { get; set; }
+    }
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/ServiceAttribute.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/ServiceAttribute.cs
new file mode 100644
index 0000000..6e43ce7
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceHost/ServiceAttribute.cs
@@ -0,0 +1,133 @@
+using System;
+using System.Collections.Generic;
+
+namespace ServiceStack.ServiceHost
+{
+	/// <summary>
+	/// Used to decorate Request DTO's to alter the behaviour of a service.
+	/// </summary>
+	[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
+	public class ServiceAttribute
+		: Attribute
+	{
+		/// <summary>
+		/// Sets a single access restriction
+		/// </summary>
+		/// <value>The restrict access to.</value>
+		public EndpointAttributes RestrictAccessTo
+		{
+			get
+			{
+				return this.RestrictAccessToScenarios.Length == 0
+				       	? EndpointAttributes.All
+				       	: this.RestrictAccessToScenarios[0];
+			}
+			set
+			{
+				this.RestrictAccessToScenarios = new[] { value };
+			}
+		}
+
+		/// <summary>
+		/// Set multiple access scenarios
+		/// </summary>
+		/// <value>The restrict access to scenarios.</value>
+		public EndpointAttributes[] RestrictAccessToScenarios { get; private set; }
+
+		public int? Version { get; set; }
+
+		public ServiceAttribute()
+		{
+			this.RestrictAccessToScenarios = new EndpointAttributes[0];
+		}
+
+		public ServiceAttribute(params EndpointAttributes[] restrictAccessToScenarios)
+			: this()
+		{
+			if (restrictAccessToScenarios.Length == 0)
+			{
+				this.RestrictAccessTo = EndpointAttributes.All;
+				return;
+			}
+
+			var scenarios = new List<EndpointAttributes>();
+			foreach (var restrictAccessToScenario in restrictAccessToScenarios)
+			{
+				var restrictAccessTo = EndpointAttributes.None;
+
+				//Network access
+				if (!HasAnyRestrictionsOf(restrictAccessToScenario, EndpointAttributes.AllNetworkAccessTypes))
+				{
+					restrictAccessTo |= EndpointAttributes.AllNetworkAccessTypes;
+				}
+				else
+				{
+					restrictAccessTo |= (restrictAccessToScenario & EndpointAttributes.AllNetworkAccessTypes);
+				}
+
+				//Security
+				if (!HasAnyRestrictionsOf(restrictAccessToScenario, EndpointAttributes.AllSecurityModes))
+				{
+					restrictAccessTo |= EndpointAttributes.AllSecurityModes;
+				}
+				else
+				{
+					restrictAccessTo |= (restrictAccessToScenario & EndpointAttributes.AllSecurityModes);
+				}
+
+				//Http Method
+				if (!HasAnyRestrictionsOf(restrictAccessToScenario, EndpointAttributes.AllHttpMethods))
+				{
+					restrictAccessTo |= EndpointAttributes.AllHttpMethods;
+				}
+				else
+				{
+					restrictAccessTo |= (restrictAccessToScenario & EndpointAttributes.AllHttpMethods);
+				}
+
+				//Call style
+				if (!HasAnyRestrictionsOf(restrictAccessToScenario, EndpointAttributes.AllCallStyles))
+				{
+					restrictAccessTo |= EndpointAttributes.AllCallStyles;
+				}
+				else
+				{
+					restrictAccessTo |= (restrictAccessToScenario & EndpointAttributes.AllCallStyles);
+				}
+
+				//Endpoint
+				if (!HasAnyRestrictionsOf(restrictAccessToScenario, EndpointAttributes.AllEndpointTypes))
+				{
+					restrictAccessTo |= EndpointAttributes.AllEndpointTypes;
+				}
+				else
+				{
+					restrictAccessTo |= (restrictAccessToScenario & EndpointAttributes.AllEndpointTypes);
+				}
+
+				scenarios.Add(restrictAccessTo);
+			}
+
+			this.RestrictAccessToScenarios = scenarios.ToArray();
+		}
+
+		static bool HasAnyRestrictionsOf(EndpointAttributes allRestrictions, EndpointAttributes restrictions)
+		{
+			return (allRestrictions & restrictions) != 0;
+		}
+
+		public ServiceAttribute(int version, params EndpointAttributes[] restrictAccessScenarios)
+			: this(restrictAccessScenarios)
+		{
+			this.Version = version;
+		}
+
+		public bool HasNoAccessRestrictions
+		{
+			get
+			{
+				return this.RestrictAccessTo == EndpointAttributes.All;
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceInterface.ServiceModel/CollectionTypes.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceInterface.ServiceModel/CollectionTypes.cs
new file mode 100644
index 0000000..328c4e8
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceInterface.ServiceModel/CollectionTypes.cs
@@ -0,0 +1,108 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace ServiceStack.ServiceInterface.ServiceModel
+{
+	/*
+	 * Useful collection DTO's that provide pretty Xml output for collection types, e.g.
+	 * 
+	 * ArrayOfIntId Ids { get; set; }		
+	 * ... =>
+	 * 
+	 * <Ids>
+	 *   <Id>1</Id>
+	 *   <Id>2</Id>
+	 *   <Id>3</Id>
+	 * <Ids>
+	 */
+
+	[CollectionDataContract(ItemName = "String")]
+	public partial class ArrayOfString : List<string>
+	{
+		public ArrayOfString()
+		{
+		}
+
+		public ArrayOfString(IEnumerable<string> collection) : base(collection) { }
+		public ArrayOfString(params string[] args) : base(args) { }
+	}
+
+	[CollectionDataContract(ItemName = "Id")]
+	public partial class ArrayOfStringId : List<string>
+	{
+		public ArrayOfStringId()
+		{
+		}
+
+		public ArrayOfStringId(IEnumerable<string> collection) : base(collection) { }
+		public ArrayOfStringId(params string[] args) : base(args) { }
+	}
+
+	[CollectionDataContract(ItemName = "Guid")]
+	public partial class ArrayOfGuid : List<Guid>
+	{
+		public ArrayOfGuid()
+		{
+		}
+
+		public ArrayOfGuid(IEnumerable<Guid> collection) : base(collection) { }
+		public ArrayOfGuid(params Guid[] args) : base(args) { }
+	}
+
+	[CollectionDataContract(ItemName = "Id")]
+	public partial class ArrayOfGuidId : List<Guid>
+	{
+		public ArrayOfGuidId()
+		{
+		}
+
+		public ArrayOfGuidId(IEnumerable<Guid> collection) : base(collection) { }
+		public ArrayOfGuidId(params Guid[] args) : base(args) { }
+	}
+
+	[CollectionDataContract(ItemName = "Long")]
+	public partial class ArrayOfLong : List<long>
+	{
+		public ArrayOfLong()
+		{
+		}
+
+		public ArrayOfLong(IEnumerable<long> collection) : base(collection) { }
+		public ArrayOfLong(params long[] args) : base(args) { }
+	}
+
+	[CollectionDataContract(ItemName = "Id")]
+	public partial class ArrayOfLongId : List<long>
+	{
+		public ArrayOfLongId()
+		{
+		}
+
+		public ArrayOfLongId(IEnumerable<long> collection) : base(collection) { }
+		public ArrayOfLongId(params long[] args) : base(args) { }
+	}
+
+	[CollectionDataContract(ItemName = "Int")]
+	public partial class ArrayOfInt : List<int>
+	{
+		public ArrayOfInt()
+		{
+		}
+
+		public ArrayOfInt(IEnumerable<int> collection) : base(collection) { }
+		public ArrayOfInt(params int[] args) : base(args) { }
+	}
+
+	[CollectionDataContract(ItemName = "Id")]
+	public partial class ArrayOfIntId : List<int>
+	{
+		public ArrayOfIntId ()
+		{
+		}
+
+		public ArrayOfIntId(IEnumerable<int> collection) : base(collection) { }
+		public ArrayOfIntId(params int[] args) : base(args) { }
+	}
+
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceInterface.ServiceModel/ICacheByDateModified.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceInterface.ServiceModel/ICacheByDateModified.cs
new file mode 100644
index 0000000..7cdf17e
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceInterface.ServiceModel/ICacheByDateModified.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace ServiceStack.ServiceInterface.ServiceModel
+{
+	public interface ICacheByDateModified
+	{
+		DateTime? LastModified { get; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceInterface.ServiceModel/ICacheByEtag.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceInterface.ServiceModel/ICacheByEtag.cs
new file mode 100644
index 0000000..6ec39a8
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceInterface.ServiceModel/ICacheByEtag.cs
@@ -0,0 +1,7 @@
+namespace ServiceStack.ServiceInterface.ServiceModel
+{
+	public interface ICacheByEtag
+	{
+		string Etag { get; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceInterface.ServiceModel/IHasAction.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceInterface.ServiceModel/IHasAction.cs
new file mode 100644
index 0000000..8bf09c7
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceInterface.ServiceModel/IHasAction.cs
@@ -0,0 +1,7 @@
+namespace ServiceStack.ServiceInterface.ServiceModel
+{
+	public interface IHasAction
+	{
+		string Action { get; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceInterface.ServiceModel/IHasResponseStatus.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceInterface.ServiceModel/IHasResponseStatus.cs
new file mode 100644
index 0000000..a1d7d9c
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceInterface.ServiceModel/IHasResponseStatus.cs
@@ -0,0 +1,10 @@
+namespace ServiceStack.ServiceInterface.ServiceModel
+{
+	/// <summary>
+	/// Contract indication that the Response DTO has a ResponseStatus
+	/// </summary>
+	public interface IHasResponseStatus
+	{
+		ResponseStatus ResponseStatus { get; set; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceInterface.ServiceModel/Property.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceInterface.ServiceModel/Property.cs
new file mode 100644
index 0000000..b046330
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceInterface.ServiceModel/Property.cs
@@ -0,0 +1,19 @@
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace ServiceStack.ServiceInterface.ServiceModel
+{
+	[DataContract]
+	public class Property
+	{
+		public string Name { get; set; }
+		public string Value { get; set; }
+	}
+
+	[CollectionDataContract(ItemName = "Property")]
+	public class Properties : List<Property>
+	{
+		public Properties() { }
+		public Properties(IEnumerable<Property> collection) : base(collection) { }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceInterface.ServiceModel/RequestLogEntry.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceInterface.ServiceModel/RequestLogEntry.cs
new file mode 100644
index 0000000..854b7a5
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceInterface.ServiceModel/RequestLogEntry.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+
+namespace ServiceStack.ServiceInterface.ServiceModel
+{
+	/// <summary>
+	/// A log entry added by the IRequestLogger
+	/// </summary>
+	public class RequestLogEntry
+	{
+		public long Id { get; set; }
+		public DateTime DateTime { get; set; }
+		public string HttpMethod { get; set; }
+		public string AbsoluteUri { get; set; }
+		public string PathInfo { get; set; }
+		public object RequestDto { get; set; }
+		public string UserAuthId { get; set; }
+		public string SessionId { get; set; }
+		public string IpAddress { get; set; }
+		public string ForwardedFor { get; set; }
+		public string Referer { get; set; }
+		public Dictionary<string, string> Headers { get; set; }
+		public Dictionary<string, string> FormData { get; set; }
+		public Dictionary<string, object> Items { get; set; }
+		public object Session { get; set; }
+		public object ResponseDto { get; set; }
+		public object ErrorResponse { get; set; }
+        public TimeSpan RequestDuration { get; set; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceInterface.ServiceModel/ResponseError.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceInterface.ServiceModel/ResponseError.cs
new file mode 100644
index 0000000..1fc547f
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceInterface.ServiceModel/ResponseError.cs
@@ -0,0 +1,31 @@
+/*
+// $Id: ResponseError.cs 11037 2010-02-03 12:36:14Z Demis Bellot $
+//
+// Revision      : $Revision: 11037 $
+// Modified Date : $LastChangedDate: 2010-02-03 12:36:14 +0000 (Wed, 03 Feb 2010) $
+// Modified By   : $LastChangedBy: Demis Bellot $
+//
+// (c) Copyright 2010 Liquidbit Ltd
+*/
+
+using System.Runtime.Serialization;
+
+namespace ServiceStack.ServiceInterface.ServiceModel
+{
+	/// <summary>
+	/// Error information pertaining to a particular named field.
+	/// Used for returning multiple field validation errors.s
+	/// </summary>
+	[DataContract]
+	public class ResponseError
+	{
+		[DataMember]
+		public string ErrorCode { get; set; }
+
+		[DataMember]
+		public string FieldName { get; set; }
+	
+		[DataMember]
+		public string Message { get; set; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceInterface.ServiceModel/ResponseStatus.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceInterface.ServiceModel/ResponseStatus.cs
new file mode 100644
index 0000000..86536b1
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceInterface.ServiceModel/ResponseStatus.cs
@@ -0,0 +1,80 @@
+/*
+// $Id: ResponseStatus.cs 11037 2010-02-03 12:36:14Z Demis Bellot $
+//
+// Revision      : $Revision: 11037 $
+// Modified Date : $LastChangedDate: 2010-02-03 12:36:14 +0000 (Wed, 03 Feb 2010) $
+// Modified By   : $LastChangedBy: Demis Bellot $
+//
+// (c) Copyright 2010 Liquidbit Ltd
+*/
+
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace ServiceStack.ServiceInterface.ServiceModel
+{
+	/// <summary>
+	/// Common ResponseStatus class that should be present on all response DTO's
+	/// </summary>
+	[DataContract]
+	public class ResponseStatus
+	{
+		/// <summary>
+		/// Initializes a new instance of the <see cref="ResponseStatus"/> class.
+		/// 
+		/// A response status without an errorcode == success
+		/// </summary>
+		public ResponseStatus()
+		{
+		}
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ResponseStatus"/> class.
+        /// 
+        /// A response status with an errorcode == failure
+        /// </summary>
+        public ResponseStatus(string errorCode)
+        {
+            this.ErrorCode = errorCode;
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ResponseStatus"/> class.
+        /// 
+        /// A response status with an errorcode == failure
+        /// </summary>
+        public ResponseStatus(string errorCode, string message)
+            : this(errorCode)
+        {
+            this.Message = message;
+        }
+        
+		/// <summary>
+		/// Holds the custom ErrorCode enum if provided in ValidationException
+		/// otherwise will hold the name of the Exception type, e.g. typeof(Exception).Name
+		/// 
+		/// A value of non-null means the service encountered an error while processing the request.
+		/// </summary>
+		[DataMember]
+		public string ErrorCode { get; set; }
+
+		/// <summary>
+		/// A human friendly error message
+		/// </summary>
+		[DataMember]
+		public string Message { get; set; }
+
+		/// <summary>
+		/// 
+		/// </summary>
+		[DataMember]
+		public string StackTrace { get; set; }
+
+		/// <summary>
+		/// For multiple detailed validation errors.
+		/// Can hold a specific error message for each named field.
+		/// </summary>
+		[DataMember]
+		public List<ResponseError> Errors { get; set; }
+	}
+}
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceStack.Interfaces.csproj b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceStack.Interfaces.csproj
new file mode 100644
index 0000000..b3a55b1
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/ServiceStack.Interfaces.csproj
@@ -0,0 +1,660 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{42E1C8C0-A163-44CC-92B1-8F416F2C0B01}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>ServiceStack</RootNamespace>
+    <AssemblyName>ServiceStack.Interfaces</AssemblyName>
+    <FileAlignment>512</FileAlignment>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation />
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+  </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>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <TreatWarningsAsErrors>True</TreatWarningsAsErrors>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>True</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <DocumentationFile>bin\Release\ServiceStack.Interfaces.XML</DocumentationFile>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'MONOTOUCH|AnyCPU'">
+    <OutputPath>bin\MONOTOUCH\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <DocumentationFile>bin\Release\ServiceStack.Interfaces.XML</DocumentationFile>
+    <Optimize>True</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <CodeAnalysisLogFile>bin\Release\ServiceStack.Interfaces.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+    <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+    <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRuleSetDirectories>;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+    <CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
+    <CodeAnalysisRuleDirectories>;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Runtime.Serialization" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="CacheAccess\ICacheClearable.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="CacheAccess\ICacheClient.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="CacheAccess\ICacheHasContentType.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="CacheAccess\ICacheManager.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="CacheAccess\ICacheTextManager.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="CacheAccess\ICacheTextManagerFactory.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="CacheAccess\ICompressableCacheTextManager.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="CacheAccess\ICompressableCacheTextManagerFactory.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="CacheAccess\IDeflateProvider.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="CacheAccess\IGZipProvider.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="CacheAccess\IHasCacheClient.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="CacheAccess\IMemcachedClient.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="CacheAccess\IPersistenceProviderCache.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="CacheAccess\IPersistenceProviderCacheFactory.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="CacheAccess\ISession.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="CacheAccess\ISessionFactory.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Configuration\IContainerAdapter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Configuration\IFactoryProvider.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Configuration\IRelease.cs" />
+    <Compile Include="Configuration\IResourceManager.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Configuration\ITypeFactory.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DataAccess\Criteria\ICriteria.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DataAccess\Criteria\IOrderAscendingCriteria.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DataAccess\Criteria\IOrderDescendingCriteria.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DataAccess\Criteria\IPagingCriteria.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DataAccess\Criteria\PagingCriteria.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DataAccess\DataAccessException.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DataAccess\IAggregatable.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DataAccess\IBasicPersistenceProvider.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DataAccess\IBasicPersistenceProvider.Generic.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DataAccess\IHasDbConnection.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DataAccess\IPersistenceProvider.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DataAccess\IPersistenceProviderManager.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DataAccess\IPersistenceProviderManagerFactory.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DataAccess\IQueryable.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DataAccess\IQueryableByComparer.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DataAccess\IQueryableByExample.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DataAccess\IQueryableByPredicate.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DataAccess\IQueryablePersistenceProvider.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DataAccess\IResultSet.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DataAccess\ITransactionContext.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DataAnnotations\AliasAttribute.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DataAnnotations\AutoIncrementAttribute.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DataAnnotations\CompositeIndexAttribute.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DataAnnotations\DefaultAttribute.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DataAnnotations\IndexAttribute.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DataAnnotations\ReferencesAttribute.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DesignPatterns\Command\ICommand.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DesignPatterns\Command\ICommandExec.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DesignPatterns\Command\ICommandIEnumerable.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DesignPatterns\Command\ICommandIList.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DesignPatterns\Command\ICommandList.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DesignPatterns\Command\ICommandVoid.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DesignPatterns\Model\IHasGuidId.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DesignPatterns\Model\IHasId.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DesignPatterns\Model\IHasIntId.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DesignPatterns\Model\IHasLongId.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DesignPatterns\Model\IHasNamed.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DesignPatterns\Model\IHasNamedCollection.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DesignPatterns\Model\IHasNamedList.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DesignPatterns\Model\IHasStringId.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DesignPatterns\Model\IHasUserId.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DesignPatterns\Model\IHasUserSession.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DesignPatterns\Serialization\IStringDeserializer.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DesignPatterns\Serialization\IStringSerializer.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DesignPatterns\Serialization\ITextSerializer.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DesignPatterns\Translator\ITranslator.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Logging\ILog.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Logging\ILogFactory.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Logging\LogManager.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Logging\Support\Logging\ConsoleLogFactory.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Logging\Support\Logging\ConsoleLogger.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Logging\Support\Logging\DebugLogFactory.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Logging\Support\Logging\DebugLogger.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Logging\Support\Logging\NullDebugLogger.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Logging\Support\Logging\NullLogFactory.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Logging\Support\Logging\TestLogFactory.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Logging\Support\Logging\TestLogger.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="LogicFacade\IApplicationContext.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="LogicFacade\IInitContext.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="LogicFacade\ILogicFacade.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="LogicFacade\InitOptions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="LogicFacade\IOperationContext.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="LogicFacade\IServiceModelFinder.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="LogicFacade\IXmlRequest.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Messaging\IMessage.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Messaging\IMessageFactory.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Messaging\IMessageProducer.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Messaging\IMessageQueueClient.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Messaging\IMessageQueueClientFactory.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Messaging\IMessageService.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Messaging\MessageError.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Messaging\MessageFactory.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Messaging\MessageHandlerStats.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Messaging\MessageOption.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Messaging\MessagingException.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Messaging\QueueNames.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Messaging\UnRetryableMessagingException.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="OrmLite\DbConnectionFactory.cs" />
+    <Compile Include="OrmLite\IDbConnectionFactory.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Redis\Generic\IRedisHash.Generic.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Redis\Generic\IRedisList.Generic.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Redis\Generic\IRedisSet.Generic.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Redis\Generic\IRedisSortedSet.Generic.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Redis\Generic\IRedisTransaction.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Redis\Generic\IRedisTypedClient.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Redis\Generic\IRedisTypedPipeline.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Redis\Generic\IRedisTypedQueueableOperation.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Redis\IRedisClient.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Redis\IRedisClientCacheManager.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Redis\IRedisClientsManager.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Redis\IRedisHash.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Redis\IRedisList.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Redis\IRedisNativeClient.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Redis\IRedisSet.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Redis\IRedisSortedSet.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Redis\IRedisSubscription.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Redis\IRedisTransaction.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Redis\IRedisTransactionBase.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Redis\ItemRef.cs" />
+    <Compile Include="Redis\Pipeline\IRedisPipeline.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Redis\Pipeline\IRedisPipelineShared.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Redis\Pipeline\IRedisQueueableOperation.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Redis\Pipeline\IRedisQueueCompletableOperation.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Redis\RedisKeyType.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Redis\SortOptions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="SearchIndex\FullTextIndexAttribute.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="SearchIndex\FullTextIndexDocumentAttribute.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="SearchIndex\FullTextIndexFieldAttribute.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceHost\IRequiresHttpRequest.cs" />
+    <Compile Include="ServiceHost\IRequiresRequestStream.cs" />
+    <Compile Include="ServiceHost\EndpointAttributes.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceHost\Feature.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceHost\IAsyncService.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceHost\IResolver.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceHost\IContentTypeFilter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceHost\IContentTypeReader.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceHost\IContentTypeWriter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceHost\ICookies.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceHost\IExpirable.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceHost\IFile.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceHost\IHasOptions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceHost\IHasRequestFilter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceHost\IHasResponseFilter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceHost\IHttpError.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceHost\IHttpRequest.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceHost\IHttpResponse.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceHost\IHttpResult.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceHost\IRequestAttributes.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceHost\IRequestContext.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceHost\IRequestLogger.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceHost\IRequiresRequestContext.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceHost\IRestDeleteService.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceHost\IRestGetService.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceHost\IRestPatchService.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceHost\IRestPath.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceHost\IRestPostService.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceHost\IRestPutService.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceHost\IRestService.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceHost\IService.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceHost\IServiceController.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceHost\IServiceRoutes.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceHost\RouteAttribute.cs" />
+    <Compile Include="ServiceInterface.ServiceModel\RequestLogEntry.cs" />
+    <Compile Include="ServiceHost\RestServiceAttribute.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceHost\ServiceAttribute.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceInterface.ServiceModel\CollectionTypes.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceInterface.ServiceModel\ICacheByDateModified.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceInterface.ServiceModel\ICacheByEtag.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceInterface.ServiceModel\IHasAction.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceInterface.ServiceModel\IHasResponseStatus.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceInterface.ServiceModel\Property.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceInterface.ServiceModel\ResponseError.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ServiceInterface.ServiceModel\ResponseStatus.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Service\IOneWayClient.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Service\IReplyClient.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Service\IResponseBase.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Service\IResponseStatus.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Service\IRestClient.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Service\IRestClientAsync.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Service\IServiceClient.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Service\IServiceClientAsync.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Service\IStreamWriter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Translators\TranslateAttribute.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Translators\TranslateExtensionAttribute.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Translators\TranslateMemberAttribute.cs">
+      <SubType>Code</SubType>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+      <Visible>False</Visible>
+      <ProductName>Windows Installer 3.1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="README.md" />
+    <None Include="Redis\Redis.cd" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="Redis\Redis-annotated.png" />
+    <Content Include="Redis\Redis.png" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\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>
+  -->
+  <ItemGroup />
+</Project>
\ No newline at end of file
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Translators/TranslateAttribute.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Translators/TranslateAttribute.cs
new file mode 100644
index 0000000..4486718
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Translators/TranslateAttribute.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace ServiceStack.Translators
+{
+	/// <summary>
+	/// This instructs the generator tool to generate translator methods for the types supplied.
+	/// A {TypeName}.generated.cs partial class will be generated that contains the methods required
+	/// to generate to and from that type.
+	/// </summary>
+	[AttributeUsage(AttributeTargets.Class)]
+	public class TranslateAttribute : Attribute
+	{
+		public string SourceMethodPrefix { get; set; }
+		public string TargetMethodPrefix { get; set; }
+		public Type SourceType { get; set; }
+		public Type TargetType { get; set; }
+
+		public TranslateAttribute(Type targetType) 
+			: this(null, targetType) {}
+
+		public TranslateAttribute(string sourceExtensionPrefix, Type targetType, string targetExtensionPrefix)
+			: this(null, sourceExtensionPrefix, targetType, targetExtensionPrefix) { }
+
+		protected TranslateAttribute(Type sourceType, Type targetType)
+		{
+			this.SourceType = sourceType;
+			this.TargetType = targetType;
+		}
+
+		protected TranslateAttribute(Type sourceType, string sourceExtensionPrefix, Type targetType, string targetExtensionPrefix)
+		{
+			this.SourceType = sourceType;
+			this.SourceMethodPrefix = sourceExtensionPrefix;
+			this.TargetType = targetType;
+			this.TargetMethodPrefix = targetExtensionPrefix;
+		}
+	}
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Translators/TranslateExtensionAttribute.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Translators/TranslateExtensionAttribute.cs
new file mode 100644
index 0000000..05db17e
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Translators/TranslateExtensionAttribute.cs
@@ -0,0 +1,23 @@
+using System;
+
+namespace ServiceStack.Translators
+{
+	/// <summary>
+	/// This instructs the generator tool to generate translator extension methods for the types supplied.
+	/// A {TypeName}.generated.cs static class will be generated that contains the extension methods required
+	/// to generate to and from that type.
+	/// 
+	/// The source type is what the type the attribute is decorated on which can only be resolved at runtime.
+	/// </summary>
+	[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
+	public class TranslateExtensionAttribute : TranslateAttribute
+	{
+
+		public TranslateExtensionAttribute(Type sourceType, Type targetType)
+			: base(sourceType, targetType) {}
+
+		public TranslateExtensionAttribute(Type sourceType, string sourceExtensionPrefix, Type targetType, string targetExtensionPrefix)
+			:base(sourceType, sourceExtensionPrefix, targetType, targetExtensionPrefix) {}
+	}
+
+}
diff --git a/lib/ServiceStack/src/ServiceStack.Interfaces/Translators/TranslateMemberAttribute.cs b/lib/ServiceStack/src/ServiceStack.Interfaces/Translators/TranslateMemberAttribute.cs
new file mode 100644
index 0000000..2d4d07c
--- /dev/null
+++ b/lib/ServiceStack/src/ServiceStack.Interfaces/Translators/TranslateMemberAttribute.cs
@@ -0,0 +1,18 @@
+using System;
+
+namespace ServiceStack.Translators
+{
+	/// <summary>
+	/// This changes the default behaviour for the 
+	/// </summary>
+	[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
+	public class TranslateMemberAttribute : Attribute
+	{
+		public string PropertyName { get; set; }
+
+		public TranslateMemberAttribute(string toPropertyName)
+		{
+			this.PropertyName = toPropertyName;
+		}
+	}
+}
\ No newline at end of file
diff --git a/lib/SmartIrc4net/SmartIrc4net.csproj b/lib/SmartIrc4net/SmartIrc4net.csproj
index 2056ab0..1cf706f 100644
--- a/lib/SmartIrc4net/SmartIrc4net.csproj
+++ b/lib/SmartIrc4net/SmartIrc4net.csproj
@@ -88,4 +88,4 @@
     <Reference Include="System.Core" />
   </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-</Project>
\ No newline at end of file
+</Project>
diff --git a/lib/SmartIrc4net/src/IrcClient/Delegates.cs b/lib/SmartIrc4net/src/IrcClient/Delegates.cs
index 2dc40e0..995a311 100644
--- a/lib/SmartIrc4net/src/IrcClient/Delegates.cs
+++ b/lib/SmartIrc4net/src/IrcClient/Delegates.cs
@@ -39,6 +39,10 @@ namespace Meebey.SmartIrc4net
     public delegate void ListEventHandler(object sender, ListEventArgs e);
     public delegate void PartEventHandler(object sender, PartEventArgs e);
     public delegate void InviteEventHandler(object sender, InviteEventArgs e);
+    public delegate void OwnerEventHandler(object sender, OwnerEventArgs e);
+    public delegate void DeownerEventHandler(object sender, DeownerEventArgs e);
+    public delegate void ChannelAdminEventHandler(object sender, ChannelAdminEventArgs e);
+    public delegate void DeChannelAdminEventHandler(object sender, DeChannelAdminEventArgs e);
     public delegate void OpEventHandler(object sender, OpEventArgs e);
     public delegate void DeopEventHandler(object sender, DeopEventArgs e);
     public delegate void HalfopEventHandler(object sender, HalfopEventArgs e);
diff --git a/lib/SmartIrc4net/src/IrcClient/EventArgs.cs b/lib/SmartIrc4net/src/IrcClient/EventArgs.cs
index 648348c..da7f9e8 100644
--- a/lib/SmartIrc4net/src/IrcClient/EventArgs.cs
+++ b/lib/SmartIrc4net/src/IrcClient/EventArgs.cs
@@ -230,7 +230,8 @@ namespace Meebey.SmartIrc4net
     {
         private string   _Channel;
         private string[] _UserList;
-        
+        public string[] RawUserList { get; private set; }
+
         public string Channel {
             get {
                 return _Channel;
@@ -243,10 +244,11 @@ namespace Meebey.SmartIrc4net
             }
         }
          
-        internal NamesEventArgs(IrcMessageData data, string channel, string[] userlist) : base(data)
+        internal NamesEventArgs(IrcMessageData data, string channel, string[] userlist, string[] rawUserList) : base(data)
         {
             _Channel = channel;
             _UserList = userlist;
+            RawUserList = rawUserList;
         }
     }
 
@@ -641,212 +643,119 @@ namespace Meebey.SmartIrc4net
     }
 
     /// <summary>
-    ///
+    /// Event arguments for any change in channel role.
     /// </summary>
-    public class OpEventArgs : IrcEventArgs
+    public class ChannelRoleChangeEventArgs : IrcEventArgs
     {
-        private string   _Channel;
-        private string   _Who;
-        private string   _Whom;
-        
-        public string Channel {
-            get {
-                return _Channel;
-            }
-        }
+        public string Channel { get; private set; }
+        public string Who { get; private set; }
+        public string Whom { get; private set; }
 
-        public string Who {
-            get {
-                return _Who;
-            }
-        }
-
-        public string Whom {
-            get {
-                return _Whom;
-            }
-        }
-        
-        internal OpEventArgs(IrcMessageData data, string channel, string who, string whom) : base(data)
+        internal ChannelRoleChangeEventArgs(IrcMessageData data, string channel, string who, string whom) : base(data)
         {
-            _Channel = channel;
-            _Who = who;
-            _Whom = whom;
+            Channel = channel;
+            Who = who;
+            Whom = whom;
         }
     }
 
     /// <summary>
-    ///
+    /// User gained owner status (non-RFC, channel mode +q, prefix ~).
     /// </summary>
-    public class DeopEventArgs : IrcEventArgs
+    public class OwnerEventArgs : ChannelRoleChangeEventArgs
     {
-        private string   _Channel;
-        private string   _Who;
-        private string   _Whom;
-        
-        public string Channel {
-            get {
-                return _Channel;
-            }
-        }
-
-        public string Who {
-            get {
-                return _Who;
-            }
-        }
-
-        public string Whom {
-            get {
-                return _Whom;
-            }
-        }
-        
-        internal DeopEventArgs(IrcMessageData data, string channel, string who, string whom) : base(data)
+        internal OwnerEventArgs(IrcMessageData data, string channel, string who, string whom) : base(data, channel, who, whom)
         {
-            _Channel = channel;
-            _Who = who;
-            _Whom = whom;
         }
     }
-    
+
     /// <summary>
-    ///
+    /// User lost owner status (non-RFC, channel mode -q).
     /// </summary>
-    public class HalfopEventArgs : IrcEventArgs
+    public class DeownerEventArgs : ChannelRoleChangeEventArgs
     {
-        private string   _Channel;
-        private string   _Who;
-        private string   _Whom;
-        
-        public string Channel {
-            get {
-                return _Channel;
-            }
-        }
-
-        public string Who {
-            get {
-                return _Who;
-            }
-        }
-
-        public string Whom {
-            get {
-                return _Whom;
-            }
-        }
-        
-        internal HalfopEventArgs(IrcMessageData data, string channel, string who, string whom) : base(data)
+        internal DeownerEventArgs(IrcMessageData data, string channel, string who, string whom) : base(data, channel, who, whom)
         {
-            _Channel = channel;
-            _Who = who;
-            _Whom = whom;
         }
     }
 
     /// <summary>
-    ///
+    /// User gained channel admin status (non-RFC, channel mode +a, prefix &).
     /// </summary>
-    public class DehalfopEventArgs : IrcEventArgs
+    public class ChannelAdminEventArgs : ChannelRoleChangeEventArgs
     {
-        private string   _Channel;
-        private string   _Who;
-        private string   _Whom;
-        
-        public string Channel {
-            get {
-                return _Channel;
-            }
-        }
-
-        public string Who {
-            get {
-                return _Who;
-            }
+        internal ChannelAdminEventArgs(IrcMessageData data, string channel, string who, string whom) : base(data, channel, who, whom)
+        {
         }
+    }
 
-        public string Whom {
-            get {
-                return _Whom;
-            }
-        }
-        
-        internal DehalfopEventArgs(IrcMessageData data, string channel, string who, string whom) : base(data)
+    /// <summary>
+    /// User lost channel admin status (non-RFC, channel mode -a).
+    /// </summary>
+    public class DeChannelAdminEventArgs : ChannelRoleChangeEventArgs
+    {
+        internal DeChannelAdminEventArgs(IrcMessageData data, string channel, string who, string whom) : base(data, channel, who, whom)
         {
-            _Channel = channel;
-            _Who = who;
-            _Whom = whom;
         }
     }
-    
+
     /// <summary>
-    ///
+    /// User gained op status (channel mode +o, prefix @).
     /// </summary>
-    public class VoiceEventArgs : IrcEventArgs
+    public class OpEventArgs : ChannelRoleChangeEventArgs
     {
-        private string   _Channel;
-        private string   _Who;
-        private string   _Whom;
-        
-        public string Channel {
-            get {
-                return _Channel;
-            }
+        internal OpEventArgs(IrcMessageData data, string channel, string who, string whom) : base(data, channel, who, whom)
+        {
         }
+    }
 
-        public string Who {
-            get {
-                return _Who;
-            }
+    /// <summary>
+    /// User lost op status (channel mode -o).
+    /// </summary>
+    public class DeopEventArgs : ChannelRoleChangeEventArgs
+    {
+        internal DeopEventArgs(IrcMessageData data, string channel, string who, string whom) : base(data, channel, who, whom)
+        {
         }
+    }
 
-        public string Whom {
-            get {
-                return _Whom;
-            }
-        }
-        
-        internal VoiceEventArgs(IrcMessageData data, string channel, string who, string whom) : base(data)
+    /// <summary>
+    /// User gained halfop status (non-RFC, channel mode +h, prefix %).
+    /// </summary>
+    public class HalfopEventArgs : ChannelRoleChangeEventArgs
+    {
+        internal HalfopEventArgs(IrcMessageData data, string channel, string who, string whom) : base(data, channel, who, whom)
         {
-            _Channel = channel;
-            _Who = who;
-            _Whom = whom;
         }
     }
 
     /// <summary>
-    ///
+    /// User lost halfop status (non-RFC, channel mode -h).
     /// </summary>
-    public class DevoiceEventArgs : IrcEventArgs
+    public class DehalfopEventArgs : ChannelRoleChangeEventArgs
     {
-        private string   _Channel;
-        private string   _Who;
-        private string   _Whom;
-        
-        public string Channel {
-            get {
-                return _Channel;
-            }
+        internal DehalfopEventArgs(IrcMessageData data, string channel, string who, string whom) : base(data, channel, who, whom)
+        {
         }
+    }
 
-        public string Who {
-            get {
-                return _Who;
-            }
+    /// <summary>
+    /// User gained voice status (channel mode +v, prefix +).
+    /// </summary>
+    public class VoiceEventArgs : ChannelRoleChangeEventArgs
+    {
+        internal VoiceEventArgs(IrcMessageData data, string channel, string who, string whom) : base(data, channel, who, whom)
+        {
         }
+    }
 
-        public string Whom {
-            get {
-                return _Whom;
-            }
-        }
-        
-        internal DevoiceEventArgs(IrcMessageData data, string channel, string who, string whom) : base(data)
+    /// <summary>
+    /// User lost voice status (channel mode -v).
+    /// </summary>
+    public class DevoiceEventArgs : ChannelRoleChangeEventArgs
+    {
+        internal DevoiceEventArgs(IrcMessageData data, string channel, string who, string whom) : base(data, channel, who, whom)
         {
-            _Channel = channel;
-            _Who = who;
-            _Whom = whom;
         }
     }
 
diff --git a/lib/SmartIrc4net/src/IrcClient/IrcClient.cs b/lib/SmartIrc4net/src/IrcClient/IrcClient.cs
index 9a8c441..6562ee6 100644
--- a/lib/SmartIrc4net/src/IrcClient/IrcClient.cs
+++ b/lib/SmartIrc4net/src/IrcClient/IrcClient.cs
@@ -113,6 +113,10 @@ namespace Meebey.SmartIrc4net
         public event InviteEventHandler         OnInvite;
         public event BanEventHandler            OnBan;
         public event UnbanEventHandler          OnUnban;
+        public event OwnerEventHandler          OnOwner;
+        public event DeownerEventHandler        OnDeowner;
+        public event ChannelAdminEventHandler   OnChannelAdmin;
+        public event DeChannelAdminEventHandler OnDeChannelAdmin;
         public event OpEventHandler             OnOp;
         public event DeopEventHandler           OnDeop;
         public event HalfopEventHandler         OnHalfop;
@@ -1373,6 +1377,8 @@ namespace Meebey.SmartIrc4net
             chan.UnsafeVoices.Remove(nickname);
             if (SupportNonRfc) {
                 NonRfcChannel nchan = (NonRfcChannel)chan;
+                nchan.UnsafeOwners.Remove(nickname);
+                nchan.UnsafeChannelAdmins.Remove(nickname);
                 nchan.UnsafeHalfops.Remove(nickname);
             } 
         }
@@ -1471,6 +1477,138 @@ namespace Meebey.SmartIrc4net
                             }
                         }
                     break;
+                    case 'q':
+                        if (SupportNonRfc) {
+                            temp = (string)parametersEnumerator.Current;
+                            parametersEnumerator.MoveNext();
+
+                            if (add) {
+                                if (ActiveChannelSyncing && channel != null) {
+                                    // sanity check
+                                    if (GetChannelUser(ircdata.Channel, temp) != null) {
+                                        // update the owner list
+                                        try {
+                                            ((NonRfcChannel)channel).UnsafeOwners.Add(temp, GetIrcUser(temp));
+#if LOG4NET
+                                            Logger.ChannelSyncing.Debug("added owner: "+temp+" to: "+ircdata.Channel);
+#endif
+                                        } catch (ArgumentException) {
+#if LOG4NET
+                                            Logger.ChannelSyncing.Debug("duplicate owner: "+temp+" in: "+ircdata.Channel+" not added");
+#endif
+                                        }
+
+                                        // update the user owner status
+                                        NonRfcChannelUser cuser = (NonRfcChannelUser)GetChannelUser(ircdata.Channel, temp);
+                                        cuser.IsOwner = true;
+#if LOG4NET
+                                        Logger.ChannelSyncing.Debug("set owner status: " + temp + " for: "+ircdata.Channel);
+#endif
+                                    } else {
+#if LOG4NET
+                                        Logger.ChannelSyncing.Error("_InterpretChannelMode(): GetChannelUser(" + ircdata.Channel + "," + temp + ") returned null! Ignoring...");
+#endif
+                                    }
+                                }
+
+                                if (OnOwner != null) {
+                                    OnOwner(this, new OwnerEventArgs(ircdata, ircdata.Channel, ircdata.Nick, temp));
+                                }
+                            }
+                            if (remove) {
+                                if (ActiveChannelSyncing && channel != null) {
+                                    // sanity check
+                                    if (GetChannelUser(ircdata.Channel, temp) != null) {
+                                        // update the owner list
+                                        ((NonRfcChannel)channel).UnsafeOwners.Remove(temp);
+#if LOG4NET
+                                        Logger.ChannelSyncing.Debug("removed owner: "+temp+" from: "+ircdata.Channel);
+#endif
+                                        // update the user owner status
+                                        NonRfcChannelUser cuser = (NonRfcChannelUser)GetChannelUser(ircdata.Channel, temp);
+                                        cuser.IsOwner = false;
+#if LOG4NET
+                                        Logger.ChannelSyncing.Debug("unset owner status: " + temp + " for: "+ircdata.Channel);
+#endif
+                                    } else {
+#if LOG4NET
+                                        Logger.ChannelSyncing.Error("_InterpretChannelMode(): GetChannelUser(" + ircdata.Channel + "," + temp + ") returned null! Ignoring...");
+#endif
+                                    }
+                                }
+
+                                if (OnDeowner != null) {
+                                    OnDeowner(this, new DeownerEventArgs(ircdata, ircdata.Channel, ircdata.Nick, temp));
+                                }
+                            }
+                        }
+                    break;
+                    case 'a':
+                        if (SupportNonRfc) {
+                            temp = (string)parametersEnumerator.Current;
+                            parametersEnumerator.MoveNext();
+
+                            if (add) {
+                                if (ActiveChannelSyncing && channel != null) {
+                                    // sanity check
+                                    if (GetChannelUser(ircdata.Channel, temp) != null) {
+                                        // update the channel admin list
+                                        try {
+                                            ((NonRfcChannel)channel).UnsafeChannelAdmins.Add(temp, GetIrcUser(temp));
+#if LOG4NET
+                                            Logger.ChannelSyncing.Debug("added channel admin: "+temp+" to: "+ircdata.Channel);
+#endif
+                                        } catch (ArgumentException) {
+#if LOG4NET
+                                            Logger.ChannelSyncing.Debug("duplicate channel admin: "+temp+" in: "+ircdata.Channel+" not added");
+#endif
+                                        }
+
+                                        // update the user channel admin status
+                                        NonRfcChannelUser cuser = (NonRfcChannelUser)GetChannelUser(ircdata.Channel, temp);
+                                        cuser.IsChannelAdmin = true;
+#if LOG4NET
+                                        Logger.ChannelSyncing.Debug("set channel admin status: " + temp + " for: "+ircdata.Channel);
+#endif
+                                    } else {
+#if LOG4NET
+                                        Logger.ChannelSyncing.Error("_InterpretChannelMode(): GetChannelUser(" + ircdata.Channel + "," + temp + ") returned null! Ignoring...");
+#endif
+                                    }
+                                }
+
+                                if (OnChannelAdmin != null) {
+                                    OnChannelAdmin(this, new ChannelAdminEventArgs(ircdata, ircdata.Channel, ircdata.Nick, temp));
+                                }
+                            }
+                            if (remove) {
+                                if (ActiveChannelSyncing && channel != null) {
+                                    // sanity check
+                                    if (GetChannelUser(ircdata.Channel, temp) != null) {
+                                        // update the channel admin list
+                                        ((NonRfcChannel)channel).UnsafeChannelAdmins.Remove(temp);
+#if LOG4NET
+                                        Logger.ChannelSyncing.Debug("removed channel admin: "+temp+" from: "+ircdata.Channel);
+#endif
+                                        // update the user channel admin status
+                                        NonRfcChannelUser cuser = (NonRfcChannelUser)GetChannelUser(ircdata.Channel, temp);
+                                        cuser.IsChannelAdmin = false;
+#if LOG4NET
+                                        Logger.ChannelSyncing.Debug("unset channel admin status: " + temp + " for: "+ircdata.Channel);
+#endif
+                                    } else {
+#if LOG4NET
+                                        Logger.ChannelSyncing.Error("_InterpretChannelMode(): GetChannelUser(" + ircdata.Channel + "," + temp + ") returned null! Ignoring...");
+#endif
+                                    }
+                                }
+
+                                if (OnDeChannelAdmin != null) {
+                                    OnDeChannelAdmin(this, new DeChannelAdminEventArgs(ircdata, ircdata.Channel, ircdata.Nick, temp));
+                                }
+                            }
+                        }
+                    break;
                     case 'h':
                         if (SupportNonRfc) {
                             temp = (string)parametersEnumerator.Current;
@@ -1806,7 +1944,7 @@ namespace Meebey.SmartIrc4net
                     // ignore
                 } else {
                     ChannelUser channeluser = CreateChannelUser(channelname, ircuser);
-                    channel.UnsafeUsers.Add(who, channeluser);
+                    channel.UnsafeUsers[who] = channeluser;
                 }
             }
 
@@ -2094,6 +2232,16 @@ namespace Meebey.SmartIrc4net
                         // remove first to avoid duplication, Foo -> foo
                         channel.UnsafeUsers.Remove(oldnickname);
                         channel.UnsafeUsers.Add(newnickname, channeluser);
+                        if (SupportNonRfc && ((NonRfcChannelUser)channeluser).IsOwner) {
+                            NonRfcChannel nchannel = (NonRfcChannel)channel;
+                            nchannel.UnsafeOwners.Remove(oldnickname);
+                            nchannel.UnsafeOwners.Add(newnickname, channeluser);
+                        }
+                        if (SupportNonRfc && ((NonRfcChannelUser)channeluser).IsChannelAdmin) {
+                            NonRfcChannel nchannel = (NonRfcChannel)channel;
+                            nchannel.UnsafeChannelAdmins.Remove(oldnickname);
+                            nchannel.UnsafeChannelAdmins.Add(newnickname, channeluser);
+                        }
                         if (channeluser.IsOp) {
                             channel.UnsafeOps.Remove(oldnickname);
                             channel.UnsafeOps.Add(newnickname, channeluser);
@@ -2258,6 +2406,8 @@ namespace Meebey.SmartIrc4net
             if (ActiveChannelSyncing &&
                 IsJoined(channelname)) {
                 string nickname;
+                bool   owner;
+                bool   chanadmin;
                 bool   op;
                 bool   halfop;
                 bool   voice;
@@ -2266,10 +2416,20 @@ namespace Meebey.SmartIrc4net
                         continue;
                     }
 
+                    owner = false;
+                    chanadmin = false;
                     op = false;
                     halfop = false;
                     voice = false;
                     switch (user[0]) {
+                        case '~':
+                            owner = true;
+                            nickname = user.Substring(1);
+                        break;
+                        case '&':
+                            chanadmin = true;
+                            nickname = user.Substring(1);
+                        break;
                         case '@':
                             op = true;
                             nickname = user.Substring(1);
@@ -2278,18 +2438,10 @@ namespace Meebey.SmartIrc4net
                             voice = true;
                             nickname = user.Substring(1);
                         break;
-                        // RFC VIOLATION
-                        // some IRC network do this and break our channel sync...
-                        case '&':
-                            nickname = user.Substring(1);
-                        break;
                         case '%':
                             halfop = true;
                             nickname = user.Substring(1);
                         break;
-                        case '~':
-                            nickname = user.Substring(1);
-                        break;
                         default:
                             nickname = user;
                         break;
@@ -2315,6 +2467,18 @@ namespace Meebey.SmartIrc4net
                         Channel channel = GetChannel(channelname);
                         
                         channel.UnsafeUsers.Add(nickname, channeluser);
+                        if (SupportNonRfc && owner) {
+                            ((NonRfcChannel)channel).UnsafeOwners.Add(nickname, channeluser);
+#if LOG4NET
+                            Logger.ChannelSyncing.Debug("added owner: "+nickname+" to: "+channelname);
+#endif
+                        }
+                        if (SupportNonRfc && chanadmin) {
+                            ((NonRfcChannel)channel).UnsafeChannelAdmins.Add(nickname, channeluser);
+#if LOG4NET
+                            Logger.ChannelSyncing.Debug("added channel admin: "+nickname+" to: "+channelname);
+#endif
+                        }
                         if (op) {
                             channel.UnsafeOps.Add(nickname, channeluser);
 #if LOG4NET
@@ -2338,7 +2502,10 @@ namespace Meebey.SmartIrc4net
                     channeluser.IsOp    = op;
                     channeluser.IsVoice = voice;
                     if (SupportNonRfc) {
-                        ((NonRfcChannelUser)channeluser).IsHalfop = halfop;
+                        var nchanneluser = (NonRfcChannelUser)channeluser;
+                        nchanneluser.IsOwner = owner;
+                        nchanneluser.IsChannelAdmin = chanadmin;
+                        nchanneluser.IsHalfop = halfop;
                     }
                 }
             }
@@ -2368,7 +2535,7 @@ namespace Meebey.SmartIrc4net
 
             if (OnNames != null) {
                 OnNames(this, new NamesEventArgs(ircdata, channelname,
-                                                 filteredUserlist.ToArray()));
+                                                 filteredUserlist.ToArray(), userlist));
             }
         }
         
diff --git a/lib/SmartIrc4net/src/IrcClient/NonRfcChannel.cs b/lib/SmartIrc4net/src/IrcClient/NonRfcChannel.cs
index 1fe91a9..10d94d6 100644
--- a/lib/SmartIrc4net/src/IrcClient/NonRfcChannel.cs
+++ b/lib/SmartIrc4net/src/IrcClient/NonRfcChannel.cs
@@ -37,8 +37,10 @@ namespace Meebey.SmartIrc4net
     /// <threadsafety static="true" instance="true" />
     public class NonRfcChannel : Channel
     {
+        private Hashtable _Owners = Hashtable.Synchronized(new Hashtable(new CaseInsensitiveHashCodeProvider(), new CaseInsensitiveComparer()));
+        private Hashtable _ChannelAdmins = Hashtable.Synchronized(new Hashtable(new CaseInsensitiveHashCodeProvider(), new CaseInsensitiveComparer()));
         private Hashtable _Halfops = Hashtable.Synchronized(new Hashtable(new CaseInsensitiveHashCodeProvider(), new CaseInsensitiveComparer()));
-        
+
         /// <summary>
         /// 
         /// </summary>
@@ -58,6 +60,46 @@ namespace Meebey.SmartIrc4net
         /// 
         /// </summary>
         /// <value> </value>
+        public Hashtable Owners {
+            get {
+                return (Hashtable) _Owners.Clone();
+            }
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <value> </value>
+        internal Hashtable UnsafeOwners {
+            get {
+                return _Owners;
+            }
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <value> </value>
+        public Hashtable ChannelAdmins {
+            get {
+                return (Hashtable) _ChannelAdmins.Clone();
+            }
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <value> </value>
+        internal Hashtable UnsafeChannelAdmins {
+            get {
+                return _ChannelAdmins;
+            }
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <value> </value>
         public Hashtable Halfops {
             get {
                 return (Hashtable) _Halfops.Clone();
diff --git a/lib/SmartIrc4net/src/IrcClient/NonRfcChannelUser.cs b/lib/SmartIrc4net/src/IrcClient/NonRfcChannelUser.cs
index e34500a..3fef0ec 100644
--- a/lib/SmartIrc4net/src/IrcClient/NonRfcChannelUser.cs
+++ b/lib/SmartIrc4net/src/IrcClient/NonRfcChannelUser.cs
@@ -34,9 +34,9 @@ namespace Meebey.SmartIrc4net
     /// <threadsafety static="true" instance="true" />
     public class NonRfcChannelUser : ChannelUser
     {
-        private bool _IsHalfop;
-        private bool _IsOwner;
-        private bool _IsAdmin;
+        public bool IsOwner { get; set; }
+        public bool IsChannelAdmin { get; set; }
+        public bool IsHalfop { get; set; }
         
         /// <summary>
         /// 
@@ -53,18 +53,5 @@ namespace Meebey.SmartIrc4net
             Logger.ChannelSyncing.Debug("NonRfcChannelUser ("+Channel+":"+IrcUser.Nick+") destroyed");
         }
 #endif
-
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <value> </value>
-        public bool IsHalfop {
-            get {
-                return _IsHalfop;
-            }
-            set {
-                _IsHalfop = value;
-            }
-        }
     }
 }
diff --git a/lib/SmartIrc4net/src/IrcClient/WhoInfo.cs b/lib/SmartIrc4net/src/IrcClient/WhoInfo.cs
index dee028d..335055b 100644
--- a/lib/SmartIrc4net/src/IrcClient/WhoInfo.cs
+++ b/lib/SmartIrc4net/src/IrcClient/WhoInfo.cs
@@ -41,7 +41,10 @@ namespace Meebey.SmartIrc4net
         private int      f_HopCount;
         private string   f_Realname;
         private bool     f_IsAway;
+        private bool     f_IsOwner;
+        private bool     f_IsChannelAdmin;
         private bool     f_IsOp;
+        private bool     f_IsHalfop;
         private bool     f_IsVoice;
         private bool     f_IsIrcOp;
         private bool     f_IsRegistered;
@@ -94,12 +97,30 @@ namespace Meebey.SmartIrc4net
             }
         }
 
+        public bool IsOwner {
+            get {
+                return f_IsOwner;
+            }
+        }
+
+        public bool IsChannelAdmin {
+            get {
+                return f_IsChannelAdmin;
+            }
+        }
+
         public bool IsOp {
             get {
                 return f_IsOp;
             }
         }
 
+        public bool IsHalfop {
+            get {
+                return f_IsHalfop;
+            }
+        }
+
         public bool IsVoice {
             get {
                 return f_IsVoice;
@@ -151,7 +172,10 @@ namespace Meebey.SmartIrc4net
             }
 
             string usermode = data.RawMessageArray[8];
+            bool owner = false;
+            bool chanadmin = false;
             bool op = false;
+            bool halfop = false;
             bool voice = false;
             bool ircop = false;
             bool away = false;
@@ -165,9 +189,18 @@ namespace Meebey.SmartIrc4net
                     case 'G':
                         away = true;
                     break;
+                    case '~':
+                        owner = true;
+                    break;
+                    case '&':
+                        chanadmin = true;
+                    break;
                     case '@':
                         op = true;
                     break;
+                    case '%':
+                        halfop = true;
+                    break;
                     case '+':
                         voice = true;
                     break;
@@ -180,7 +213,10 @@ namespace Meebey.SmartIrc4net
                 }
             }
             whoInfo.f_IsAway = away;
+            whoInfo.f_IsOwner = owner;
+            whoInfo.f_IsChannelAdmin = chanadmin;
             whoInfo.f_IsOp = op;
+            whoInfo.f_IsHalfop = halfop;
             whoInfo.f_IsVoice = voice;
             whoInfo.f_IsIrcOp = ircop;
 
diff --git a/lib/SmartIrc4net/src/IrcCommands/IrcCommands.cs b/lib/SmartIrc4net/src/IrcCommands/IrcCommands.cs
index bbe6625..3de1a90 100644
--- a/lib/SmartIrc4net/src/IrcCommands/IrcCommands.cs
+++ b/lib/SmartIrc4net/src/IrcCommands/IrcCommands.cs
@@ -134,155 +134,107 @@ namespace Meebey.SmartIrc4net
             SendReply(data, message, Priority.Medium);
         }
         
+
         /// <summary>
-        /// 
+        /// Give or take a user's privilege in a channel.
         /// </summary>
-        /// <param name="channel"></param>
-        /// <param name="nickname"></param>
-        /// <param name="priority"></param>
-        public void Op(string channel, string nickname, Priority priority)
+        /// <param name="modechg">The mode change (e.g. +o) to perform on the user.</param>
+        /// <param name="channel">The channel in which to perform the privilege change.</param>
+        /// <param name="nickname">The nickname of the user whose privilege is being changed.</param>
+        /// <param name="priority">The priority with which the mode-setting message should be sent.</param>
+        public void ChangeChannelPrivilege(string modechg, string channel, string nickname, Priority priority)
         {
-            WriteLine(Rfc2812.Mode(channel, "+o "+nickname), priority);
+            WriteLine(Rfc2812.Mode(channel, modechg + " " + nickname), priority);
         }
 
         /// <summary>
-        ///
+        /// Give or take a user's privilege in a channel.
         /// </summary>
-        /// <param name="channel"></param>
-        /// <param name="nickname"></param>
-        public void Op(string channel, string[] nicknames)
+        /// <param name="modechg">The mode change (e.g. +o) to perform on the user.</param>
+        /// <param name="channel">The channel in which to perform the privilege change.</param>
+        /// <param name="nickname">The nickname of the user whose privilege is being changed.</param>
+        public void ChangeChannelPrivilege(string modechg, string channel, string nickname)
+        {
+            WriteLine(Rfc2812.Mode(channel, modechg + " " + nickname));
+        }
+
+        /// <summary>
+        /// Give or take a privilege to/from multiple users in a channel.
+        /// </summary>
+        /// <param name="modechg">The mode change (e.g. +o) to perform on the users.</param>
+        /// <param name="channel">The channel in which to give the users a privilege.</param>
+        /// <param name="nickname">The nicknames of the users receiving the privilege.</param>
+        public void ChangeChannelPrivilege(string modechg, string channel, string[] nicknames)
         {
             if (nicknames == null) {
                 throw new ArgumentNullException("nicknames");
             }
-            
+
             string[] modes = new string[nicknames.Length];
             for (int i = 0; i < nicknames.Length; i++) {
-                modes[i] = "+o";
+                modes[i] = modechg;
             }
             Mode(channel, modes, nicknames);
         }
 
-        public void Op(string channel, string nickname)
+        public void Op(string channel, string nickname, Priority priority)
         {
-            WriteLine(Rfc2812.Mode(channel, "+o "+nickname));
+            ChangeChannelPrivilege("+o", channel, nickname, priority);
         }
-        
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="channel"></param>
-        /// <param name="nickname"></param>
-        /// <param name="priority"></param>
-        public void Deop(string channel, string nickname, Priority priority)
+
+        public void Op(string channel, string[] nicknames)
         {
-            WriteLine(Rfc2812.Mode(channel, "-o "+nickname), priority);
+            ChangeChannelPrivilege("+o", channel, nicknames);
         }
 
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="channel"></param>
-        /// <param name="nickname"></param>
-        public void Deop(string channel, string nickname)
+        public void Op(string channel, string nickname)
         {
-            WriteLine(Rfc2812.Mode(channel, "-o "+nickname));
+            ChangeChannelPrivilege("+o", channel, nickname);
         }
 
-        /// <summary>
-        ///
-        /// </summary>
-        /// <param name="channel"></param>
-        /// <param name="nickname"></param>
-        public void Deop(string channel, string[] nicknames)
+        public void Deop(string channel, string nickname, Priority priority)
         {
-            if (nicknames == null) {
-                throw new ArgumentNullException("nicknames");
-            }
+            ChangeChannelPrivilege("-o", channel, nickname, priority);
+        }
 
-            string[] modes = new string[nicknames.Length];
-            for (int i = 0; i < nicknames.Length; i++) {
-                modes[i] = "-o";
-            }
-            Mode(channel, modes, nicknames);
+        public void Deop(string channel, string[] nicknames)
+        {
+            ChangeChannelPrivilege("-o", channel, nicknames);
         }
 
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="channel"></param>
-        /// <param name="nickname"></param>
-        /// <param name="priority"></param>
-        public void Voice(string channel, string nickname, Priority priority)
+        public void Deop(string channel, string nickname)
         {
-            WriteLine(Rfc2812.Mode(channel, "+v "+nickname), priority);
+            ChangeChannelPrivilege("-o", channel, nickname);
         }
 
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="channel"></param>
-        /// <param name="nickname"></param>
-        public void Voice(string channel, string nickname)
+        public void Voice(string channel, string nickname, Priority priority)
         {
-            WriteLine(Rfc2812.Mode(channel, "+v "+nickname));
+            ChangeChannelPrivilege("+v", channel, nickname, priority);
         }
 
-        /// <summary>
-        ///
-        /// </summary>
-        /// <param name="channel"></param>
-        /// <param name="nickname"></param>
         public void Voice(string channel, string[] nicknames)
         {
-            if (nicknames == null) {
-                throw new ArgumentNullException("nicknames");
-            }
-
-            string[] modes = new string[nicknames.Length];
-            for (int i = 0; i < nicknames.Length; i++) {
-                modes[i] = "+v";
-            }
-            Mode(channel, modes, nicknames);
+            ChangeChannelPrivilege("+v", channel, nicknames);
         }
 
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="channel"></param>
-        /// <param name="nickname"></param>
-        /// <param name="priority"></param>
-        public void Devoice(string channel, string nickname, Priority priority)
+        public void Voice(string channel, string nickname)
         {
-            WriteLine(Rfc2812.Mode(channel, "-v "+nickname), priority);
+            ChangeChannelPrivilege("+v", channel, nickname);
         }
 
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="channel"></param>
-        /// <param name="nickname"></param>
-        public void Devoice(string channel, string nickname)
+        public void Devoice(string channel, string nickname, Priority priority)
         {
-            WriteLine(Rfc2812.Mode(channel, "-v "+nickname));
+            ChangeChannelPrivilege("-v", channel, nickname, priority);
         }
 
-        /// <summary>
-        ///
-        /// </summary>
-        /// <param name="channel"></param>
-        /// <param name="nicknames"></param>
         public void Devoice(string channel, string[] nicknames)
         {
-            if (nicknames == null) {
-                throw new ArgumentNullException("nicknames");
-            }
+            ChangeChannelPrivilege("-v", channel, nicknames);
+        }
 
-            string[] modes = new string[nicknames.Length];
-            for (int i = 0; i < nicknames.Length; i++) {
-                modes[i] = "-v";
-            }
-            Mode(channel, modes, nicknames);
+        public void Devoice(string channel, string nickname)
+        {
+            ChangeChannelPrivilege("-v", channel, nickname);
         }
 
         /// <summary>
@@ -383,61 +335,95 @@ namespace Meebey.SmartIrc4net
         }
 
         // non-RFC commands
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="channel"></param>
-        /// <param name="nickname"></param>
-        /// <param name="priority"></param>
-        public void Halfop(string channel, string nickname)
+
+        public void Owner(string channel, string nickname, Priority priority)
         {
-            WriteLine(Rfc2812.Mode(channel, "+h "+nickname));
+            ChangeChannelPrivilege("+q", channel, nickname, priority);
+        }
+
+        public void Owner(string channel, string[] nicknames)
+        {
+            ChangeChannelPrivilege("+q", channel, nicknames);
+        }
+
+        public void Owner(string channel, string nickname)
+        {
+            ChangeChannelPrivilege("+q", channel, nickname);
+        }
+
+        public void Deowner(string channel, string nickname, Priority priority)
+        {
+            ChangeChannelPrivilege("-q", channel, nickname, priority);
+        }
+
+        public void Deowner(string channel, string[] nicknames)
+        {
+            ChangeChannelPrivilege("-q", channel, nicknames);
+        }
+
+        public void Deowner(string channel, string nickname)
+        {
+            ChangeChannelPrivilege("-q", channel, nickname);
+        }
+
+        public void ChanAdmin(string channel, string nickname, Priority priority)
+        {
+            ChangeChannelPrivilege("+a", channel, nickname, priority);
+        }
+
+        public void ChanAdmin(string channel, string[] nicknames)
+        {
+            ChangeChannelPrivilege("+a", channel, nicknames);
+        }
+
+        public void ChanAdmin(string channel, string nickname)
+        {
+            ChangeChannelPrivilege("+a", channel, nickname);
+        }
+
+        public void DeChanAdmin(string channel, string nickname, Priority priority)
+        {
+            ChangeChannelPrivilege("-a", channel, nickname, priority);
+        }
+
+        public void DeChanAdmin(string channel, string[] nicknames)
+        {
+            ChangeChannelPrivilege("-a", channel, nicknames);
+        }
+
+        public void DeChanAdmin(string channel, string nickname)
+        {
+            ChangeChannelPrivilege("-a", channel, nickname);
+        }
+
+        public void Halfop(string channel, string nickname, Priority priority)
+        {
+            ChangeChannelPrivilege("+h", channel, nickname, priority);
         }
 
-        /// <summary>
-        ///
-        /// </summary>
-        /// <param name="channel"></param>
-        /// <param name="nicknames"></param>
         public void Halfop(string channel, string[] nicknames)
         {
-            if (nicknames == null) {
-                throw new ArgumentNullException("nicknames");
-            }
+            ChangeChannelPrivilege("+h", channel, nicknames);
+        }
 
-            string[] modes = new string[nicknames.Length];
-            for (int i = 0; i < nicknames.Length; i++) {
-                modes[i] = "+h";
-            }
-            Mode(channel, modes, nicknames);
+        public void Halfop(string channel, string nickname)
+        {
+            ChangeChannelPrivilege("+h", channel, nickname);
         }
 
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="channel"></param>
-        /// <param name="nickname"></param>
-        public void Dehalfop(string channel, string nickname)
+        public void Dehalfop(string channel, string nickname, Priority priority)
         {
-            WriteLine(Rfc2812.Mode(channel, "-h "+nickname));
+            ChangeChannelPrivilege("-h", channel, nickname, priority);
         }
 
-        /// <summary>
-        ///
-        /// </summary>
-        /// <param name="channel"></param>
-        /// <param name="nicknames"></param>
         public void Dehalfop(string channel, string[] nicknames)
         {
-            if (nicknames == null) {
-                throw new ArgumentNullException("nicknames");
-            }
+            ChangeChannelPrivilege("-h", channel, nicknames);
+        }
 
-            string[] modes = new string[nicknames.Length];
-            for (int i = 0; i < nicknames.Length; i++) {
-                modes[i] = "-h";
-            }
-            Mode(channel, modes, nicknames);
+        public void Dehalfop(string channel, string nickname)
+        {
+            ChangeChannelPrivilege("-h", channel, nickname);
         }
 
         /// <summary>
diff --git a/lib/SmartIrc4net/src/IrcConnection/IrcConnection.cs b/lib/SmartIrc4net/src/IrcConnection/IrcConnection.cs
index 3a1479f..28def5f 100644
--- a/lib/SmartIrc4net/src/IrcConnection/IrcConnection.cs
+++ b/lib/SmartIrc4net/src/IrcConnection/IrcConnection.cs
@@ -134,6 +134,10 @@ namespace Meebey.SmartIrc4net
                 lock (this) {
                     _IsConnectionError = value;
                 }
+                if (value) {
+                    // signal ReadLine() to check IsConnectionError state
+                    _ReadThread.QueuedEvent.Set();
+                }
             }
         }
 
@@ -766,7 +770,6 @@ namespace Meebey.SmartIrc4net
             Logger.Connection.Info("reconnecting...");
 #endif
             Disconnect();
-            Thread.Sleep(AutoRetryDelay * 1000);
             Connect(_AddressList, _Port);
         }
         
@@ -863,7 +866,7 @@ namespace Meebey.SmartIrc4net
                 while (IsConnected &&
                        !IsConnectionError &&
                        _ReadThread.Queue.Count == 0) {
-                    Thread.Sleep(10);
+                    _ReadThread.QueuedEvent.WaitOne();
                 }
             }
 
@@ -905,6 +908,7 @@ namespace Meebey.SmartIrc4net
                 _WriteLine(data);
             } else {
                 ((Queue)_SendBuffer[priority]).Enqueue(data);
+                _WriteThread.QueuedEvent.Set();
             }
         }
 
@@ -1016,6 +1020,8 @@ namespace Meebey.SmartIrc4net
         {
             try {
                 if (AutoReconnect) {
+                    // prevent connect -> exception -> connect flood loop
+                    Thread.Sleep(AutoRetryDelay * 1000);
                     // lets try to recover the connection
                     Reconnect();
                 } else {
@@ -1038,6 +1044,8 @@ namespace Meebey.SmartIrc4net
             private Thread         _Thread;
             private Queue          _Queue = Queue.Synchronized(new Queue());
 
+            public AutoResetEvent  QueuedEvent;
+
             public Queue Queue {
                 get {
                     return _Queue;
@@ -1051,6 +1059,7 @@ namespace Meebey.SmartIrc4net
             public ReadThread(IrcConnection connection)
             {
                 _Connection = connection;
+                QueuedEvent = new AutoResetEvent(false);
             }
 
             /// <summary>
@@ -1104,6 +1113,7 @@ namespace Meebey.SmartIrc4net
                         while (_Connection.IsConnected &&
                                ((data = _Connection._Reader.ReadLine()) != null)) {
                             _Queue.Enqueue(data);
+                            QueuedEvent.Set();
 #if LOG4NET
                             Logger.Socket.Debug("received: \""+data+"\"");
 #endif
@@ -1155,6 +1165,8 @@ namespace Meebey.SmartIrc4net
             private int            _BelowMediumThresholdCount = 1;
             private int            _BurstCount;
 
+            public AutoResetEvent QueuedEvent;
+
             /// <summary>
             /// 
             /// </summary>
@@ -1162,6 +1174,7 @@ namespace Meebey.SmartIrc4net
             public WriteThread(IrcConnection connection)
             {
                 _Connection = connection;
+                QueuedEvent = new AutoResetEvent(false);
             }
 
             /// <summary>
@@ -1203,8 +1216,12 @@ namespace Meebey.SmartIrc4net
                 try {
                     try {
                         while (_Connection.IsConnected) {
-                            _CheckBuffer();
-                            Thread.Sleep(_Connection._SendDelay);
+                            QueuedEvent.WaitOne();
+                            var isBufferEmpty = false;
+                            do {
+                                isBufferEmpty = _CheckBuffer() == 0;
+                                Thread.Sleep(_Connection._SendDelay);
+                            } while (!isBufferEmpty);
                         }
                     } catch (IOException e) {
 #if LOG4NET
@@ -1234,19 +1251,25 @@ namespace Meebey.SmartIrc4net
 
 #region WARNING: complex scheduler, don't even think about changing it!
             // WARNING: complex scheduler, don't even think about changing it!
-            private void _CheckBuffer()
+            private int _CheckBuffer()
             {
-                // only send data if we are succefully registered on the IRC network
-                if (!_Connection._IsRegistered) {
-                    return;
-                }
-
                 _HighCount        = ((Queue)_Connection._SendBuffer[Priority.High]).Count;
                 _AboveMediumCount = ((Queue)_Connection._SendBuffer[Priority.AboveMedium]).Count;
                 _MediumCount      = ((Queue)_Connection._SendBuffer[Priority.Medium]).Count;
                 _BelowMediumCount = ((Queue)_Connection._SendBuffer[Priority.BelowMedium]).Count;
                 _LowCount         = ((Queue)_Connection._SendBuffer[Priority.Low]).Count;
 
+                var msgCount = _HighCount +
+                               _AboveMediumCount +
+                               _MediumCount +
+                               _BelowMediumCount +
+                               _LowCount;
+
+                // only send data if we are succefully registered on the IRC network
+                if (!_Connection._IsRegistered) {
+                    return msgCount;
+                }
+
                 if (_CheckHighBuffer() &&
                     _CheckAboveMediumBuffer() &&
                     _CheckMediumBuffer() &&
@@ -1263,6 +1286,8 @@ namespace Meebey.SmartIrc4net
                     _BurstCount++;
                     //_CheckBuffer();
                 }
+
+                return msgCount;
             }
 
             private bool _CheckHighBuffer()
@@ -1274,6 +1299,7 @@ namespace Meebey.SmartIrc4net
                         Logger.Queue.Warn("Sending data was not sucessful, data is requeued!");
 #endif
                         ((Queue)_Connection._SendBuffer[Priority.High]).Enqueue(data);
+                        return false;
                     }
 
                     if (_HighCount > 1) {
@@ -1295,6 +1321,7 @@ namespace Meebey.SmartIrc4net
                         Logger.Queue.Warn("Sending data was not sucessful, data is requeued!");
 #endif
                         ((Queue)_Connection._SendBuffer[Priority.AboveMedium]).Enqueue(data);
+                        return false;
                     }
                     _AboveMediumSentCount++;
 
@@ -1316,6 +1343,7 @@ namespace Meebey.SmartIrc4net
                         Logger.Queue.Warn("Sending data was not sucessful, data is requeued!");
 #endif
                         ((Queue)_Connection._SendBuffer[Priority.Medium]).Enqueue(data);
+                        return false;
                     }
                     _MediumSentCount++;
 
@@ -1337,6 +1365,7 @@ namespace Meebey.SmartIrc4net
                         Logger.Queue.Warn("Sending data was not sucessful, data is requeued!");
 #endif
                         ((Queue)_Connection._SendBuffer[Priority.BelowMedium]).Enqueue(data);
+                        return false;
                     }
                     _BelowMediumSentCount++;
 
@@ -1364,6 +1393,7 @@ namespace Meebey.SmartIrc4net
                         Logger.Queue.Warn("Sending data was not sucessful, data is requeued!");
 #endif
                         ((Queue)_Connection._SendBuffer[Priority.Low]).Enqueue(data);
+                        return false;
                     }
 
                     if (_LowCount > 1) {
diff --git a/lib/Twitterizer/CommonAssemblyInfo.cs b/lib/Twitterizer/CommonAssemblyInfo.cs
index ee09c66..c701b96 100644
--- a/lib/Twitterizer/CommonAssemblyInfo.cs
+++ b/lib/Twitterizer/CommonAssemblyInfo.cs
@@ -51,8 +51,9 @@ using System.Security;
 [assembly: AssemblyCopyright("2010 Patrick 'Ricky' Smith (www.ricky-dev.com)")]
 [assembly: AssemblyTrademark("")]
 
-[assembly: AssemblyVersion("2.4.0.*")]
-[assembly: AssemblyFileVersion("2.4.0.0")]
+[assembly: AssemblyVersion("2.4.1.*")]
+[assembly: AssemblyFileVersion("2.4.1.0")]
+[assembly: AssemblyInformationalVersion("2.4.1")]
 
 #if !SILVERLIGHT
 [assembly: AllowPartiallyTrustedCallers]
diff --git a/lib/Twitterizer/Twitterizer2/Attributes/AuthorizedCommandAttribute.cs b/lib/Twitterizer/Twitterizer2/Attributes/AuthorizedCommandAttribute.cs
index b354d4e..3dc2921 100644
--- a/lib/Twitterizer/Twitterizer2/Attributes/AuthorizedCommandAttribute.cs
+++ b/lib/Twitterizer/Twitterizer2/Attributes/AuthorizedCommandAttribute.cs
@@ -34,17 +34,13 @@
 
 namespace Twitterizer.Core
 {
+    using System;
+
     /// <summary>
     /// Indicates that a command class requires authorization tokens.
     /// </summary>
-    [global::System.AttributeUsage(System.AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
+    [AttributeUsage(System.AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
     internal sealed class AuthorizedCommandAttribute : System.Attribute
     {
-        /// <summary>
-        /// Initializes a new instance of the <see cref="AuthorizedCommandAttribute"/> class.
-        /// </summary>
-        public AuthorizedCommandAttribute()
-        {
-        }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Attributes/RateLimitedAttribute.cs b/lib/Twitterizer/Twitterizer2/Attributes/RateLimitedAttribute.cs
index 7df5344..c6e8d92 100644
--- a/lib/Twitterizer/Twitterizer2/Attributes/RateLimitedAttribute.cs
+++ b/lib/Twitterizer/Twitterizer2/Attributes/RateLimitedAttribute.cs
@@ -38,14 +38,8 @@ namespace Twitterizer
     /// <summary>
     /// Identifies command classes that must enforce rate limiting. This will cause rate status to be queried before each command call.
     /// </summary>
-    [global::System.AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
+    [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
     internal sealed class RateLimitedAttribute : Attribute
     {
-        /// <summary>
-        /// Initializes a new instance of the <see cref="RateLimitedAttribute"/> class.
-        /// </summary>
-        public RateLimitedAttribute()
-        {
-        }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Core/OptionalProperties.cs b/lib/Twitterizer/Twitterizer2/Core/OptionalProperties.cs
index 3cce16d..52c153a 100644
--- a/lib/Twitterizer/Twitterizer2/Core/OptionalProperties.cs
+++ b/lib/Twitterizer/Twitterizer2/Core/OptionalProperties.cs
@@ -52,12 +52,6 @@ namespace Twitterizer
             // Set the default values for the properties
             this.UseSSL = false;
             this.APIBaseAddress = "http://api.twitter.com/1/";
-
-#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"]/*'/>
@@ -73,46 +67,5 @@ namespace Twitterizer
         /// <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; }
-
-		/// <summary>
-        /// Reads the configuration settings.
-        /// </summary>
-        private void ReadConfigurationSettings()
-        {
-
-            System.Collections.Specialized.NameValueCollection appSettings = ConfigurationManager.AppSettings;
-
-            // Get the enable caching configuration setting
-            if (!string.IsNullOrEmpty(appSettings["Twitterizer2.EnableCaching"]) &&
-                appSettings["Twitterizer2.EnableCaching"].ToLower().Trim() == "true")
-            {
-                this.CacheOutput = true;
-            }
-
-            // Get the cache timeout setting
-            string cacheTimeoutSetting = appSettings["Twitterizer2.CacheTimeout"];
-            long cacheTimeoutSeconds;
-            if (!string.IsNullOrEmpty(appSettings["Twitterizer2.CacheTimeout"]) &&
-                long.TryParse(cacheTimeoutSetting, out cacheTimeoutSeconds))
-            {
-                // Convert the seconds value to ticks and instantiate a new timespan
-                this.CacheTimespan = new TimeSpan(cacheTimeoutSeconds * 10000000);
-            }
-
-            // Get the SSL setting
-            if (!string.IsNullOrEmpty(appSettings["Twitterizer2.EnableSSL"]) &&
-                appSettings["Twitterizer2.EnableSSL"].ToLower().Trim() == "true")
-            {
-                this.UseSSL = true;
-            }
-        }
-#endif
-        }
+    }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Core/SerializationHelper.cs b/lib/Twitterizer/Twitterizer2/Core/SerializationHelper.cs
index 387d913..9afd843 100644
--- a/lib/Twitterizer/Twitterizer2/Core/SerializationHelper.cs
+++ b/lib/Twitterizer/Twitterizer2/Core/SerializationHelper.cs
@@ -42,14 +42,14 @@ namespace Twitterizer.Core
     /// The Serialization Helper class. Provides a simple interface for common serialization tasks.
     /// </summary>
     /// <typeparam name="T">The type of object to be deserialized</typeparam>
-    internal static class SerializationHelper<T>
+    public static class SerializationHelper<T>
         where T : ITwitterObject
     {
         /// <summary>
         /// The JavascriptConversionDelegate. The delegate is invokes when using the JavaScriptSerializer to manually construct a result object.
         /// </summary>
         /// <param name="value">Contains nested dictionary objects containing deserialized values for manual parsing.</param>
-        /// <returns>A strongly typed object representing the deserialized data of type <typeparamref name="T" />
+        /// <returns>A strongly typed object representing the deserialized data of type T.
         /// </returns>
         public delegate T DeserializationHandler(JObject value);
 
@@ -63,16 +63,41 @@ namespace Twitterizer.Core
         /// </returns>
         public static T Deserialize(byte[] webResponseData, DeserializationHandler deserializationHandler)
         {
+            return Deserialize(Encoding.UTF8.GetString(webResponseData, 0, webResponseData.Length), deserializationHandler);
+        }
+
+        /// <summary>
+        /// Deserializes the specified web response.
+        /// </summary>
+        /// <param name="webResponseData">The web response data.</param>
+        /// <returns>
+        /// A strongly typed object representing the deserialized data of type <typeparamref name="T"/>
+        /// </returns>
+        public static T Deserialize(byte[] webResponseData)
+        {
+            return Deserialize(Encoding.UTF8.GetString(webResponseData, 0, webResponseData.Length), null);
+        }
+
+        /// <summary>
+        /// Deserializes the specified web response.
+        /// </summary>
+        /// <param name="webResponseData">The web response data.</param>
+        /// <param name="deserializationHandler">The deserialization handler.</param>
+        /// <returns>
+        /// A strongly typed object representing the deserialized data of type <typeparamref name="T"/>
+        /// </returns>
+        public static T Deserialize(string webResponseData, DeserializationHandler deserializationHandler)
+        {
             T resultObject;
 
             // Deserialize the results.
             if (deserializationHandler == null)
             {
-                resultObject = JsonConvert.DeserializeObject<T>(Encoding.UTF8.GetString(webResponseData, 0, webResponseData.Length));
+                resultObject = JsonConvert.DeserializeObject<T>(webResponseData);
             }
             else
             {
-                resultObject = deserializationHandler((JObject)JsonConvert.DeserializeObject(Encoding.UTF8.GetString(webResponseData, 0, webResponseData.Length)));
+                resultObject = deserializationHandler((JObject)JsonConvert.DeserializeObject(webResponseData));
             }
 
             return resultObject;
@@ -85,7 +110,7 @@ namespace Twitterizer.Core
         /// <returns>
         /// A strongly typed object representing the deserialized data of type <typeparamref name="T"/>
         /// </returns>
-        public static T Deserialize(byte[] webResponseData)
+        public static T Deserialize(string webResponseData)
         {
             return Deserialize(webResponseData, null);
         }
diff --git a/lib/Twitterizer/Twitterizer2/Core/TwitterCommand.cs b/lib/Twitterizer/Twitterizer2/Core/TwitterCommand.cs
index 33f5e30..fd4bebf 100644
--- a/lib/Twitterizer/Twitterizer2/Core/TwitterCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Core/TwitterCommand.cs
@@ -42,9 +42,6 @@ namespace Twitterizer.Core
 #if !SILVERLIGHT
     using System.Web;
 #endif
-#if !LITE && !SILVERLIGHT
-    using System.Web.Caching;
-#endif
     using Twitterizer;
 
     /// <summary>
@@ -66,7 +63,7 @@ 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, object>();
+            this.RequestParameters = new Dictionary<string, object>();
             this.Verb = method;
             this.Tokens = tokens;
             this.OptionalProperties = optionalProperties ?? new OptionalProperties();
@@ -78,19 +75,19 @@ namespace Twitterizer.Core
         /// Gets or sets the optional properties.
         /// </summary>
         /// <value>The optional properties.</value>
-        public OptionalProperties OptionalProperties { get; set; }
+        protected OptionalProperties OptionalProperties { get; set; }
 
         /// <summary>
         /// Gets or sets the API method URI.
         /// </summary>
         /// <value>The URI for the API method.</value>
-        public Uri Uri { get; set; }
+        private Uri Uri { get; set; }
 
         /// <summary>
         /// Gets or sets the method.
         /// </summary>
         /// <value>The method.</value>
-        public HTTPVerb Verb { get; set; }
+        private HTTPVerb Verb { get; set; }
 
         /// <summary>
         /// Gets or sets the request parameters.
@@ -102,7 +99,7 @@ namespace Twitterizer.Core
         /// Gets or sets the serialization delegate.
         /// </summary>
         /// <value>The serialization delegate.</value>
-        public SerializationHelper<T>.DeserializationHandler DeserializationHandler { get; set; }
+        protected SerializationHelper<T>.DeserializationHandler DeserializationHandler { get; set; }
 
         /// <summary>
         /// Gets the request tokens.
@@ -119,7 +116,7 @@ namespace Twitterizer.Core
         /// 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; }
+        protected bool Multipart { get; set; }
 
         /// <summary>
         /// Executes the command.
@@ -137,7 +134,7 @@ namespace Twitterizer.Core
             // Loop through all of the custom attributes assigned to the command class
             foreach (Attribute attribute in this.GetType().GetCustomAttributes(false))
             {
-                if (attribute.GetType() == typeof(AuthorizedCommandAttribute))
+                if (attribute is AuthorizedCommandAttribute)
                 {
                     if (this.Tokens == null)
                     {
@@ -152,7 +149,7 @@ namespace Twitterizer.Core
                         throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, "Token values cannot be null when executing the \"{0}\" command.", this.GetType()));
                     }
                 }
-                else if (attribute.GetType() == typeof(RateLimitedAttribute))
+                else if (attribute is RateLimitedAttribute)
                 {
                     // Get the rate limiting status
                     if (TwitterRateLimitStatus.GetStatus(this.Tokens).ResponseObject.RemainingHits == 0)
@@ -163,42 +160,13 @@ namespace Twitterizer.Core
 
             }
 
-#if !LITE && !SILVERLIGHT
-            // Variables and objects needed for caching
-            StringBuilder cacheKeyBuilder = new StringBuilder(this.Uri.AbsoluteUri);
-            if (this.Tokens != null)
-            {
-                cacheKeyBuilder.AppendFormat("|{0}|{1}", this.Tokens.ConsumerKey, this.Tokens.ConsumerKey);
-            }
-
-            Cache cache = HttpRuntime.Cache;
-#endif
-
             // Prepare the query parameters
-			Dictionary<string, object> queryParameters = new Dictionary<string, object>();
-			foreach (KeyValuePair<string, object> 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)
-                {
-                    return new TwitterResponse<T>()
-                               {
-                                   ResponseObject = (T)cache[cacheKeyBuilder.ToString()],
-                                   ResponseCached = true
-                               };
-                }
-            }
-            
-#endif
             // Declare the variable to be returned
             twitterResponse.ResponseObject = default(T);
             twitterResponse.RequestUrl = this.Uri.AbsoluteUri;
@@ -208,7 +176,7 @@ namespace Twitterizer.Core
 
             try
             {
-				WebRequestBuilder requestBuilder = new WebRequestBuilder(this.Uri, this.Verb, this.Tokens, "") { Multipart = this.Multipart };
+				WebRequestBuilder requestBuilder = new WebRequestBuilder(this.Uri, this.Verb, this.Tokens) { Multipart = this.Multipart };
 
 #if !SILVERLIGHT
                 if (this.OptionalProperties != null)
@@ -222,16 +190,28 @@ namespace Twitterizer.Core
 
                 HttpWebResponse response = requestBuilder.ExecuteRequest();
 
+                if (response == null)
+                {
+                    twitterResponse.Result = RequestResult.Unknown;
+                    return twitterResponse;
+                }
+
                 responseData = ConversionUtility.ReadStream(response.GetResponseStream());
                 twitterResponse.Content = Encoding.UTF8.GetString(responseData, 0, responseData.Length);
 
                 twitterResponse.RequestUrl = requestBuilder.RequestUri.AbsoluteUri;
 
+#if !SILVERLIGHT
                 // Parse the rate limiting HTTP Headers
                 rateLimiting = ParseRateLimitHeaders(response.Headers);
 
                 // Parse Access Level
                 accessLevel = ParseAccessLevel(response.Headers);
+#else
+                rateLimiting = null;
+                accessLevel = AccessLevel.Unknown;
+
+#endif
 
                 // Lookup the status code and set the status accordingly
                 SetStatusCode(twitterResponse, response.StatusCode, rateLimiting);
@@ -266,15 +246,21 @@ namespace Twitterizer.Core
                 responseData = ConversionUtility.ReadStream(exceptionResponse.GetResponseStream());
                 twitterResponse.Content = Encoding.UTF8.GetString(responseData, 0, responseData.Length);
 
+#if !SILVERLIGHT
                 rateLimiting = ParseRateLimitHeaders(exceptionResponse.Headers);
 
                 // Parse Access Level
                 accessLevel = ParseAccessLevel(exceptionResponse.Headers);
+#else
+                rateLimiting = null;
+                accessLevel = AccessLevel.Unknown;
+#endif
 
                 // Try to read the error message, if there is one.
                 try
                 {
-                    twitterResponse.ErrorMessage = SerializationHelper<TwitterErrorDetails>.Deserialize(responseData).ErrorMessage;
+                    TwitterErrorDetails errorDetails = SerializationHelper<TwitterErrorDetails>.Deserialize(responseData);
+                    twitterResponse.ErrorMessage = errorDetails.ErrorMessage;
                 }
                 catch (Exception)
                 {
@@ -304,10 +290,12 @@ namespace Twitterizer.Core
                 twitterResponse.Result = RequestResult.Unknown;
                 return twitterResponse;
             }
-
-#if !LITE && !SILVERLIGHT
-            this.AddResultToCache(cacheKeyBuilder, cache, twitterResponse.ResponseObject);
-#endif
+            catch (Newtonsoft.Json.JsonSerializationException)
+            {
+                twitterResponse.ErrorMessage = "Unable to parse JSON";
+                twitterResponse.Result = RequestResult.Unknown;
+                return twitterResponse;
+            }
 
             // Pass the current oauth tokens into the new object, so method calls from there will keep the authentication.
             twitterResponse.Tokens = this.Tokens;
@@ -330,7 +318,11 @@ namespace Twitterizer.Core
                     break;
 
                 case HttpStatusCode.BadRequest:
-                    twitterResponse.Result = rateLimiting.Remaining == 0 ? RequestResult.RateLimited : RequestResult.BadRequest;
+                    twitterResponse.Result = (rateLimiting != null && rateLimiting.Remaining == 0) ? RequestResult.RateLimited : RequestResult.BadRequest;
+                    break;
+
+                case (HttpStatusCode)420: //Rate Limited from Search/Trends API
+                    twitterResponse.Result = RequestResult.RateLimited;
                     break;
 
                 case HttpStatusCode.Unauthorized:
@@ -345,6 +337,14 @@ namespace Twitterizer.Core
                     twitterResponse.Result = RequestResult.ProxyAuthenticationRequired;
                     break;
 
+                case HttpStatusCode.RequestTimeout:
+                    twitterResponse.Result = RequestResult.TwitterIsOverloaded;
+                    break;
+
+                case HttpStatusCode.Forbidden:
+                    twitterResponse.Result = RequestResult.Unauthorized;
+                    break;
+
                 default:
                     twitterResponse.Result = RequestResult.Unknown;
                     break;
@@ -387,6 +387,11 @@ namespace Twitterizer.Core
                 rateLimiting.ResetDate = DateTime.SpecifyKind(new DateTime(1970, 1, 1, 0, 0, 0, 0)
                     .AddSeconds(double.Parse(responseHeaders["X-RateLimit-Reset"], CultureInfo.InvariantCulture)), DateTimeKind.Utc);
             }
+            else if(!string.IsNullOrEmpty(responseHeaders["Retry-After"]))
+            {
+                rateLimiting.ResetDate = DateTime.UtcNow.AddSeconds(Convert.ToInt32(responseHeaders["Retry-After"]));
+            }
+            
             return rateLimiting;
         }
 
@@ -408,38 +413,10 @@ namespace Twitterizer.Core
                     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>
-        /// <param name="cache">The cache.</param>
-        /// <param name="resultObject">The result object.</param>
-        private void AddResultToCache(StringBuilder cacheKeyBuilder, Cache cache, T resultObject)
-        {
-            // If caching is enabled, add the result to the cache.
-            if (this.Verb == HTTPVerb.GET && this.OptionalProperties.CacheOutput)
-            {
-                cache.Add(
-                    cacheKeyBuilder.ToString(),
-                    resultObject,
-                    null,
-                    DateTime.Now.Add(this.OptionalProperties.CacheTimespan),
-                    Cache.NoSlidingExpiration,
-                    CacheItemPriority.Normal,
-                    null);
-            }
-        }
-#endif
+            return AccessLevel.Unavailable;
         }
+    }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Core/TwitterCursorPagedIdCollection.cs b/lib/Twitterizer/Twitterizer2/Core/TwitterCursorPagedIdCollection.cs
index 599f792..feeb615 100644
--- a/lib/Twitterizer/Twitterizer2/Core/TwitterCursorPagedIdCollection.cs
+++ b/lib/Twitterizer/Twitterizer2/Core/TwitterCursorPagedIdCollection.cs
@@ -34,15 +34,19 @@
 
 namespace Twitterizer
 {
+    using System;
     using System.Collections.Generic;
     using System.Collections.ObjectModel;
     using Newtonsoft.Json;
     using Newtonsoft.Json.Linq;
-    using Twitterizer.Core;
+    using Core;
 
     /// <summary>
     /// Holds a collection of ID values that are broken into multiple pages.
     /// </summary>
+#if !SILVERLIGHT
+    [Serializable]
+#endif
     public class TwitterCursorPagedIdCollection : Collection<decimal>, ITwitterObject
     {
         /// <summary>
diff --git a/lib/Twitterizer/Twitterizer2/Core/TwitterDictionary.cs b/lib/Twitterizer/Twitterizer2/Core/TwitterDictionary.cs
new file mode 100644
index 0000000..9acc437
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Core/TwitterDictionary.cs
@@ -0,0 +1,62 @@
+//-----------------------------------------------------------------------
+// <copyright file="TwitterDictionary.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 base class for object dictionaries.</summary>
+//-----------------------------------------------------------------------
+
+namespace Twitterizer.Core
+{
+    using System;
+    using System.Collections.ObjectModel;
+    using System.Runtime.Serialization;
+    using System.Collections.Generic;
+
+    /// <summary>
+    /// The base class for object dictionaries.
+    /// </summary>
+    /// <typeparam name="T">The type of key object stored in the collection.</typeparam>
+    /// <typeparam name="T2">The type of value object stored in the collection.</typeparam>
+#if !SILVERLIGHT
+    [Serializable]
+#endif
+    [DataContract]
+    public abstract class TwitterDictionary<T, T2> : Dictionary<T, T2>
+        //where T : class, ITwitterObject
+        where T2: class, ITwitterObject        
+    {
+        /// <summary>
+        /// Gets or sets the annotations.
+        /// </summary>
+        /// <value>The annotations.</value>
+        [DataMember]
+        public Dictionary<string, string> Annotations { get; set; }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Core/TwitterIdCollection.cs b/lib/Twitterizer/Twitterizer2/Core/TwitterIdCollection.cs
index 76795bd..df5b1aa 100644
--- a/lib/Twitterizer/Twitterizer2/Core/TwitterIdCollection.cs
+++ b/lib/Twitterizer/Twitterizer2/Core/TwitterIdCollection.cs
@@ -32,15 +32,20 @@
 // <summary>The twitter id collection class.</summary>
 //-----------------------------------------------------------------------
 
+
 namespace Twitterizer
 {
+    using System;
     using System.Collections.Generic;
     using System.Collections.ObjectModel;
-    using Twitterizer.Core;
+    using Core;
 
     /// <summary>
     /// Holds a collection of ID values
     /// </summary>
+#if !SILVERLIGHT
+    [Serializable]
+#endif
     public class TwitterIdCollection : Collection<decimal>, ITwitterObject
     {
         /// <summary>
@@ -56,7 +61,7 @@ namespace Twitterizer
         /// <remarks></remarks>
         public TwitterIdCollection(List<decimal> items)
         {
-            items.ForEach((a) => { this.Add(a); });
+            items.ForEach(Add);
         }
 
         /// <summary>
@@ -66,7 +71,7 @@ namespace Twitterizer
         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"/>.
+        /// Performs an explicit conversion from <see cref="List{T}"/> to <see cref="Twitterizer.TwitterIdCollection"/>.
         /// </summary>
         /// <param name="collection">The collection.</param>
         /// <returns>The result of the conversion.</returns>
diff --git a/lib/Twitterizer/Twitterizer2/Core/TwitterizerDateConverter.cs b/lib/Twitterizer/Twitterizer2/Core/TwitterizerDateConverter.cs
index dc8a475..396fdb3 100644
--- a/lib/Twitterizer/Twitterizer2/Core/TwitterizerDateConverter.cs
+++ b/lib/Twitterizer/Twitterizer2/Core/TwitterizerDateConverter.cs
@@ -42,7 +42,6 @@ namespace Twitterizer
     /// </summary>
     public class TwitterizerDateConverter : Newtonsoft.Json.Converters.DateTimeConverterBase
     {
-        public TwitterizerDateConverter() { }
         /// <summary>
         /// The date pattern for most dates returned by the API
         /// </summary>
@@ -79,21 +78,10 @@ namespace Twitterizer
         /// <param name="serializer">The serializer.</param>
         public override void WriteJson(Newtonsoft.Json.JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer)
         {
-            throw new NotImplementedException();
-        }
+            if (value.GetType() != typeof(DateTime))
+                throw new ArgumentOutOfRangeException("value", "The value provided was not the expected data type.");
 
-//#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
+            writer.WriteValue(((DateTime)value).ToString(DateFormat, CultureInfo.InvariantCulture));
+        }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Information.cs b/lib/Twitterizer/Twitterizer2/Information.cs
index fc4dff9..62b72b3 100644
--- a/lib/Twitterizer/Twitterizer2/Information.cs
+++ b/lib/Twitterizer/Twitterizer2/Information.cs
@@ -48,7 +48,7 @@ namespace Twitterizer
 #if !SILVERLIGHT
             return System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
 #else
-            return System.Reflection.Assembly.GetExecutingAssembly().FullName.Split(',')[1].Split('=')[1].ToString();
+            return System.Reflection.Assembly.GetExecutingAssembly().FullName.Split(',')[1].Split('=')[1];
 #endif
         }
     }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileBackgroundImageCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileBackgroundImageCommand.cs
index 6ca5dc7..3a3ca15 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileBackgroundImageCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileBackgroundImageCommand.cs
@@ -45,7 +45,7 @@ namespace Twitterizer.Commands
 #endif
     internal sealed class UpdateProfileBackgroundImageCommand : TwitterCommand<TwitterUser>
     {
-        private byte[] imageData;
+        private readonly byte[] imageData;
 
         /// <summary>
         /// Initializes a new instance of the <see cref="UpdateProfileBackgroundImageCommand"/> class.
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileBackgroundImageOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileBackgroundImageOptions.cs
index 6c58920..90308ad 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileBackgroundImageOptions.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileBackgroundImageOptions.cs
@@ -36,6 +36,9 @@ namespace Twitterizer
 {
     using System;
 
+    /// <summary>
+    /// An options class for updating the user's profile background image.
+    /// </summary>
 #if !SILVERLIGHT
     [Serializable]
 #endif
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileColorsCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileColorsCommand.cs
index e9cf653..bee553c 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileColorsCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileColorsCommand.cs
@@ -75,50 +75,65 @@ namespace Twitterizer.Commands
         {
             UpdateProfileColorsOptions options = (UpdateProfileColorsOptions)this.OptionalProperties;
 
-            if (options.BackgroundColor != null)
-            {
 #if !SILVERLIGHT
+            if (options.BackgroundColor != Color.Empty)
+            {
                 this.RequestParameters.Add("profile_background_color", ColorTranslator.ToHtml(options.BackgroundColor));
+            }
 #else
+            if (options.BackgroundColor != null)
+            {
                 this.RequestParameters.Add("profile_background_color", options.BackgroundColor);
-#endif
             }
+#endif
 
-            if (options.TextColor != null)
-            {
 #if !SILVERLIGHT
+            if (options.TextColor != Color.Empty)
+            {
                 this.RequestParameters.Add("profile_text_color", ColorTranslator.ToHtml(options.TextColor));
+            }
 #else
+            if (options.TextColor != null)
+            {
                 this.RequestParameters.Add("profile_text_color", options.TextColor);
-#endif
             }
+#endif
 
-            if (options.LinkColor != null)
-            {
 #if !SILVERLIGHT
+            if (options.LinkColor != Color.Empty)
+            {
                 this.RequestParameters.Add("profile_link_color", ColorTranslator.ToHtml(options.LinkColor));
+            }
 #else
+            if (options.LinkColor != null)
+            {
                 this.RequestParameters.Add("profile_link_color", options.LinkColor);
-#endif
             }
+#endif
 
-            if (options.SidebarFillColor != null)
-            {
 #if !SILVERLIGHT
+            if (options.SidebarFillColor != Color.Empty)
+            {
                 this.RequestParameters.Add("profile_sidebar_fill_color", ColorTranslator.ToHtml(options.SidebarFillColor));
+            }
 #else
+            if (options.SidebarFillColor != null)
+            {
                 this.RequestParameters.Add("profile_sidebar_fill_color", options.SidebarFillColor);
-#endif
             }
+#endif
 
-            if (options.SidebarBorderColor != null)
-            {
 #if !SILVERLIGHT
+            if (options.SidebarBorderColor != Color.Empty)
+            {
                 this.RequestParameters.Add("profile_sidebar_border_color", ColorTranslator.ToHtml(options.SidebarBorderColor));
+            }
 #else
+            if (options.SidebarBorderColor != null)
+            {
                 this.RequestParameters.Add("profile_sidebar_border_color", options.SidebarBorderColor);
-#endif
             }
+#endif
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileColorsOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileColorsOptions.cs
index 9a6257a..e23b38f 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileColorsOptions.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileColorsOptions.cs
@@ -39,12 +39,24 @@ namespace Twitterizer
 #endif
 
     /// <summary>
-    /// Optional properties for the <see cref="Twitterizer.TwitterUser.UpdateProfileColors"/> method.
+    /// Optional properties for the <see cref="Twitterizer.TwitterUser"/>.Profile*Colors methods.
     /// </summary>
     public class UpdateProfileColorsOptions : OptionalProperties
     {
 #if !SILVERLIGHT
         /// <summary>
+        /// Initializes a new instance of the <see cref="UpdateProfileColorsOptions"/> class.
+        /// </summary>
+        public UpdateProfileColorsOptions()
+        {
+            BackgroundColor = Color.Empty;
+            TextColor = Color.Empty;
+            LinkColor = Color.Empty;
+            SidebarFillColor = Color.Empty;
+            SidebarBorderColor = Color.Empty;
+        }
+
+        /// <summary>
         /// Gets or sets the color of the background.
         /// </summary>
         /// <value>The color of the background.</value>
@@ -74,7 +86,7 @@ namespace Twitterizer
         /// <value>The color of the sidebar border.</value>
         public Color SidebarBorderColor { get; set; }
 #else
-                /// <summary>
+        /// <summary>
         /// Gets or sets the color of the background.
         /// </summary>
         /// <value>The color of the background.</value>
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileImageCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileImageCommand.cs
index 9ae17fd..f466d2c 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileImageCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Account/UpdateProfileImageCommand.cs
@@ -42,7 +42,7 @@ namespace Twitterizer.Commands
 #endif
     internal class UpdateProfileImageCommand : TwitterCommand<TwitterUser>
     {
-        private byte[] imageData;
+        private readonly byte[] imageData;
 
         /// <summary>
         /// Initializes a new instance of the <see cref="UpdateProfileImageCommand"/> class.
@@ -63,7 +63,7 @@ namespace Twitterizer.Commands
                 throw new ArithmeticException("Image data cannot be null or zero length.");
             }
 
-            if (image.Length > 89600)
+            if (image.Length > 716800)
             {
                 throw new ArithmeticException("Image cannot exceed 700Kb in size.");
             }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Account/VerifyCredentialsCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Account/VerifyCredentialsCommand.cs
index 63d6086..a93a07b 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Account/VerifyCredentialsCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Account/VerifyCredentialsCommand.cs
@@ -64,7 +64,7 @@ namespace Twitterizer.Commands
 
             if (options == null) return;
 
-            if (options.IncludeEntities == true)
+            if (options.IncludeEntities)
             {
                 this.RequestParameters.Add("include_entities", "true");
             }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/DirectMessagesOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/DirectMessagesOptions.cs
index f8bf0a1..eae72d0 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/DirectMessagesOptions.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/DirectMessagesOptions.cs
@@ -48,7 +48,6 @@ namespace Twitterizer
         /// Initializes a new instance of the <see cref="DirectMessagesOptions"/> class.
         /// </summary>
         public DirectMessagesOptions()
-            : base()
         {
             this.Page = 1;
         }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/DirectMessagesSentOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/DirectMessagesSentOptions.cs
index 16ed614..dc19424 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/DirectMessagesSentOptions.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/DirectMessagesSentOptions.cs
@@ -47,7 +47,6 @@ namespace Twitterizer
         /// Initializes a new instance of the <see cref="DirectMessagesSentOptions"/> class.
         /// </summary>
         public DirectMessagesSentOptions()
-            : base()
         {
             this.Page = 1;
         }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/ShowDirectMessageCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/ShowDirectMessageCommand.cs
index e7c849e..d302bda 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/ShowDirectMessageCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/ShowDirectMessageCommand.cs
@@ -53,12 +53,12 @@ namespace Twitterizer.Commands
         {
             if (tokens == null)
             {
-                throw new ArgumentNullException("The tokens parameter is required.");
+                throw new ArgumentNullException("tokens", "The tokens parameter is required.");
             }
 
             if (id <= 0)
             {
-                throw new ArgumentOutOfRangeException("The id parameter must be greater than zero.");
+                throw new ArgumentOutOfRangeException("id", "The id parameter must be greater than zero.");
             }
         }
 
diff --git a/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/TwitterDirectMessage.cs b/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/TwitterDirectMessage.cs
index 3492210..96f44d6 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/TwitterDirectMessage.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/DirectMessage/TwitterDirectMessage.cs
@@ -281,5 +281,14 @@ namespace Twitterizer
 
             return Core.CommandPerformer.PerformAction(command);
         }
+
+        /// <summary>
+        /// Returns the status text with HTML links to users, urls, and hashtags.
+        /// </summary>
+        /// <returns></returns>
+        public string LinkifiedText()
+        {
+            return TwitterStatus.LinkifiedText(Entities, Text);
+        }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Favorites/ListFavoritesCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Favorites/ListFavoritesCommand.cs
index 48c8732..0fbf04b 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Favorites/ListFavoritesCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Favorites/ListFavoritesCommand.cs
@@ -74,7 +74,7 @@ namespace Twitterizer.Commands
                 this.RequestParameters.Add("page", "1");
                 return;
             }
-
+            
             this.RequestParameters.Add("page", options.Page > 0 ? options.Page.ToString(CultureInfo.InvariantCulture) : "1");
 
             if (!string.IsNullOrEmpty(options.UserNameOrId))
@@ -86,6 +86,12 @@ namespace Twitterizer.Commands
             {
                 this.RequestParameters.Add("count", options.Count.ToString(CultureInfo.InvariantCulture));
             }
+
+            if (options.SinceStatusId > 0)
+                this.RequestParameters.Add("since_id", options.SinceStatusId.ToString());
+
+            if (options.MaxStatusId > 0)
+                this.RequestParameters.Add("max_id", options.MaxStatusId.ToString());
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Favorites/ListFavoritesOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/Favorites/ListFavoritesOptions.cs
index 66306d9..3afdff5 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Favorites/ListFavoritesOptions.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Favorites/ListFavoritesOptions.cs
@@ -59,5 +59,17 @@ namespace Twitterizer
         /// </summary>
         /// <value>The page number.</value>
         public int Page { get; set; }
+
+        /// <summary>
+        /// Gets or sets the minimum (earliest) status id to request.
+        /// </summary>
+        /// <value>The since id.</value>
+        public decimal SinceStatusId { get; set; }
+
+        /// <summary>
+        /// Gets or sets the max (latest) status id to request.
+        /// </summary>
+        /// <value>The max id.</value>
+        public decimal MaxStatusId { get; set; }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Favorites/TwitterFavorite.cs b/lib/Twitterizer/Twitterizer2/Methods/Favorites/TwitterFavorite.cs
index ded8856..d98bf94 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Favorites/TwitterFavorite.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Favorites/TwitterFavorite.cs
@@ -35,7 +35,7 @@
 namespace Twitterizer
 {
     using System;
-    using Twitterizer.Core;
+    using Core;
 
     /// <summary>
     /// The TwitterFavorite class. Provides static methods for manipulating favorite tweets.
@@ -46,13 +46,6 @@ namespace Twitterizer
     public sealed class TwitterFavorite : TwitterObject
     {
         /// <summary>
-        /// Prevents a default instance of the TwitterFavorite class from being created.
-        /// </summary>
-        private TwitterFavorite()
-        { 
-        }
-
-        /// <summary>
         /// Favorites the status specified in the ID parameter as the authenticating user.
         /// </summary>
         /// <param name="tokens">The tokens.</param>
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Friendship/CreateFriendshipOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/Friendship/CreateFriendshipOptions.cs
index 4a5008c..eb7263a 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Friendship/CreateFriendshipOptions.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Friendship/CreateFriendshipOptions.cs
@@ -43,14 +43,6 @@ namespace Twitterizer
 #endif
     public sealed class CreateFriendshipOptions : OptionalProperties
     {
-         /// <summary>
-        /// Initializes a new instance of the <see cref="CreateFriendshipOptions"/> class.
-        /// </summary>
-        public CreateFriendshipOptions()
-            : base()
-        {
-        }
-
         /// <summary>
         /// Gets or sets a value indicating whether to enable delivery of statuses from this user to the authenticated user's device
         /// </summary>
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Friendship/NoRetweetIDsCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Friendship/NoRetweetIDsCommand.cs
new file mode 100644
index 0000000..bcc415b
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Friendship/NoRetweetIDsCommand.cs
@@ -0,0 +1,60 @@
+//-----------------------------------------------------------------------
+// <copyright file="NoRetweetIDsCommand.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 NoRetweetIDsCommand : TwitterCommand<UserIdCollection>
+    {
+        /// <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 NoRetweetIDsCommand(OAuthTokens tokens, OptionalProperties options)
+            : base(HTTPVerb.GET, "friendships/no_retweet_ids.json", tokens, options)
+        { }
+
+        /// <summary>
+        /// Inits this instance.
+        /// </summary>
+        public override void Init()
+        { }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Friendship/TwitterFriendship.cs b/lib/Twitterizer/Twitterizer2/Methods/Friendship/TwitterFriendship.cs
index 9d2238d..d2c7587 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Friendship/TwitterFriendship.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Friendship/TwitterFriendship.cs
@@ -485,5 +485,75 @@ namespace Twitterizer
             return OutgoingRequests(tokens, null);
         }
 
+        /// <summary>
+        /// Returns a collection of IDs that the user does not want to see retweets from.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="options">The options.</param>
+        /// <returns></returns>
+        public static TwitterResponse<UserIdCollection> NoRetweetIDs(OAuthTokens tokens, OptionalProperties options)
+        {
+            Commands.NoRetweetIDsCommand command = new Commands.NoRetweetIDsCommand(tokens, options);
+            return Core.CommandPerformer.PerformAction(command);
+        }
+
+        /// <summary>
+        /// Returns a collection of IDs that the user does not want to see retweets from.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>        
+        /// <returns></returns>
+        public static TwitterResponse<UserIdCollection> NoRetweetIDs(OAuthTokens tokens)
+        {
+            return NoRetweetIDs(tokens, null);
+        }
+
+        /// <summary>
+        /// Updates a friendship for a user.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="userid">The userid.</param>
+        /// <param name="options">The options.</param>
+        /// <returns></returns>
+        public static TwitterResponse<TwitterRelationship> Update(OAuthTokens tokens, decimal userid, UpdateFriendshipOptions options)
+        {
+            Commands.UpdateFriendshipCommand command = new Commands.UpdateFriendshipCommand(tokens, userid, options);
+            return Core.CommandPerformer.PerformAction(command);
+        }
+
+        /// <summary>
+        /// Updates a friendship for a user.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="userid">The userid.</param>
+        /// <returns></returns>
+        public static TwitterResponse<TwitterRelationship> Update(OAuthTokens tokens, decimal userid)
+        {
+            return Update(tokens, userid, null);
+        }
+
+        /// <summary>
+        /// Updates a friendship for a user.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="screenname">The screenname.</param>
+        /// <param name="options">The options.</param>
+        /// <returns></returns>
+        public static TwitterResponse<TwitterRelationship> Update(OAuthTokens tokens, string screenname, UpdateFriendshipOptions options)
+        {
+            Commands.UpdateFriendshipCommand command = new Commands.UpdateFriendshipCommand(tokens, screenname, options);
+            return Core.CommandPerformer.PerformAction(command);
+        }
+
+        /// <summary>
+        /// Updates a friendship for a user.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="screenname">The screenname.</param>
+        /// <returns></returns>
+        public static TwitterResponse<TwitterRelationship> Update(OAuthTokens tokens, string screenname)
+        {
+            return Update(tokens, screenname, null);
+        }
+
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Friendship/TwitterRelationship.cs b/lib/Twitterizer/Twitterizer2/Methods/Friendship/TwitterRelationship.cs
index b5188fd..a7e1ba0 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Friendship/TwitterRelationship.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Friendship/TwitterRelationship.cs
@@ -50,50 +50,18 @@ namespace Twitterizer
     public class TwitterRelationship : TwitterObject
     {
         /// <summary>
-        /// The relationship source
-        /// </summary>
-        private TwitterUser source;
-
-        /// <summary>
-        /// The relationship target
-        /// </summary>
-        private TwitterUser target;
-
-        /// <summary>
         /// Gets or sets the source.
         /// </summary>
         /// <value>The source.</value>
         [JsonProperty(PropertyName = "source")]
-        public TwitterUser Source
-        {
-            get
-            {
-                return this.source;
-            }
-
-            set
-            {
-                this.source = value;
-            }
-        }
+        public TwitterRelationshipUser Source { get; set; }
 
         /// <summary>
         /// Gets or sets the target.
         /// </summary>
         /// <value>The target.</value>
         [JsonProperty(PropertyName = "target")]
-        public TwitterUser Target
-        {
-            get
-            {
-                return this.target;
-            }
-
-            set
-            {
-                this.target = value;
-            }
-        }
+        public TwitterRelationshipUser Target { get; set; }
 
         /// <summary>
         /// Gets or sets the relationship.
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Friendship/TwitterRelationshipUser.cs b/lib/Twitterizer/Twitterizer2/Methods/Friendship/TwitterRelationshipUser.cs
new file mode 100644
index 0000000..5ffc154
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Friendship/TwitterRelationshipUser.cs
@@ -0,0 +1,123 @@
+//-----------------------------------------------------------------------
+// <copyright file="TwitterRelationshipUser.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 relationship user class</summary>
+//-----------------------------------------------------------------------
+
+namespace Twitterizer
+{
+    using System;
+    using System.Diagnostics;
+    using Newtonsoft.Json;
+    using Twitterizer.Core;
+
+    /// <summary>
+    /// The Twitter Relationship entity class
+    /// </summary>
+    [JsonObject(MemberSerialization = MemberSerialization.OptIn)]
+#if !SILVERLIGHT
+    [Serializable]
+#endif
+    public class TwitterRelationshipUser : TwitterObject
+    {  
+
+        /// <summary>
+        /// Gets or sets the ID.
+        /// </summary>
+        /// <value>The ID.</value>
+        [JsonProperty(PropertyName = "id")]
+        public decimal Id { get; set; }
+
+        /// <summary>
+        /// Gets or sets if Following.
+        /// </summary>
+        /// <value>Is the user following.</value>
+        [JsonProperty(PropertyName = "following")]
+        public bool Following { get; set; }
+
+        /// <summary>
+        /// Gets or sets the ScreenName.
+        /// </summary>
+        /// <value>The users ScreenName.</value>
+        [JsonProperty(PropertyName = "screen_name")]
+        public string ScreenName { get; set; }
+
+        /// <summary>
+        /// Gets or sets if followed by.
+        /// </summary>
+        /// <value>Is the user being followed by.</value>
+        [JsonProperty(PropertyName = "followed_by")]
+        public bool FollowedBy { get; set; }
+
+        /// <summary>
+        /// Gets or sets if notifications are enabled.
+        /// </summary>
+        /// <value>Notifications enabled for this user.</value>
+        [JsonProperty(PropertyName = "notifications_enabled")]
+        public bool? NotificationsEnabled { get; set; }
+
+        /// <summary>
+        /// Gets or sets if Can DM.
+        /// </summary>
+        /// <value>Can the user be DM.</value>
+        [JsonProperty(PropertyName = "can_dm")]
+        public bool CanDM { get; set; }
+
+        /// <summary>
+        /// Gets or sets if wants retweets.
+        /// </summary>
+        /// <value>The user wants to see retweets.</value>
+        [JsonProperty(PropertyName = "want_retweets")]
+        public bool? WantRetweets { get; set; }
+
+        /// <summary>
+        /// Gets or sets if marked as spam.
+        /// </summary>
+        /// <value>If the user is marked as spam.</value>
+        [JsonProperty(PropertyName = "marked_spam")]
+        public bool? MarkedSpam { get; set; }
+
+        /// <summary>
+        /// Gets or sets if all replies.
+        /// </summary>
+        /// <value>If the user wants All Replies.</value>
+        [JsonProperty(PropertyName = "all_replies")]
+        public bool? AllReplies { get; set; }
+
+        /// <summary>
+        /// Gets or sets if blocking.
+        /// </summary>
+        /// <value>If the user is blocked.</value>
+        [JsonProperty(PropertyName = "blocking")]
+        public bool? Blocking { get; set; }      
+           
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Friendship/UpdateFriendshipCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Friendship/UpdateFriendshipCommand.cs
new file mode 100644
index 0000000..76e6b75
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Friendship/UpdateFriendshipCommand.cs
@@ -0,0 +1,137 @@
+//-----------------------------------------------------------------------
+// <copyright file="UpdateFriendshipCommand.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 Direct Messages Sent Command class.</summary>
+//-----------------------------------------------------------------------
+
+namespace Twitterizer.Commands
+{
+    using System;
+    using System.Globalization;
+    using Twitterizer;
+    using Twitterizer.Core;
+
+    /// <summary>
+    /// Creates a friendship between the authenticated user and another user
+    /// </summary>
+    [AuthorizedCommandAttribute]
+#if !SILVERLIGHT
+    [Serializable]
+#endif
+    internal sealed class UpdateFriendshipCommand : Core.TwitterCommand<TwitterRelationship>
+    {
+        /// <summary>
+        /// The base address to the API method.
+        /// </summary>
+        private const string Path = "friendships/update.json";
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="UpdateFriendshipCommand"/> class.
+        /// </summary>
+        /// <param name="tokens">The request tokens.</param>
+        /// <param name="userId">The userid.</param>
+        /// <param name="optionalProperties">The optional properties.</param>
+        public UpdateFriendshipCommand(OAuthTokens tokens, decimal userId, UpdateFriendshipOptions optionalProperties)
+            : base(HTTPVerb.POST, Path, tokens, optionalProperties)
+        {
+            if (tokens == null)
+            {
+                throw new ArgumentNullException("tokens");
+            }
+
+            if (userId <= 0)
+            {
+                throw new ArgumentException("userId");
+            }
+
+            this.UserId = userId;
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="UpdateFriendshipCommand"/> class.
+        /// </summary>
+        /// <param name="tokens">The request tokens.</param>
+        /// <param name="userName">Name of the user.</param>
+        /// <param name="optionalProperties">The optional properties.</param>
+        public UpdateFriendshipCommand(OAuthTokens tokens, string userName, UpdateFriendshipOptions optionalProperties)
+            : base(HTTPVerb.POST, Path, tokens, optionalProperties)
+        {
+            if (tokens == null)
+            {
+                throw new ArgumentNullException("tokens");
+            }
+
+            if (string.IsNullOrEmpty(userName))
+            {
+                throw new ArgumentNullException("userName");
+            }
+
+            this.UserName = userName;
+        }
+        
+        /// <summary>
+        /// Gets or sets the user id.
+        /// </summary>
+        /// <value>The user id.</value>
+        public decimal UserId { get; set; }
+
+        /// <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.UserId > 0)
+            {
+                this.RequestParameters.Add("user_id", this.UserId.ToString(CultureInfo.InvariantCulture));
+            }
+            else if (!string.IsNullOrEmpty(this.UserName))
+            {
+                this.RequestParameters.Add("screen_name", this.UserName);
+            }
+
+            UpdateFriendshipOptions options = this.OptionalProperties as UpdateFriendshipOptions;
+            if (options != null)
+            {
+                if (options.DeviceNotifications != null)
+                    this.RequestParameters.Add("device", (bool)options.DeviceNotifications ? "true" : "false");
+
+                if (options.ShowRetweets != null)
+                    this.RequestParameters.Add("retweets", (bool)options.ShowRetweets ? "true" : "false");
+            }
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Friendship/UpdateFriendshipOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/Friendship/UpdateFriendshipOptions.cs
new file mode 100644
index 0000000..b33906d
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Friendship/UpdateFriendshipOptions.cs
@@ -0,0 +1,67 @@
+//-----------------------------------------------------------------------
+// <copyright file="UpdateFriendshipOptions.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 update friendship options class.</summary>
+//-----------------------------------------------------------------------
+namespace Twitterizer
+{
+    using System;
+
+    /// <summary>
+    /// The Update Friendship Options class
+    /// </summary>
+#if !SILVERLIGHT
+    [System.Serializable]
+#endif
+    public sealed class UpdateFriendshipOptions : OptionalProperties
+    {
+         /// <summary>
+        /// Initializes a new instance of the <see cref="UpdateFriendshipOptions"/> class.
+        /// </summary>
+        public UpdateFriendshipOptions()
+        {
+            DeviceNotifications = null;
+            ShowRetweets = null;
+        }
+
+        /// <summary>
+        /// Gets or sets a value indicating whether to enable delivery of statuses from this user to the authenticated user's device
+        /// </summary>
+        /// <value><c>true</c> if follow; otherwise, <c>false</c>.</value>
+        public bool? DeviceNotifications { get; set; }
+
+        /// <summary>
+        /// Gets or sets a value indicating whether to show retweets for this user
+        /// </summary>
+        /// <value><c>true</c> if follow; otherwise, <c>false</c>.</value>
+        public bool? ShowRetweets { get; set; } 
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Geo/Coordinate.cs b/lib/Twitterizer/Twitterizer2/Methods/Geo/Coordinate.cs
index d0afe8a..aafd67c 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Geo/Coordinate.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Geo/Coordinate.cs
@@ -36,6 +36,7 @@ namespace Twitterizer
     using System;
     using System.Collections.ObjectModel;
     using System.Linq;
+    using System.Runtime.Serialization;
     using Newtonsoft.Json;
 
     /// <summary>
@@ -44,6 +45,7 @@ namespace Twitterizer
 #if !SILVERLIGHT
     [Serializable]
 #endif
+    [DataContract]
     public class Coordinate
     {
         /// <summary>
@@ -103,10 +105,13 @@ namespace Twitterizer
                         return null;
                     }
 
-                    int depth = reader.Depth + 1;
+                    if (reader.TokenType == JsonToken.StartArray)
+                        reader.Read();
+
+                    //int depth = reader.Depth + 1;
                     double count = 1;
 
-                    while (reader.Read() && reader.Depth >= startDepth)
+                    while (reader.Read() && reader.Depth > startDepth)
                     {
                         if (new[] { JsonToken.StartArray, JsonToken.EndArray }.Contains(reader.TokenType))
                             continue;
@@ -116,16 +121,15 @@ namespace Twitterizer
                         if (count % 2 > 0)
                         {
                             result.Add(new Coordinate());
-                            result[itemIndex].Latitude = (double)reader.Value;
+                            result[itemIndex].Latitude = Convert.ToDouble(reader.Value);
                         }
                         else
                         {
-                            result[itemIndex].Longitude = (double)reader.Value;
+                            result[itemIndex].Longitude = Convert.ToDouble(reader.Value);
                         }
 
                         count++;
-                    }
-
+                    }                    
                     return result;
                 }
                 catch
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Geo/TwitterPlace.cs b/lib/Twitterizer/Twitterizer2/Methods/Geo/TwitterPlace.cs
index e910fba..9d89569 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Geo/TwitterPlace.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Geo/TwitterPlace.cs
@@ -84,6 +84,46 @@ namespace Twitterizer
         public string StreetAddress { get; set; }
 
         /// <summary>
+        /// Gets or sets the postal code.
+        /// </summary>
+        /// <value>The postal code.</value>
+        /// <remarks></remarks>
+        [JsonProperty(PropertyName = "postal_code")]
+        public string PostalCode { get; set; }
+
+        /// <summary>
+        /// Gets or sets the phone number in the preferred local format for the place, include long distance code.
+        /// </summary>
+        /// <value>The phone number.</value>
+        /// <remarks></remarks>
+        [JsonProperty(PropertyName = "phone")]
+        public string Phone { get; set; }
+
+        /// <summary>
+        /// Gets or sets the locality.
+        /// </summary>
+        /// <value>The locality.</value>
+        /// <remarks></remarks>
+        [JsonProperty(PropertyName = "locality")]
+        public string Locality { get; set; }
+
+        /// <summary>
+        /// Gets or sets the region.
+        /// </summary>
+        /// <value>The region.</value>
+        /// <remarks></remarks>
+        [JsonProperty(PropertyName = "region")]
+        public string Region { get; set; }
+
+        /// <summary>
+        /// Gets or sets the iso3 country code.
+        /// </summary>
+        /// <value>The iso3 country code.</value>
+        /// <remarks></remarks>
+        [JsonProperty(PropertyName = "iso3")]
+        public string Iso3CountryCode { get; set; }
+
+        /// <summary>
         /// Gets or sets the full name.
         /// </summary>
         /// <value>The full name.</value>
@@ -105,6 +145,13 @@ namespace Twitterizer
         public string Id { get; set; }
 
         /// <summary>
+        /// Gets or sets an ID or comma separated list of IDs representing the place in the applications place database.
+        /// </summary>
+        /// <value>The app ids.</value>
+        [JsonProperty(PropertyName = "app:id")]
+        public string AppIds { get; set; }
+
+        /// <summary>
         /// Gets or sets the bounding box.
         /// </summary>
         /// <value>The bounding box.</value>
diff --git a/lib/Twitterizer/Twitterizer2/Methods/List/CreateListMembershipCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/List/CreateListMembershipCommand.cs
index 7297e38..698e30e 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/List/CreateListMembershipCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/List/CreateListMembershipCommand.cs
@@ -1,14 +1,11 @@
 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;
+        private readonly decimal listId;
 
         /// <summary>
         /// Initializes a new instance of the <see cref="CreateListMembershipCommand"/> class.
diff --git a/lib/Twitterizer/Twitterizer2/Methods/List/ListMembershipsCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/List/ListMembershipsCommand.cs
index 6f6ff50..2ad53f6 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/List/ListMembershipsCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/List/ListMembershipsCommand.cs
@@ -45,22 +45,52 @@ namespace Twitterizer.Commands
     [AuthorizedCommandAttribute]
     internal sealed class ListMembershipsCommand : TwitterCommand<TwitterListCollection>
     {
+        private readonly string screenname;
+        private readonly decimal userid;
+
         /// <summary>
         /// Initializes a new instance of the <see cref="ListMembershipsCommand"/> class.
         /// </summary>
         /// <param name="requestTokens">The request tokens.</param>
-        /// <param name="username">The username.</param>
+        /// <param name="username">The screenname.</param>
         /// <param name="options">The options.</param>
-        public ListMembershipsCommand(OAuthTokens requestTokens, string username, ListMembershipsOptions options)
+        public ListMembershipsCommand(OAuthTokens requestTokens, string screenname, ListMembershipsOptions options)
             : base(
                 HTTPVerb.GET, 
-                string.Format("{0}/lists/memberships.json", username), 
+                "lists/memberships.json", 
                 requestTokens, 
                 options)
         {
-            if (string.IsNullOrEmpty(username))
+            if (string.IsNullOrEmpty(screenname))
+            {
+                throw new ArgumentNullException("screenname");
+            }
+
+            if (Tokens == null)
+            {
+                throw new ArgumentNullException("requestTokens");
+            }
+
+            this.DeserializationHandler = TwitterListCollection.Deserialize;
+            this.screenname = screenname;
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ListMembershipsCommand"/> class.
+        /// </summary>
+        /// <param name="requestTokens">The request tokens.</param>
+        /// <param name="username">The screenname.</param>
+        /// <param name="options">The options.</param>
+        public ListMembershipsCommand(OAuthTokens requestTokens, decimal userid, ListMembershipsOptions options)
+            : base(
+                HTTPVerb.GET,
+                "lists/memberships.json",
+                requestTokens,
+                options)
+        {
+            if (userid <= 0)
             {
-                throw new ArgumentNullException("username");
+                throw new ArgumentNullException("userid");
             }
 
             if (Tokens == null)
@@ -69,6 +99,7 @@ namespace Twitterizer.Commands
             }
 
             this.DeserializationHandler = TwitterListCollection.Deserialize;
+            this.userid = userid;
         }
 
         /// <summary>
@@ -76,14 +107,23 @@ namespace Twitterizer.Commands
         /// </summary>
         public override void Init()
         {
+            if (!String.IsNullOrEmpty(screenname))
+                this.RequestParameters.Add("screen_name", screenname);
+
+            if (userid > 0)
+                this.RequestParameters.Add("user_id", userid.ToString());
+
             ListMembershipsOptions options = this.OptionalProperties as ListMembershipsOptions;
-            if (options == null || options.Cursor <= 0)
+            if (options != null)
             {
-                this.RequestParameters.Add("cursor", "-1");
+                if (options.Cursor <= 0)
+                    this.RequestParameters.Add("cursor", "-1");
+                else
+                    this.RequestParameters.Add("cursor", options.Cursor.ToString(CultureInfo.CurrentCulture));
 
+                if (options.FilterToOwnedLists)
+                    this.RequestParameters.Add("filter_to_owned_lists", "true");
             }
-            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
index 5eb0ca1..b901a3f 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/List/ListMembershipsOptions.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/List/ListMembershipsOptions.cs
@@ -44,5 +44,11 @@ namespace Twitterizer
         /// </summary>
         /// <value>The cursor.</value>
         public long Cursor { get; set; }
+
+        /// <summary>
+        /// Gets or sets filtered to owned lists.
+        /// </summary>
+        /// <value>Whether to filter to owned lists.</value>
+        public bool FilterToOwnedLists { get; set; }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/List/ListStatusesCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/List/ListStatusesCommand.cs
index 0fd7b4a..81d6d27 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/List/ListStatusesCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/List/ListStatusesCommand.cs
@@ -100,6 +100,11 @@ namespace Twitterizer.Commands
                 this.RequestParameters.Add("include_entities", "true");
             }
 
+            if (options.IncludeRetweets)
+            {
+                this.RequestParameters.Add("include_rts", "true");
+            }
+
             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 a397012..41a7a2b 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/List/ListStatusesOptions.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/List/ListStatusesOptions.cs
@@ -71,5 +71,11 @@ namespace Twitterizer
         /// </summary>
         /// <value>Boolean.</value>
         public bool IncludeEntites { get; set; }
+
+        /// <summary>
+        /// Gets or sets whether to include entities in the request.
+        /// </summary>
+        /// <value>Boolean.</value>
+        public bool IncludeRetweets { get; set; }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/List/TwitterList.cs b/lib/Twitterizer/Twitterizer2/Methods/List/TwitterList.cs
index 26d2f10..5ee627b 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/List/TwitterList.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/List/TwitterList.cs
@@ -329,14 +329,14 @@ namespace Twitterizer
         /// List the lists the specified user has been added to.
         /// </summary>
         /// <param name="tokens">The tokens.</param>
-        /// <param name="username">The username.</param>
+        /// <param name="username">The screenname.</param>
         /// <param name="options">The options.</param>
         /// <returns>
         /// A <see cref="TwitterListCollection"/> instance.
         /// </returns>
-        public static TwitterResponse<TwitterListCollection> GetMemberships(OAuthTokens tokens, string username, ListMembershipsOptions options)
+        public static TwitterResponse<TwitterListCollection> GetMemberships(OAuthTokens tokens, string screenname, ListMembershipsOptions options)
         {
-            Commands.ListMembershipsCommand command = new Twitterizer.Commands.ListMembershipsCommand(tokens, username, options);
+            Commands.ListMembershipsCommand command = new Twitterizer.Commands.ListMembershipsCommand(tokens, screenname, options);
             return Core.CommandPerformer.PerformAction(command);
         }
 
@@ -344,13 +344,41 @@ namespace Twitterizer
         /// List the lists the specified user has been added to.
         /// </summary>
         /// <param name="tokens">The tokens.</param>
-        /// <param name="username">The username.</param>
+        /// <param name="username">The screenname.</param>
+        /// <returns>
+        /// A <see cref="TwitterListCollection"/> instance.
+        /// </returns>
+        public static TwitterResponse<TwitterListCollection> GetMemberships(OAuthTokens tokens, string screenname)
+        {
+            return GetMemberships(tokens, screenname, null);
+        }
+
+        /// <summary>
+        /// List the lists the specified user has been added to.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="username">The userid.</param>
+        /// <param name="options">The options.</param>
+        /// <returns>
+        /// A <see cref="TwitterListCollection"/> instance.
+        /// </returns>
+        public static TwitterResponse<TwitterListCollection> GetMemberships(OAuthTokens tokens, decimal userid, ListMembershipsOptions options)
+        {
+            Commands.ListMembershipsCommand command = new Twitterizer.Commands.ListMembershipsCommand(tokens, userid, options);
+            return Core.CommandPerformer.PerformAction(command);
+        }
+
+        /// <summary>
+        /// List the lists the specified user has been added to.
+        /// </summary>
+        /// <param name="tokens">The tokens.</param>
+        /// <param name="username">The userid.</param>
         /// <returns>
         /// A <see cref="TwitterListCollection"/> instance.
         /// </returns>
-        public static TwitterResponse<TwitterListCollection> GetMemberships(OAuthTokens tokens, string username)
+        public static TwitterResponse<TwitterListCollection> GetMemberships(OAuthTokens tokens, decimal userid)
         {
-            return GetMemberships(tokens, username, null);
+            return GetMemberships(tokens, userid, null);
         }
 
         /// <summary>
diff --git a/lib/Twitterizer/Twitterizer2/Methods/List/UpdateListCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/List/UpdateListCommand.cs
index b14c82d..1963399 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/List/UpdateListCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/List/UpdateListCommand.cs
@@ -47,6 +47,7 @@ namespace Twitterizer.Commands
 #endif
     internal sealed class UpdateListCommand : TwitterCommand<TwitterList>
     {
+        private readonly string id;
         #region Constructors
         /// <summary>
         /// Initializes a new instance of the <see cref="UpdateListCommand"/> class.
@@ -71,6 +72,8 @@ namespace Twitterizer.Commands
             {
                 throw new ArgumentNullException("id");
             }
+
+            this.id = id;
         }
         #endregion
 
@@ -79,6 +82,9 @@ namespace Twitterizer.Commands
         /// </summary>
         public override void Init()
         {
+            if (!string.IsNullOrEmpty(id))
+                this.RequestParameters.Add("list_id", id);
+
             UpdateListOptions options = this.OptionalProperties as UpdateListOptions;
 
             if (options == null)
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Search/SearchCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Search/SearchCommand.cs
index aa5c533..775b31b 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Search/SearchCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Search/SearchCommand.cs
@@ -37,11 +37,8 @@ namespace Twitterizer.Commands
     using System;
     using System.Globalization;
     using Twitterizer;
-    using Twitterizer.Core;
+    using Core;
 
-    /// <summary>
-    /// The create list command class
-    /// </summary>
 #if !SILVERLIGHT
     [Serializable]
 #endif
@@ -57,7 +54,7 @@ namespace Twitterizer.Commands
         public SearchCommand(OAuthTokens requestTokens, string query, SearchOptions options)
             : base(HTTPVerb.GET, "search.json", requestTokens, options)
         {
-            if (string.IsNullOrEmpty(query) && options == null && string.IsNullOrEmpty(options.Locale))
+            if (string.IsNullOrEmpty(query))
             {
                 throw new ArgumentNullException("query");
             }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Search/SearchOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/Search/SearchOptions.cs
index b2c605a..6fdef2e 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Search/SearchOptions.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Search/SearchOptions.cs
@@ -73,7 +73,6 @@ namespace Twitterizer
         /// Initializes a new instance of the <see cref="SearchOptions"/> class.
         /// </summary>
         public SearchOptions()
-            : base()
         {
             this.APIBaseAddress = "http://search.twitter.com/";
         }
@@ -94,7 +93,7 @@ namespace Twitterizer
         /// Gets or sets the max id.
         /// </summary>
         /// <value>The max id.</value>
-        public long MaxId { get; set; }
+        public decimal MaxId { get; set; }
 
         /// <summary>
         /// Gets or sets the number per page.
@@ -118,7 +117,7 @@ namespace Twitterizer
         /// Gets or sets the since id.
         /// </summary>
         /// <value>The since id.</value>
-        public long SinceId { get; set; }
+        public decimal SinceId { get; set; }
 
         /// <summary>
         /// Gets or sets the geo code string. 
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Search/TwitterSearchResult.cs b/lib/Twitterizer/Twitterizer2/Methods/Search/TwitterSearchResult.cs
index 65a7e91..76702d5 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Search/TwitterSearchResult.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Search/TwitterSearchResult.cs
@@ -62,7 +62,14 @@ namespace Twitterizer
         public DateTime CreatedDate { get; set; }
 
         /// <summary>
-        /// Gets or sets the name of from user screen.
+        /// Gets or sets the display name of the from user.
+        /// </summary>
+        /// <value>The name of from user screen.</value>
+        [JsonProperty(PropertyName = "from_user_name")]
+        public string FromUserDisplayName { get; set; }
+
+        /// <summary>
+        /// Gets or sets the screen name of the from user.
         /// </summary>
         /// <value>The name of from user screen.</value>
         [JsonProperty(PropertyName = "from_user")]
@@ -73,10 +80,17 @@ namespace Twitterizer
         /// </summary>
         /// <value>From user id.</value>
         [JsonProperty(PropertyName = "from_user_id")]
-        public long? FromUserId { get; set; }
+        public decimal? FromUserId { get; set; }
+
+        /// <summary>
+        /// Gets or sets the display name of the to user.
+        /// </summary>
+        /// <value>The name of to user screen.</value>
+        [JsonProperty(PropertyName = "to_user_name")]
+        public string ToUserDisplayName { get; set; }
 
         /// <summary>
-        /// Gets or sets the name of to user screen.
+        /// Gets or sets the screen name of to user.
         /// </summary>
         /// <value>The name of to user screen.</value>
         [JsonProperty(PropertyName = "to_user")]
@@ -87,7 +101,7 @@ namespace Twitterizer
         /// </summary>
         /// <value>To user id.</value>
         [JsonProperty(PropertyName = "to_user_id")]
-        public long? ToUserId { get; set; }
+        public decimal? ToUserId { get; set; }
 
         /// <summary>
         /// Gets or sets the status text.
@@ -97,11 +111,21 @@ namespace Twitterizer
         public string Text { get; set; }
 
         /// <summary>
+        /// Returns the status text with HTML links to users, urls, and hashtags.
+        /// </summary>
+        /// <remarks>This will only work if you specify <see cref="SearchOptions.IncludeEntities"/> = <c>true</c> when executing the search.</remarks>
+        /// <returns></returns>
+        public string LinkifiedText()
+        {
+            return TwitterStatus.LinkifiedText(Entities, Text);
+        }
+
+        /// <summary>
         /// Gets or sets the status id.
         /// </summary>
         /// <value>The status id.</value>
         [JsonProperty(PropertyName = "id")]
-        public long Id { get; set; }
+        public decimal Id { get; set; }
 
         /// <summary>
         /// Gets or sets the source.
@@ -132,6 +156,13 @@ namespace Twitterizer
         public string Location { get; set; }
 
         /// <summary>
+        /// Gets or sets the status id the status is in reply to.
+        /// </summary>
+        /// <value>The status id.</value>
+        [DataMember, JsonProperty(PropertyName = "in_reply_to_status_id")]
+        public decimal? InReplyToStatusId { get; set; }
+
+        /// <summary>
         /// Gets or sets the entities.
         /// </summary>
         /// <value>The entities.</value>
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Spam/TwitterSpam.cs b/lib/Twitterizer/Twitterizer2/Methods/Spam/TwitterSpam.cs
index 7e3b6b6..8a90194 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Spam/TwitterSpam.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Spam/TwitterSpam.cs
@@ -85,7 +85,7 @@ namespace Twitterizer
         /// <returns>The user details.</returns>
         public static TwitterResponse<TwitterUser> ReportUser(OAuthTokens tokens, string screenName)
         {
-            return ReportUser(tokens, screenName);
+            return ReportUser(tokens, screenName, null);
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Timeline/FriendsTimelineCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Timeline/FriendsTimelineCommand.cs
index 762bd28..10eea19 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Timeline/FriendsTimelineCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Timeline/FriendsTimelineCommand.cs
@@ -34,14 +34,10 @@
 
 namespace Twitterizer.Commands
 {
-    using System;
-    using System.Globalization;
-    using Twitterizer.Core;
-
     /// <summary>
     /// The Friends Timeline Command class
     /// </summary>
-    internal sealed class FriendsTimelineCommand : PagedTimelineCommand<TwitterStatusCollection>
+    internal sealed class FriendsTimelineCommand : PagedTimelineCommand
     {
         #region Constructors
         /// <summary>
@@ -64,7 +60,7 @@ namespace Twitterizer.Commands
             if (options == null)
                 options = new TimelineOptions();
             
-            TimelineOptions.Init<TwitterStatusCollection>(this, options);
+            TimelineOptions.Init(this, options);
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Timeline/HomeTimelineCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Timeline/HomeTimelineCommand.cs
index 323fb3b..4424186 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Timeline/HomeTimelineCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Timeline/HomeTimelineCommand.cs
@@ -44,7 +44,7 @@ namespace Twitterizer.Commands
     [Serializable]
 #endif
     [AuthorizedCommandAttribute]
-    internal sealed class HomeTimelineCommand : PagedTimelineCommand<TwitterStatusCollection>
+    internal sealed class HomeTimelineCommand : PagedTimelineCommand
     {
         /// <summary>
         /// Initializes a new instance of the <see cref="HomeTimelineCommand"/> class.
@@ -69,7 +69,7 @@ namespace Twitterizer.Commands
             if (options == null)
                 options = new TimelineOptions();
 
-            TimelineOptions.Init<TwitterStatusCollection>(this, options);
+            TimelineOptions.Init(this, options);
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Timeline/MentionsCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Timeline/MentionsCommand.cs
index 88e64c0..6c7b08c 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Timeline/MentionsCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Timeline/MentionsCommand.cs
@@ -35,8 +35,7 @@
 namespace Twitterizer.Commands
 {
     using System;
-    using System.Globalization;
-    using Twitterizer.Core;
+    using Core;
 
     /// <summary>
     /// The Mentions Command class
@@ -45,7 +44,7 @@ namespace Twitterizer.Commands
 #if !SILVERLIGHT
     [Serializable]
 #endif
-    internal sealed class MentionsCommand : PagedTimelineCommand<TwitterStatusCollection>
+    internal sealed class MentionsCommand : PagedTimelineCommand
     {
         /// <summary>
         /// Initializes a new instance of the <see cref="MentionsCommand"/> class.
@@ -70,7 +69,7 @@ namespace Twitterizer.Commands
             if (options == null)
                 options = new TimelineOptions();
 
-            TimelineOptions.Init<TwitterStatusCollection>(this, options);
+            TimelineOptions.Init(this, options);
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Timeline/PagedTimelineCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Timeline/PagedTimelineCommand.cs
index 426da2b..d43b1fe 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Timeline/PagedTimelineCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Timeline/PagedTimelineCommand.cs
@@ -34,30 +34,25 @@
 
 namespace Twitterizer.Commands
 {
-    using System;
     using System.Globalization;
-    using Twitterizer.Core;
+    using Core;
 
     /// <summary>
     /// The Paged Timeline Command class. Provides common functionality for all of the paged timeline command classes.
     /// </summary>
-    /// <typeparam name="T"></typeparam>
 #if !SILVERLIGHT
-    [Serializable]
+    [System.Serializable]
 #endif
-    internal abstract class PagedTimelineCommand<T> : TwitterCommand<TwitterStatusCollection>
-        where T : ITwitterObject
+    internal abstract class PagedTimelineCommand : TwitterCommand<TwitterStatusCollection>
     {
-        private NumberFormatInfo numberFormat = CultureInfo.InvariantCulture.NumberFormat;
-
         /// <summary>
-        /// Initializes a new instance of the <see cref="PagedTimelineCommand<T>"/> class.
+        /// Initializes a new instance of the <see cref="PagedTimelineCommand"/> 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>
-        public PagedTimelineCommand(HTTPVerb httpMethod, string endPoint, OAuthTokens tokens, OptionalProperties optionalProperties)
+        protected PagedTimelineCommand(HTTPVerb httpMethod, string endPoint, OAuthTokens tokens, OptionalProperties optionalProperties)
             : base(httpMethod, endPoint, tokens, optionalProperties)
         {
         }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Timeline/RetweetedByMeCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Timeline/RetweetedByMeCommand.cs
index 04c1060..e9c8009 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Timeline/RetweetedByMeCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Timeline/RetweetedByMeCommand.cs
@@ -83,6 +83,8 @@ namespace Twitterizer.Commands
                 this.RequestParameters.Add("count", options.Count.ToString(CultureInfo.InvariantCulture));
 
             this.RequestParameters.Add("page", options.Page > 0 ? options.Page.ToString(CultureInfo.InvariantCulture) : "1");
+
+            this.RequestParameters.Add("include_entities", "true");
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Timeline/TimelineOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/Timeline/TimelineOptions.cs
index 4d32825..4279067 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Timeline/TimelineOptions.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Timeline/TimelineOptions.cs
@@ -46,7 +46,6 @@ namespace Twitterizer
         /// Initializes a new instance of the <see cref="TimelineOptions"/> class.
         /// </summary>
         public TimelineOptions()
-            : base()
         {
             this.Page = 1;
         }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Timeline/UserTimelineCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Timeline/UserTimelineCommand.cs
index 3846072..b5e068d 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Timeline/UserTimelineCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Timeline/UserTimelineCommand.cs
@@ -36,7 +36,6 @@ namespace Twitterizer.Commands
 {
     using System;
     using System.Globalization;
-    using Twitterizer.Core;
 
     /// <summary>
     /// The user timeline command.
@@ -44,8 +43,7 @@ namespace Twitterizer.Commands
 #if !SILVERLIGHT
     [Serializable]
 #endif
-    internal sealed class UserTimelineCommand :
-        PagedTimelineCommand<TwitterStatusCollection>
+    internal sealed class UserTimelineCommand : PagedTimelineCommand
     {
         /// <summary>
         /// Initializes a new instance of the <see cref="UserTimelineCommand"/> class.
@@ -75,7 +73,7 @@ namespace Twitterizer.Commands
             if (options == null)
                 options = new UserTimelineOptions();
 
-            TimelineOptions.Init<TwitterStatusCollection>(this, options);
+            TimelineOptions.Init(this, options);
             
             if (options.UserId > 0)
                 this.RequestParameters.Add("user_id", options.UserId.ToString(CultureInfo.InvariantCulture.NumberFormat));
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Trends/AvailableTrendsCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Trends/AvailableTrendsCommand.cs
new file mode 100644
index 0000000..c755650
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Trends/AvailableTrendsCommand.cs
@@ -0,0 +1,82 @@
+//-----------------------------------------------------------------------
+// <copyright file="AvailableTrendsCommand.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 available 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 AvailableTrendsCommand : TwitterCommand<TwitterTrendLocationCollection>
+    {
+        #region Constructors
+        /// <summary>
+        /// Initializes a new instance of the <see cref="AvailableTrendsCommand"/> class.
+        /// </summary>
+        /// <param name="tokens">The request tokens.</param>
+        /// <param name="options">The options.</param>
+        public AvailableTrendsCommand(OAuthTokens tokens, AvailableTrendsOptions options)
+            : base(
+                HTTPVerb.GET,
+                "trends/available.json",
+                tokens,
+                options)
+        {
+        }
+        #endregion
+
+
+        public override void Init()
+        {
+            AvailableTrendsOptions options = this.OptionalProperties as AvailableTrendsOptions;
+            if (options == null)
+            {
+                return;
+            }
+            
+            if (options.Lat != null)
+                this.RequestParameters.Add("lat", options.Lat.ToString());
+
+            if (options.Long != null)
+                this.RequestParameters.Add("long", options.Long.ToString());        
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Trends/AvailableTrendsOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/Trends/AvailableTrendsOptions.cs
new file mode 100644
index 0000000..e992dbd
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Trends/AvailableTrendsOptions.cs
@@ -0,0 +1,56 @@
+//-----------------------------------------------------------------------
+// <copyright file="AvailableTrendsOptions.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 available trends options class.</summary>
+//-----------------------------------------------------------------------
+
+namespace Twitterizer
+{
+    /// <summary>
+    /// The available trends options class. Provides a payload for optional parameters for the AvailableTrendsCommand class.
+    /// </summary>
+#if !SILVERLIGHT
+    [System.Serializable]
+#endif
+    public class AvailableTrendsOptions : OptionalProperties
+    {
+        /// <summary>
+        /// Gets or sets a value indicating how to order the list nearest to furthest.
+        /// </summary>        
+        public double? Lat { get; set; }
+
+        /// <summary>
+        /// Gets or sets a value indicating how to order the list nearest to furthest.
+        /// </summary>        
+        public double? Long { get; set; } 
+
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Trends/DailyTrendsCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Trends/DailyTrendsCommand.cs
new file mode 100644
index 0000000..0117bad
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Trends/DailyTrendsCommand.cs
@@ -0,0 +1,86 @@
+//-----------------------------------------------------------------------
+// <copyright file="DailyTrendsCommand.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 DailyTrendsCommand : TwitterCommand<TwitterTrendDictionary>
+    {
+        #region Constructors
+        /// <summary>
+        /// Initializes a new instance of the <see cref="TrendsCommand"/> class.
+        /// </summary>
+        /// <param name="tokens">The request tokens.</param>
+        /// <param name="options">The options.</param>
+        public DailyTrendsCommand(OAuthTokens tokens, TrendsOptions options)
+            : base(
+                HTTPVerb.GET,
+                "trends/daily.json",
+                tokens,
+                options)
+        {
+        }
+        #endregion
+
+        /// <summary>
+        /// Initializes the command.
+        /// </summary>
+        public override void Init()
+        {
+            TrendsOptions options = this.OptionalProperties as TrendsOptions;
+            if (options == null)
+            {
+                return;
+            }
+
+            if (!String.IsNullOrEmpty(options.Date))
+                this.RequestParameters.Add("date", options.Date);
+
+            if (options.ExcludeHashTags)
+            {
+                this.RequestParameters.Add("exclude", "hashtags");
+            }
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Trends/LocalTrendsOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/Trends/LocalTrendsOptions.cs
new file mode 100644
index 0000000..418b061
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Trends/LocalTrendsOptions.cs
@@ -0,0 +1,51 @@
+//-----------------------------------------------------------------------
+// <copyright file="LocalTrendsOptions.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 trends options class. Provides a payload for optional parameters for the TrendsCommand class.
+    /// </summary>
+#if !SILVERLIGHT
+    [System.Serializable]
+#endif
+    public class LocalTrendsOptions : 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
index 8a6b86a..e227c1b 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Trends/TrendsCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Trends/TrendsCommand.cs
@@ -51,13 +51,14 @@ namespace Twitterizer.Commands
         /// <summary>
         /// Initializes a new instance of the <see cref="TrendsCommand"/> class.
         /// </summary>
-        /// <param name="options">The WOEID.</param>
+        /// <param name="tokens">The request tokens.</param>
+        /// <param name="WOEID">The WOEID.</param>
         /// <param name="options">The options.</param>
-        public TrendsCommand(int WOEID, TrendsOptions options)
+        public TrendsCommand(OAuthTokens tokens, int WOEID, LocalTrendsOptions options)
             : base(
                 HTTPVerb.GET,
-                string.Format(CultureInfo.InvariantCulture, "trends/{0}.json", WOEID), 
-                null, 
+                string.Format(CultureInfo.InvariantCulture, "trends/{0}.json", WOEID),
+                tokens,
                 options)
         {
         }
@@ -68,7 +69,7 @@ namespace Twitterizer.Commands
         /// </summary>
         public override void Init()
         {
-            TrendsOptions options = this.OptionalProperties as TrendsOptions;
+            LocalTrendsOptions options = this.OptionalProperties as LocalTrendsOptions;
             if (options == null)
             {
                 return;
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Trends/TrendsOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/Trends/TrendsOptions.cs
index a434285..314922e 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Trends/TrendsOptions.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Trends/TrendsOptions.cs
@@ -29,23 +29,22 @@
 //  POSSIBILITY OF SUCH DAMAGE.
 // </copyright>
 // <author>Ricky Smith</author>
-// <summary>The trends options class.</summary>
+// <summary>The daily trends options class.</summary>
 //-----------------------------------------------------------------------
 
 namespace Twitterizer
 {
     /// <summary>
-    /// The current trends options class. Provides a payload for optional parameters for the CurrentTrendsCommand class.
+    /// The trends options class. Provides a payload for optional parameters for the TrendsCommand class.
     /// </summary>
 #if !SILVERLIGHT
     [System.Serializable]
 #endif
-    public class TrendsOptions : OptionalProperties
+    public class TrendsOptions : LocalTrendsOptions
     {
         /// <summary>
-        /// Gets or sets a value indicating whether [exclude hash tags].
+        /// Gets or sets a value indicating whether to set the start date of the returned trends (Format "yyyy-MM-dd")
         /// </summary>
-        /// <value><c>true</c> if [exclude hash tags]; otherwise, <c>false</c>.</value>
-        public bool ExcludeHashTags { get; set; } 
+        public string Date { get; set; } 
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrend.cs b/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrend.cs
index 701d23c..eea722f 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrend.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrend.cs
@@ -85,14 +85,15 @@ namespace Twitterizer
         /// <summary>
         /// Gets the trends with the specified WOEID.
         /// </summary>
-        /// <param name="options">The WOEID.</param>
+        /// <param name="tokens">The request tokens.</param>
+        /// <param name="WoeID">The WOEID.</param>
         /// <param name="options">The options.</param>
         /// <returns>
         /// A collection of <see cref="Twitterizer.TwitterTrend"/> objects.
         /// </returns>
-        public static TwitterResponse<TwitterTrendCollection> Trends(int WoeID, TrendsOptions options)
+        public static TwitterResponse<TwitterTrendCollection> Trends(OAuthTokens tokens, int WoeID, LocalTrendsOptions options)
         {
-            Commands.TrendsCommand command = new Twitterizer.Commands.TrendsCommand(WoeID, options);
+            Commands.TrendsCommand command = new Twitterizer.Commands.TrendsCommand(tokens, WoeID, options);
 
             return Core.CommandPerformer.PerformAction(command);
         }
@@ -100,13 +101,136 @@ namespace Twitterizer
         /// <summary>
         /// Gets the current trends.
         /// </summary>
-        /// <param name="options">The WOEID.</param>
+        /// <param name="tokens">The request tokens.</param>
+        /// <param name="WoeID">The WOEID.</param>
+        /// <returns>
+        /// A collection of <see cref="Twitterizer.TwitterTrend"/> objects.
+        /// </returns>
+        public static TwitterResponse<TwitterTrendCollection> Trends(OAuthTokens tokens, int WoeID)
+        {
+            return Trends(tokens, WoeID, null);
+        }
+
+        /// <summary>
+        /// Gets the trends with the specified WOEID.
+        /// </summary>
+        /// <param name="WoeID">The WOEID.</param>
+        /// <param name="options">The options.</param>
+        /// <returns>
+        /// A collection of <see cref="Twitterizer.TwitterTrend"/> objects.
+        /// </returns>
+        public static TwitterResponse<TwitterTrendCollection> Trends(int WoeID, LocalTrendsOptions options)
+        {
+            return Trends(null, WoeID, options);
+        }
+
+        /// <summary>
+        /// Gets the current trends.
+        /// </summary>
+        /// <param name="WoeID">The WOEID.</param>
         /// <returns>
         /// A collection of <see cref="Twitterizer.TwitterTrend"/> objects.
         /// </returns>
         public static TwitterResponse<TwitterTrendCollection> Trends(int WoeID)
         {
-            return Trends(WoeID, null);
+            return Trends(null, WoeID, null);
+        }
+
+        /// <summary>
+        /// Gets the locations where trends are available.
+        /// </summary>   
+        /// <param name="tokens">The request tokens.</param>
+        /// <param name="options">The options.</param>
+        /// <returns>
+        /// A collection of <see cref="Twitterizer.TwitterTrendLocation"/> objects.
+        /// </returns>
+        public static TwitterResponse<TwitterTrendLocationCollection> Available(OAuthTokens tokens, AvailableTrendsOptions options)
+        {
+            Commands.AvailableTrendsCommand command = new Twitterizer.Commands.AvailableTrendsCommand(tokens, options);
+
+            return Core.CommandPerformer.PerformAction(command);
+        }
+
+        /// <summary>
+        /// Gets the locations where trends are available.
+        /// </summary>          
+        /// <param name="options">The options.</param>
+        /// <returns>
+        /// A collection of <see cref="Twitterizer.TwitterTrendLocation"/> objects.
+        /// </returns>
+        public static TwitterResponse<TwitterTrendLocationCollection> Available(AvailableTrendsOptions options)
+        {
+            return Available(null, options);
+        }
+
+        /// <summary>
+        /// Gets the locations where trends are available.
+        /// </summary>          
+        /// <returns>
+        /// A collection of <see cref="Twitterizer.TwitterTrendLocation"/> objects.
+        /// </returns>
+        public static TwitterResponse<TwitterTrendLocationCollection> Available()
+        {
+            return Available(null, null);
+        }
+
+
+        /// <summary>
+        /// Gets the daily global trends
+        /// </summary>
+        /// <param name="tokens">The request tokens.</param>
+        /// <param name="options">The options.</param>
+        public static TwitterResponse<TwitterTrendDictionary> Daily(OAuthTokens tokens, TrendsOptions options)
+        {
+            Commands.DailyTrendsCommand command = new Twitterizer.Commands.DailyTrendsCommand(tokens, options);
+
+            return Core.CommandPerformer.PerformAction(command);
+        }
+
+        /// <summary>
+        /// Gets the daily global trends
+        /// </summary>
+        /// <param name="options">The options.</param>
+        public static TwitterResponse<TwitterTrendDictionary> Daily(TrendsOptions options)
+        {
+            return Daily(null, options);
+        }
+
+        /// <summary>
+        /// Gets the daily global trends
+        /// </summary>
+        public static TwitterResponse<TwitterTrendDictionary> Daily()
+        {
+            return Daily(null, null);
+        }
+
+        /// <summary>
+        /// Gets the weekly global trends
+        /// </summary>
+        /// <param name="tokens">The request tokens.</param>
+        /// <param name="options">The options.</param>
+        public static TwitterResponse<TwitterTrendDictionary> Weekly(OAuthTokens tokens, TrendsOptions options)
+        {
+            Commands.WeeklyTrendsCommand command = new Twitterizer.Commands.WeeklyTrendsCommand(tokens, options);
+
+            return Core.CommandPerformer.PerformAction(command);
+        }
+
+        /// <summary>
+        /// Gets the weekly global trends
+        /// </summary>
+        /// <param name="options">The options.</param>
+        public static TwitterResponse<TwitterTrendDictionary> Weekly(TrendsOptions options)
+        {
+            return Weekly(null, options);
+        }
+
+        /// <summary>
+        /// Gets the weekly global trends
+        /// </summary>
+        public static TwitterResponse<TwitterTrendDictionary> Weekly()
+        {
+            return Weekly(null, null);
         }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrendCollection.cs b/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrendCollection.cs
index cd00fc6..a4b14de 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrendCollection.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrendCollection.cs
@@ -47,15 +47,24 @@ namespace Twitterizer
     [Serializable]
 #endif
     public class TwitterTrendCollection : Core.TwitterCollection<TwitterTrend>, ITwitterObject
-    {        
+    {
+        /// <summary>
+        /// Gets or sets the as of date.
+        /// </summary>
         [JsonProperty(PropertyName = "as_of")]
         [JsonConverter(typeof(TwitterizerDateConverter))]
         public DateTime AsOf { get; set; }
 
+        /// <summary>
+        /// Gets or sets the created at date.
+        /// </summary>
         [JsonProperty(PropertyName = "created_at")]
         [JsonConverter(typeof(TwitterizerDateConverter))]
         public DateTime CreatedAt { get; set; }
-        
+
+        /// <summary>
+        /// Gets or sets the location.
+        /// </summary>
         public TwitterTrendLocationCollection Locations { get; set; }
         
         /// <summary>
@@ -96,13 +105,12 @@ namespace Twitterizer
 
                 int initialDepth = reader.Depth;
 
-                while (reader.Read() && reader.Depth >= initialDepth)
+                while (reader.Read() && reader.Depth > initialDepth)
                 {
-                    if (reader.TokenType == JsonToken.PropertyName && reader.Depth == 2)
+                    if (reader.TokenType == JsonToken.PropertyName && reader.Depth == initialDepth + 2)
                     {
                         switch ((string)reader.Value)
                         {
-#if !SILVERLIGHT
                             //TODO these two datetime converters don't seem to convert.
                             case "as_of":
                                 reader.Read();
@@ -115,7 +123,6 @@ namespace Twitterizer
                                 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();
@@ -123,7 +130,11 @@ namespace Twitterizer
                                 continue;
                         }
                     }
-                    if (reader.TokenType == JsonToken.StartObject && reader.Depth > 2)
+#if !SILVERLIGHT
+                    if (reader.TokenType == JsonToken.StartObject && reader.Depth > initialDepth + 1)
+#else
+                    if (reader.TokenType == JsonToken.StartObject && reader.Depth > initialDepth + 2)
+#endif
                         result.Add(new TwitterTrend());
 
                     if (reader.TokenType == JsonToken.PropertyName)
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrendDictionary.cs b/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrendDictionary.cs
new file mode 100644
index 0000000..68b633a
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrendDictionary.cs
@@ -0,0 +1,160 @@
+//-----------------------------------------------------------------------
+// <copyright file="TwitterTrendDictionary.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 trend collection class.</summary>
+//-----------------------------------------------------------------------
+
+using Twitterizer.Core;
+
+namespace Twitterizer
+{
+    using System;
+    using Newtonsoft.Json;
+    using System.Globalization;
+
+    /// <summary>
+    /// The TwitterTrendCollection class. Represents multiple <see cref="Twitterizer.TwitterTrend"/> elements.
+    /// </summary>
+    [JsonConverter(typeof(TwitterTrendDictionary.Converter))]
+#if !SILVERLIGHT
+    [Serializable]
+#endif
+    public class TwitterTrendDictionary : Core.TwitterDictionary<DateTime, TwitterTrendCollection>, ITwitterObject
+    {
+        /// <summary>
+        /// Gets or sets as of date.
+        /// </summary>
+        [JsonProperty(PropertyName = "as_of")]
+        [JsonConverter(typeof(TwitterizerDateConverter))]
+        public DateTime AsOf { 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.
+            /// </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(TwitterTrendDictionary);
+            }
+
+#if !SILVERLIGHT
+            static readonly string[] dateformats = { "yyyy-MM-dd HH:mm", "yyyy-MM-dd" };
+#endif
+
+            /// <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)
+            {
+                TwitterTrendDictionary result = existingValue as TwitterTrendDictionary;
+
+                if (result == null)
+                    result = new TwitterTrendDictionary();
+
+                int initialDepth = reader.Depth;
+
+                if (reader.TokenType == JsonToken.StartArray)
+                    reader.Read();
+
+                while (reader.Read() && reader.Depth > initialDepth)
+                {
+                    if (reader.TokenType == JsonToken.PropertyName && reader.Depth == 1)
+                    {
+#if !SILVERLIGHT
+                        switch ((string)reader.Value)
+                        {
+                            //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 "trends":
+                                reader.Read();
+                                while (reader.Read() && reader.Depth >= 3)
+                                {
+                                    if (reader.TokenType == JsonToken.PropertyName && reader.Depth == 3)
+                                    {
+                                        try
+                                        {
+                                            var date = DateTime.ParseExact(reader.Value.ToString(), dateformats, CultureInfo.InvariantCulture, DateTimeStyles.None);
+                                            result.Add(date, new TwitterTrendCollection());
+
+                                            var converter = new TwitterTrendCollection.Converter();
+                                            result[date] = (TwitterTrendCollection)converter.ReadJson(reader, typeof(TwitterTrendCollection), null, serializer);
+                                        }
+                                        catch
+                                        {
+                                            //bad date format
+                                            return null;
+                                        }
+                                    }
+                                }
+                                continue;
+                        }
+#endif
+                    }                    
+                }
+                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/Trends/TwitterTrendLocation.cs b/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrendLocation.cs
index 14ebc67..ed12bdd 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrendLocation.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrendLocation.cs
@@ -50,15 +50,43 @@ namespace Twitterizer
         /// <summary>
         /// Gets or sets the name.
         /// </summary>
-        /// <value>The name of the trend.</value>
+        /// <value>The name of the location.</value>
         [DataMember]
         public string Name { get; set; }
 
         /// <summary>
+        /// Gets or sets the place type.
+        /// </summary>
+        /// <value>The Place Type of the location.</value>
+        [DataMember]
+        public TwitterTrendLocationPlaceType PlaceType { get; set; }
+
+        /// <summary>
         /// Gets or sets the WOEID.
         /// </summary>
-        /// <value>The WOEID of the trend.</value>
+        /// <value>The WOEID of the location.</value>
         [DataMember]
         public int WOEID { get; set; }
+
+        /// <summary>
+        /// Gets or sets the Country.
+        /// </summary>
+        /// <value>The Country of the location.</value>
+        [DataMember]
+        public string Country { get; set; }
+
+        /// <summary>
+        /// Gets or sets the URL.
+        /// </summary>
+        /// <value>The URL of the location.</value>
+        [DataMember]
+        public string URL { get; set; }
+
+        /// <summary>
+        /// Gets or sets the Country Code.
+        /// </summary>
+        /// <value>The Country Code of the location.</value>
+        [DataMember]
+        public string CountryCode { get; set; }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrendLocationCollection.cs b/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrendLocationCollection.cs
index af8ad61..c20b058 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrendLocationCollection.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrendLocationCollection.cs
@@ -86,9 +86,9 @@ namespace Twitterizer
 
                 int initialDepth = reader.Depth;
 
-                while (reader.Read() && reader.Depth >= initialDepth)
+                while (reader.Read() && reader.Depth > initialDepth)
                 {
-                    if (reader.TokenType == JsonToken.StartObject && reader.Depth > 2)
+                    if (reader.TokenType == JsonToken.StartObject && reader.Depth >= 1)
                         result.Add(new TwitterTrendLocation());
 
                     if (reader.TokenType == JsonToken.PropertyName)
@@ -102,7 +102,45 @@ namespace Twitterizer
                             case "woeid":
                                 reader.Read();
                                 result[result.Count - 1].WOEID = int.Parse(reader.Value.ToString());
-                                continue;                            
+                                continue;
+
+                            case "placeType":
+                                int placetypeDepth = reader.Depth;
+                                while (reader.Read() && reader.Depth > placetypeDepth)
+                                {
+                                    if (reader.TokenType == JsonToken.StartObject && reader.Depth >= 2)
+                                        result[result.Count - 1].PlaceType = new TwitterTrendLocationPlaceType();
+
+                                    if (reader.TokenType == JsonToken.PropertyName)
+                                    {
+                                        switch ((string)reader.Value)
+                                        {
+                                            case "name":
+                                                reader.Read();
+                                                result[result.Count - 1].PlaceType.Name = (string)reader.Value;
+                                                continue;
+
+                                            case "code":
+                                                reader.Read();
+                                                result[result.Count - 1].PlaceType.Code = int.Parse(reader.Value.ToString());
+                                                continue;
+                                        }
+                                    }
+                                }
+                                continue;
+
+                            case "country":
+                                reader.Read();
+                                result[result.Count - 1].Country = (string)reader.Value;
+                                continue;
+                            case "url":
+                                reader.Read();
+                                result[result.Count - 1].URL = (string)reader.Value;
+                                continue;
+                            case "countryCode":
+                                reader.Read();
+                                result[result.Count - 1].CountryCode = (string)reader.Value;
+                                continue;  
                         }
                     }
                 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrendLocationPlaceType.cs b/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrendLocationPlaceType.cs
new file mode 100644
index 0000000..0c6e4b3
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Trends/TwitterTrendLocationPlaceType.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 TwitterTrendLocationPlaceType
+    {
+        /// <summary>
+        /// Gets or sets the name.
+        /// </summary>
+        /// <value>The name of the place type.</value>
+        [DataMember]
+        public string Name { get; set; }
+
+        /// <summary>
+        /// Gets or sets the code.
+        /// </summary>
+        /// <value>The code of the place type.</value>
+        [DataMember]
+        public int Code { get; set; }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Trends/WeeklyTrendsCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Trends/WeeklyTrendsCommand.cs
new file mode 100644
index 0000000..f520467
--- /dev/null
+++ b/lib/Twitterizer/Twitterizer2/Methods/Trends/WeeklyTrendsCommand.cs
@@ -0,0 +1,86 @@
+//-----------------------------------------------------------------------
+// <copyright file="WeeklyTrendsCommand.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 WeeklyTrendsCommand : TwitterCommand<TwitterTrendDictionary>
+    {
+        #region Constructors
+        /// <summary>
+        /// Initializes a new instance of the <see cref="WeeklyTrendsCommand"/> class.
+        /// </summary>
+        /// <param name="tokens">The request tokens.</param>
+        /// <param name="options">The options.</param>
+        public WeeklyTrendsCommand(OAuthTokens tokens, TrendsOptions options)
+            : base(
+                HTTPVerb.GET,
+                "trends/weekly.json",
+                tokens,
+                options)
+        {
+        }
+        #endregion
+
+        /// <summary>
+        /// Initializes the command.
+        /// </summary>
+        public override void Init()
+        {
+            TrendsOptions options = this.OptionalProperties as TrendsOptions;
+            if (options == null)
+            {
+                return;
+            }
+
+            if (!String.IsNullOrEmpty(options.Date))
+                this.RequestParameters.Add("date", options.Date);
+
+            if (options.ExcludeHashTags)
+            {
+                this.RequestParameters.Add("exclude", "hashtags");
+            }
+        }
+    }
+}
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterEntityCollection.cs b/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterEntityCollection.cs
index ad5f4e0..20dd5f2 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterEntityCollection.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterEntityCollection.cs
@@ -32,6 +32,8 @@
 // <summary>The twitter entity collection class</summary>
 //-----------------------------------------------------------------------
 
+using System.Collections.Generic;
+
 namespace Twitterizer.Entities
 {
     using System;
@@ -90,7 +92,10 @@ using System.Linq.Expressions;
                 TwitterEntity entity = null;
                 try
                 {
-                    while (reader.Read() && reader.Depth >= startDepth)
+                    if (reader.TokenType == JsonToken.StartArray)
+                        reader.Read();
+
+                    while (reader.Read() && reader.Depth > startDepth)
                     {
                         if (reader.TokenType == JsonToken.PropertyName && reader.Depth == startDepth + 1)
                         {
@@ -104,28 +109,37 @@ using System.Linq.Expressions;
                                 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);
-
+                                TwitterUrlEntity tue = entity as TwitterUrlEntity;
+                                if (tue != null)
+                                {
+                                    ReadFieldValue(reader, "url", entity, () => tue.Url);
+                                    ReadFieldValue(reader, "display_url", entity, () => tue.DisplayUrl);
+                                    ReadFieldValue(reader, "expanded_url", entity, () => tue.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);
-
+                                TwitterMentionEntity tme = entity as TwitterMentionEntity;
+                                if (tme != null)
+                                {
+                                    ReadFieldValue(reader, "screen_name", entity, () => tme.ScreenName);
+                                    ReadFieldValue(reader, "name", entity, () => tme.Name);
+                                    ReadFieldValue(reader, "id", entity, () => tme.UserId);
+                                }
                                 break;
 
                             case "hashtags":
                                 if (reader.TokenType == JsonToken.StartObject)
                                     entity = new TwitterHashTagEntity();
 
-                                ReadFieldValue(reader, "text", entity, () => ((TwitterHashTagEntity)entity).Text);
-
+                                TwitterHashTagEntity the = entity as TwitterHashTagEntity;
+                                if (the != null)
+                                {
+                                    ReadFieldValue(reader, "text", entity, () => the.Text);
+                                }
                                 break;
 
                             case "media":
@@ -134,9 +148,6 @@ using System.Linq.Expressions;
                                 entity = parseMediaEntity(reader);
 
                                 break;
-
-                            default:
-                                break;
                         }
 
                         // Read the indicies (for all entities except Media)
@@ -283,7 +294,7 @@ using System.Linq.Expressions;
             /// <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)
+            private static void WriteEntity<T>(JsonWriter writer, IEnumerable<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.
@@ -352,7 +363,7 @@ using System.Linq.Expressions;
                                 break;
 
                             case "sizes":
-                                entity.Sizes = new System.Collections.Generic.List<TwitterMediaEntity.MediaSize>();
+                                entity.Sizes = new List<TwitterMediaEntity.MediaSize>();
                                 break;
 
                             case "large":
@@ -470,30 +481,31 @@ using System.Linq.Expressions;
                 }
             }
 
-            private bool ReadFieldValue<TSource, TProperty>(JsonReader reader, string fieldName, TSource source, Expression<Func<TProperty>> property)
+            private void ReadFieldValue<TSource, TProperty>(JsonReader reader, string fieldName, TSource source, Expression<Func<TProperty>> property)
+                where TSource : class
             {
                 try
                 {
                     if (reader == null || source == null)
                     {
-                        return false;
+                        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))
+                    if (ReadFieldValue(reader, fieldName, ref value))
                     {
                         prop.SetValue(source, value, null);
-                        return true;
+                        return /*true*/;
                     }
 
-                    return false;
+                    return /*false*/;
                 }
                 catch
                 {
-                    return false;
+                    return /*false*/;
                 }
             }
         }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterHashTagEntity.cs b/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterHashTagEntity.cs
index ddafe35..3ddd203 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterHashTagEntity.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterHashTagEntity.cs
@@ -34,24 +34,15 @@
 
 namespace Twitterizer.Entities
 {
-    using System;
-
     /// <summary>
     /// Represents a pre-parsed hash tag in a <see cref="Twitterizer.TwitterStatus.Text"/> value.
     /// </summary>
 #if !SILVERLIGHT
-    [Serializable]
+    [System.Serializable]
 #endif
     public class TwitterHashTagEntity : TwitterEntity
     {
         /// <summary>
-        /// Initializes a new instance of the <see cref="TwitterHashTagEntity"/> class.
-        /// </summary>
-        public TwitterHashTagEntity()
-        { 
-        }
-
-        /// <summary>
         /// Gets or sets the hash tag text.
         /// </summary>
         /// <value>The hash tag text.</value>
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterMediaEntity.cs b/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterMediaEntity.cs
index 917d4c0..02a1812 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterMediaEntity.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterMediaEntity.cs
@@ -64,13 +64,6 @@ namespace Twitterizer.Entities
         }
 
         /// <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>
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterMentionEntity.cs b/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterMentionEntity.cs
index 5b95d92..3a073b4 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterMentionEntity.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterMentionEntity.cs
@@ -34,24 +34,15 @@
 
 namespace Twitterizer.Entities
 {
-    using System;
-
     /// <summary>
     /// Represents mention of a user within a <see cref="TwitterStatus.Text"/> value.
     /// </summary>
 #if !SILVERLIGHT
-    [Serializable]
+    [System.Serializable]
 #endif
     public class TwitterMentionEntity : TwitterEntity
     {
         /// <summary>
-        /// Initializes a new instance of the <see cref="TwitterMentionEntity"/> class.
-        /// </summary>
-        public TwitterMentionEntity()
-        {
-        }
-
-        /// <summary>
         /// Gets or sets the user's screen name.
         /// </summary>
         /// <value>The user's screen name.</value>
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterUrlEntity.cs b/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterUrlEntity.cs
index 23bbba6..15a8730 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterUrlEntity.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Tweets/Entities/TwitterUrlEntity.cs
@@ -34,24 +34,15 @@
 
 namespace Twitterizer.Entities
 {
-    using System;
-
     /// <summary>
     /// Represents a pre-parsed url located within the body of a <see cref="Twitterizer.TwitterStatus.Text"/>.
     /// </summary>
 #if !SILVERLIGHT
-    [Serializable]
+    [System.Serializable]
 #endif
     public class TwitterUrlEntity : TwitterEntity
     {
         /// <summary>
-        /// Initializes a new instance of the <see cref="TwitterUrlEntity"/> class.
-        /// </summary>
-        public TwitterUrlEntity()
-        {
-        }
-
-        /// <summary>
         /// Gets or sets the URL parsed from the tweet text.
         /// </summary>
         /// <value>The parsed URL.</value>
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Tweets/RetweetsOfMeCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Tweets/RetweetsOfMeCommand.cs
index 87c69f4..563eac3 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Tweets/RetweetsOfMeCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Tweets/RetweetsOfMeCommand.cs
@@ -71,7 +71,6 @@ namespace Twitterizer.Commands
 
             if (options == null)
             {
-                this.RequestParameters.Add("page", options.Page.ToString(CultureInfo.InvariantCulture));
                 return;
             }
 
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Tweets/StatusUpdateOptions.cs b/lib/Twitterizer/Twitterizer2/Methods/Tweets/StatusUpdateOptions.cs
index 06b4d3d..5f2b7b8 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Tweets/StatusUpdateOptions.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Tweets/StatusUpdateOptions.cs
@@ -34,25 +34,15 @@
 
 namespace Twitterizer
 {
-    using System;
-
     /// <summary>
     /// The Status Update Options class
     /// </summary>
 #if !SILVERLIGHT
-    [Serializable]
+    [System.Serializable]
 #endif
     public sealed class StatusUpdateOptions : OptionalProperties
     {
         /// <summary>
-        /// Initializes a new instance of the <see cref="StatusUpdateOptions"/> class.
-        /// </summary>
-        public StatusUpdateOptions()
-            : base()
-        {
-        }
-
-        /// <summary>
         /// Gets or sets the in reply to status id.
         /// </summary>
         /// <value>The in reply to status id.</value>
@@ -81,5 +71,12 @@ namespace Twitterizer
         /// </summary>
         /// <value>The place id.</value>
         public string PlaceId { get; set; }
+
+        /// <summary>
+        /// Gets or sets a value indicating whether links should be wrapped with Twitter's t.co link wrapper.
+        /// </summary>
+        /// <value><c>true</c> if [wrap links]; otherwise, <c>false</c>.</value>
+        /// <remarks>More information is available here: https://dev.twitter.com/docs/tco-link-wrapper/faq</remarks>
+        public bool WrapLinks { get; set; }
     }
 }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Tweets/TwitterStatus.cs b/lib/Twitterizer/Twitterizer2/Methods/Tweets/TwitterStatus.cs
index abc46d2..96aa0d2 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Tweets/TwitterStatus.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Tweets/TwitterStatus.cs
@@ -182,7 +182,7 @@ namespace Twitterizer
             {
                 if (string.IsNullOrEmpty(this.RetweetCountString)) return null;
 
-                int parsedResult = 0;
+                int parsedResult;
 
                 if (
                     this.RetweetCountString.EndsWith("+") &&
@@ -230,17 +230,19 @@ namespace Twitterizer
         /// <returns></returns>
         public string LinkifiedText()
         {
-            if (this.Entities == null || this.Entities.Count == 0)
+            return LinkifiedText(Entities, Text);
+        }
+
+        internal static string LinkifiedText(TwitterEntityCollection entities, string text)
+        {
+            if (entities == null || entities.Count == 0)
             {
-                return this.Text;
+                return text;
             }
 
-            string linkedText = this.Text;
+            string linkedText = text;
 
-            var entitiesSorted = this
-                                  .Entities
-                                  .OrderBy(e => e.StartIndex)
-                                  .Reverse();
+            var entitiesSorted = entities.OrderBy(e => e.StartIndex).Reverse();
 
             foreach (TwitterEntity entity in entitiesSorted)
             {
@@ -311,7 +313,7 @@ namespace Twitterizer
 		/// </summary>
 		/// <param name="tokens">The tokens.</param>
 		/// <param name="text">The status text.</param>
-		/// <param name="file">The file to upload.</param>
+		/// <param name="fileData">The file to upload, as a byte array.</param>
 		/// <param name="options">The options.</param>
 		/// <returns>
 		/// A <see cref="TwitterStatus"/> object of the newly created status.
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Tweets/UpdateStatusCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Tweets/UpdateStatusCommand.cs
index c0debc9..d887774 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Tweets/UpdateStatusCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Tweets/UpdateStatusCommand.cs
@@ -103,6 +103,9 @@ namespace Twitterizer.Commands
 
                 if (options.PlacePin)
                     this.RequestParameters.Add("display_coordinates", "true");
+
+                if (options.WrapLinks)
+                    this.RequestParameters.Add("wrap_links", "true");
             }
         }
     }
diff --git a/lib/Twitterizer/Twitterizer2/Methods/Tweets/UpdateWithmediaCommand.cs b/lib/Twitterizer/Twitterizer2/Methods/Tweets/UpdateWithmediaCommand.cs
index c9839de..3e587e2 100644
--- a/lib/Twitterizer/Twitterizer2/Methods/Tweets/UpdateWithmediaCommand.cs
+++ b/lib/Twitterizer/Twitterizer2/Methods/Tweets/UpdateWithmediaCommand.cs
@@ -64,7 +64,7 @@ namespace Twitterizer.Commands
 		/// </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="fileData">The file to upload, as a byte array.</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)
diff --git a/lib/Twitterizer/Twitterizer2/OAuth/OAuthUtility.cs b/lib/Twitterizer/Twitterizer2/OAuth/OAuthUtility.cs
index 3e8963a..3a1025e 100644
--- a/lib/Twitterizer/Twitterizer2/OAuth/OAuthUtility.cs
+++ b/lib/Twitterizer/Twitterizer2/OAuth/OAuthUtility.cs
@@ -75,8 +75,7 @@ namespace Twitterizer
             WebRequestBuilder builder = new WebRequestBuilder(
                 new Uri("https://api.twitter.com/oauth/request_token"),
                 HTTPVerb.POST,
-                new OAuthTokens { ConsumerKey = consumerKey, ConsumerSecret = consumerSecret },
-				"");
+                new OAuthTokens { ConsumerKey = consumerKey, ConsumerSecret = consumerSecret });
 
             if (!string.IsNullOrEmpty(callbackAddress))
             {
@@ -154,8 +153,7 @@ namespace Twitterizer
             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))
             {
@@ -217,8 +215,7 @@ 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 });
 
             if (!string.IsNullOrEmpty(verifier))
             {
@@ -280,8 +277,7 @@ 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;
 
@@ -349,39 +345,7 @@ namespace Twitterizer
             return new Uri(parameters.ToString());
         }
 
-        #if !LITE && !SILVERLIGHT
-        /// <summary>
-        /// Gets the access token during callback.
-        /// </summary>
-        /// <param name="consumerKey">The consumer key.</param>
-        /// <param name="consumerSecret">The consumer secret.</param>
-        /// <returns>
-        /// Access tokens returned by the Twitter API
-        /// </returns>
-        public static OAuthTokenResponse GetAccessTokenDuringCallback(string consumerKey, string consumerSecret)
-        {
-            HttpContext context = HttpContext.Current;
-            if (context == null || context.Request == null)
-            {
-                throw new ApplicationException("Could not located the HTTP context. GetAccessTokenDuringCallback can only be used in ASP.NET applications.");
-            }
-
-            string requestToken = context.Request.QueryString["oauth_token"];
-            string verifier = context.Request.QueryString["oauth_verifier"];
-
-            if (string.IsNullOrEmpty(requestToken))
-            {
-                throw new ApplicationException("Could not locate the request token.");
-            }
-
-            if (string.IsNullOrEmpty(verifier))
-            {
-                throw new ApplicationException("Could not locate the verifier value.");
-            }
-
-            return GetAccessToken(consumerKey, consumerSecret, requestToken, verifier);
-        }
-
+#if !LITE && !SILVERLIGHT
         /// <summary>
         /// Adds the OAuth Echo header to the supplied web request.
         /// </summary>
@@ -392,8 +356,7 @@ namespace Twitterizer
             WebRequestBuilder builder = new WebRequestBuilder(
                 new Uri("https://api.twitter.com/1/account/verify_credentials.json"), 
                 HTTPVerb.POST,
-				tokens,
-				"");
+				tokens);
 
             builder.PrepareRequest();
 
diff --git a/lib/Twitterizer/Twitterizer2/OAuth/WebRequestBuilder.cs b/lib/Twitterizer/Twitterizer2/OAuth/WebRequestBuilder.cs
index a1f1c5b..cfd9e32 100644
--- a/lib/Twitterizer/Twitterizer2/OAuth/WebRequestBuilder.cs
+++ b/lib/Twitterizer/Twitterizer2/OAuth/WebRequestBuilder.cs
@@ -77,12 +77,12 @@ namespace Twitterizer
         /// <summary>
         /// Holds file data form performing multipart form posts.
         /// </summary>
-        private byte[] formData = null;
+        private byte[] formData;
 
         /// <summary>
         /// The HTTP Authorization realm.
         /// </summary>
-        public string Realm = "Twitter API";
+        public const string Realm = "Twitter API";
 
         /// <summary>
         /// Gets or sets the request URI.
@@ -112,19 +112,25 @@ namespace Twitterizer
         /// Gets or sets the UserAgent.
         /// </summary>
         /// <value>The User Agent.</value>
-        public String UserAgent { private get; set; }
+        private string userAgent;
 
         /// <summary>
         /// Gets or sets the Basic Auth Credentials.
         /// </summary>
         /// <value>The Basic Auth Credentials.</value>
-		public NetworkCredential NetworkCredentials { private get; set; }
+        private NetworkCredential networkCredentials;
 
-		/// <summary>
-		/// Gets or sets the Multipart config
-		/// </summary>
-		/// <value>Multipart</value>
-		public bool Multipart { get; set; }
+        /// <summary>
+        /// Gets or sets the Multipart config
+        /// </summary>
+        /// <value>Multipart</value>
+        public bool Multipart { get; set; }
+
+        /// <summary>
+        /// Gets or sets whether to use accept compression on this request
+        /// </summary>
+        /// <value>UseCompression</value>
+        public bool UseCompression { get; set; }
 
 #if !SILVERLIGHT
         /// <summary>
@@ -171,21 +177,20 @@ namespace Twitterizer
         /// </summary>
         /// <param name="requestUri">The request URI.</param>
         /// <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>
+        /// <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)
+        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.userAgent = userAgent;
             this.UseOAuth = false;
-            if (NetworkCredentials != null)
-                this.NetworkCredentials = NetworkCredentials;
+            if (networkCredentials != null)
+                this.networkCredentials = networkCredentials;
 
 			this.Parameters = new Dictionary<string, object>();
 
@@ -205,10 +210,9 @@ namespace Twitterizer
         /// <param name="requestUri">The request URI.</param>
         /// <param name="verb">The verb.</param>
         /// <param name="tokens">The tokens.</param>
-        /// <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)
+        /// <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;
 
@@ -242,7 +246,7 @@ namespace Twitterizer
             request.AllowReadStreamBuffering = true;
             HttpWebResponse response = null;
             AutoResetEvent alldone = new AutoResetEvent(false);
-            IAsyncResult asyncResult = request.BeginGetResponse(new AsyncCallback((param) => 
+            request.BeginGetResponse(param =>
             {
                 HttpWebRequest req = (HttpWebRequest)param.AsyncState;
                 try
@@ -257,7 +261,7 @@ namespace Twitterizer
                 {
                     alldone.Set();
                 }
-            }), request);
+            }, request);
             alldone.WaitOne();
             return response;
 #endif
@@ -275,7 +279,7 @@ namespace Twitterizer
 			string contentType = string.Empty;
 
 			if (!Multipart)
-			{	//We don't add the paramters to the query if we are multipart-ing
+			{	//We don't add the parameters to the query if we are multipart-ing
 				AddQueryStringParametersToUri();
 			}
 			else
@@ -287,19 +291,30 @@ namespace Twitterizer
 
 				this.Verb = HTTPVerb.POST;
 			}
+
+            HttpWebRequest request;
 #if SILVERLIGHT
-            WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);
-            WebRequest.RegisterPrefix("https://", WebRequestCreator.ClientHttp);
-#endif
-            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(this.RequestUri);
+            request = (HttpWebRequest)WebRequestCreator.ClientHttp.Create(this.RequestUri);
+            
+            if (this.RequestUri.Host.Contains("search.twitter.com") || this.RequestUri.Host.Contains("api.twitter.com")) //-- DG HACK FOR TWITTER QUERIES TO FIX BAD COOKIE DOMAIN= DATA BEING RETURNED FROM TWITTER.
+            {
+                request.CookieContainer = new CookieContainer();
+                request.CookieContainer.Add(this.RequestUri, new Cookie("k", "Twitterizer hack for bad twitter cookie"));
+            }
+#else
+            request = (HttpWebRequest)WebRequest.Create(this.RequestUri);
+            
+            if (this.UseCompression == true)
+                request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
+            else
+                request.AutomaticDecompression = DecompressionMethods.None;
 
-#if !SILVERLIGHT
             if (this.Proxy != null)
                 request.Proxy = Proxy;
 #endif
-            if (!this.UseOAuth && this.NetworkCredentials != null)
+            if (!this.UseOAuth && this.networkCredentials != null)
             {
-                request.Credentials = this.NetworkCredentials;
+                request.Credentials = this.networkCredentials;
                 request.UseDefaultCredentials = false;
             }
             else
@@ -309,11 +324,10 @@ namespace Twitterizer
 
             request.Method = this.Verb.ToString();
 
-			request.ContentLength = Multipart ? formData.Length : 0;
-
+			request.ContentLength = Multipart ? ((formData != null) ? formData.Length: 0) : 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.UserAgent = (string.IsNullOrEmpty(userAgent)) ? string.Format(CultureInfo.InvariantCulture, "Twitterizer/{0}", System.Reflection.Assembly.GetExecutingAssembly().GetName().Version) : userAgent;
             
             request.ServicePoint.Expect100Continue = false;
 #endif
@@ -336,7 +350,7 @@ namespace Twitterizer
                 using (Stream requestStream = request.GetRequestStream())
 #else
                 IAsyncResult getRequestStreamResult = request.BeginGetRequestStream(
-                    (res) =>
+                    res =>
                     {
 
                     }, null);
@@ -344,7 +358,10 @@ namespace Twitterizer
                 using (Stream requestStream = request.EndGetRequestStream(getRequestStreamResult))
 #endif
                 {
-                    requestStream.Write(formData, 0, formData.Length);
+                    if (formData != null)
+                    {
+                        requestStream.Write(formData, 0, formData.Length);
+                    }
                 }
 			}
 
@@ -363,11 +380,11 @@ namespace Twitterizer
 			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)
+            foreach (KeyValuePair<string, object> item in fieldsToInclude)
             {
-				if( item.Value.GetType() == typeof(string) )
-					requestParametersBuilder.AppendFormat("{0}={1}&", item.Key, UrlEncode(item.Value as string));
-            }
+                if (item.Value is string)
+                    requestParametersBuilder.AppendFormat("{0}={1}&", item.Key, UrlEncode((string)item.Value));
+            }        
 
             if (requestParametersBuilder.Length == 0)
                 return;
@@ -389,13 +406,16 @@ namespace Twitterizer
 			{
 				if (kvp.Value.GetType() == typeof(byte[]))
 				{	//assume this to be a byte stream
-					byte[] data = kvp.Value as byte[];
+                    byte[] data = (byte[])kvp.Value;
 
 					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);
+
+                    byte[] headerBytes = encoding.GetBytes(header);
+
+                    formDataStream.Write(headerBytes, 0, headerBytes.Length);
 					formDataStream.Write(data, 0, data.Length);
 				}
 				else
@@ -404,7 +424,10 @@ namespace Twitterizer
 						boundary,
 						kvp.Key,
 						kvp.Value);
-					formDataStream.Write(encoding.GetBytes(header), 0, header.Length);
+
+                    byte[] headerBytes = encoding.GetBytes(header);
+
+                    formDataStream.Write(headerBytes, 0, headerBytes.Length);
 				}
 			}
 
@@ -423,7 +446,7 @@ namespace Twitterizer
         /// <summary>
         /// Sets up the OAuth request details.
         /// </summary>
-        public void SetupOAuth()
+        private void SetupOAuth()
         {
             // We only sign oauth requests
             if (!this.UseOAuth)
@@ -461,7 +484,7 @@ namespace Twitterizer
         /// <returns></returns>
         public string GenerateSignature()
         {
-			IEnumerable<KeyValuePair<string, object>> nonSecretParameters = null;
+			IEnumerable<KeyValuePair<string, object>> nonSecretParameters;
 
 			if (Multipart)
 			{
@@ -587,18 +610,20 @@ namespace Twitterizer
 
             foreach (var item in paramsSorted)
             {
-                if (parameterString.Length > 0)
+                if (item.Value is string)
                 {
-                    parameterString.Append("&");
+                    if (parameterString.Length > 0)
+                    {
+                        parameterString.Append("&");
+                    }
+
+                    parameterString.Append(
+                        string.Format(
+                            CultureInfo.InvariantCulture,
+                            "{0}={1}",
+                            UrlEncode(item.Key),
+                            UrlEncode((string)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());
@@ -611,11 +636,11 @@ namespace Twitterizer
         public string GenerateAuthorizationHeader()
         {
             StringBuilder authHeaderBuilder = new StringBuilder();
-            authHeaderBuilder.AppendFormat("OAuth realm=\"\"", Realm);
+            authHeaderBuilder.AppendFormat("OAuth realm=\"{0}\"", Realm);
 
             var sortedParameters = from p in this.Parameters
                                    where OAuthParametersToIncludeInHeader.Contains(p.Key)
-                                   orderby p.Key, UrlEncode( (p.Value.GetType() == typeof(string) )? p.Value as string : "")
+                                   orderby p.Key, UrlEncode( (p.Value is string) ? (string)p.Value : string.Empty)
                                    select p;
 
             foreach (var item in sortedParameters)
diff --git a/lib/Twitterizer/Twitterizer2/OAuth/XAuthUtility.cs b/lib/Twitterizer/Twitterizer2/OAuth/XAuthUtility.cs
index e6b99dc..f7707d0 100644
--- a/lib/Twitterizer/Twitterizer2/OAuth/XAuthUtility.cs
+++ b/lib/Twitterizer/Twitterizer2/OAuth/XAuthUtility.cs
@@ -84,8 +84,7 @@ 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);
diff --git a/lib/Twitterizer/Twitterizer2/TwitterResponse.cs b/lib/Twitterizer/Twitterizer2/TwitterResponse.cs
index f178a4f..56671df 100644
--- a/lib/Twitterizer/Twitterizer2/TwitterResponse.cs
+++ b/lib/Twitterizer/Twitterizer2/TwitterResponse.cs
@@ -49,12 +49,6 @@ namespace Twitterizer
         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>
diff --git a/lib/Twitterizer/Twitterizer2/Twitterizer2.csproj b/lib/Twitterizer/Twitterizer2/Twitterizer2.csproj
index a726cb1..d77171c 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 DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@@ -11,6 +11,7 @@
     <RootNamespace>Twitterizer</RootNamespace>
     <AssemblyName>Twitterizer2</AssemblyName>
     <FileAlignment>512</FileAlignment>
+    <SignAssembly>false</SignAssembly>
     <AssemblyOriginatorKeyFile>Twitterizer2.snk</AssemblyOriginatorKeyFile>
     <FileUpgradeFlags>
     </FileUpgradeFlags>
@@ -31,26 +32,28 @@
     <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
     <UseApplicationTrust>false</UseApplicationTrust>
     <BootstrapperEnabled>true</BootstrapperEnabled>
+    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\twitterizer\</SolutionDir>
+    <RestorePackages>true</RestorePackages>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>
     <DebugType>full</DebugType>
     <Optimize>false</Optimize>
-    <OutputPath>bin\Debug\</OutputPath>
+    <OutputPath>..\Debug\Twitterizer2\Full\</OutputPath>
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
-    <DocumentationFile>bin\Debug\Twitterizer2.XML</DocumentationFile>
+    <DocumentationFile>..\Debug\Twitterizer2\Full\Twitterizer2.XML</DocumentationFile>
     <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
     <DebugType>pdbonly</DebugType>
     <Optimize>true</Optimize>
-    <OutputPath>..\Release\Twitterizer2\</OutputPath>
+    <OutputPath>..\Release\net40\</OutputPath>
     <DefineConstants>TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
-    <DocumentationFile>..\Release\Twitterizer2.XML</DocumentationFile>
+    <DocumentationFile>..\Release\net40\Twitterizer2.XML</DocumentationFile>
     <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Mono-Debug|AnyCPU' ">
@@ -62,8 +65,6 @@
     <PlatformTarget>AnyCPU</PlatformTarget>
     <ErrorReport>prompt</ErrorReport>
     <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-    <WarningLevel>4</WarningLevel>
-    <Optimize>false</Optimize>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Mono-Release|AnyCPU' ">
     <OutputPath>bin\Mono-Release\</OutputPath>
@@ -75,7 +76,6 @@
     <PlatformTarget>AnyCPU</PlatformTarget>
     <ErrorReport>prompt</ErrorReport>
     <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-    <WarningLevel>4</WarningLevel>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'CCNET|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>
@@ -86,8 +86,6 @@
     <PlatformTarget>AnyCPU</PlatformTarget>
     <ErrorReport>prompt</ErrorReport>
     <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-    <WarningLevel>4</WarningLevel>
-    <Optimize>false</Optimize>
   </PropertyGroup>
   <PropertyGroup>
     <RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
@@ -96,7 +94,6 @@
     <Reference Include="System" />
     <Reference Include="System.Drawing" />
     <Reference Include="System.Runtime.Serialization" />
-    <Reference Include="System.Web" />
     <Reference Include="System.Xml" />
     <Reference Include="System.Configuration" />
     <Reference Include="System.Core" />
@@ -107,6 +104,7 @@
     </Compile>
     <Compile Include="Attributes\RateLimitedAttribute.cs" />
     <Compile Include="Attributes\AuthorizedCommandAttribute.cs" />
+    <Compile Include="Core\TwitterDictionary.cs" />
     <Compile Include="Core\RequestResult.cs" />
     <Compile Include="Core\TwitterCursorPagedIdCollection.cs" />
     <Compile Include="Core\ITwitterObject.cs">
@@ -147,6 +145,10 @@
     <Compile Include="Methods\Favorites\ListFavoritesCommand.cs" />
     <Compile Include="Methods\Favorites\ListFavoritesOptions.cs" />
     <Compile Include="Methods\Favorites\TwitterFavorite.cs" />
+    <Compile Include="Methods\Friendship\UpdateFriendshipOptions.cs" />
+    <Compile Include="Methods\Friendship\UpdateFriendshipCommand.cs" />
+    <Compile Include="Methods\Friendship\NoRetweetIDsCommand.cs" />
+    <Compile Include="Methods\Friendship\TwitterRelationship.cs" />
     <Compile Include="Methods\Friendship\OutgoingFriendshipsCommand.cs" />
     <Compile Include="Methods\Friendship\OutgoingFriendshipsOptions.cs" />
     <Compile Include="Methods\Friendship\FriendsIdsCommand.cs" />
@@ -194,10 +196,17 @@
     <Compile Include="Methods\Spam\TwitterSpam.cs" />
     <Compile Include="Methods\Timeline\PagedTimelineCommand.cs" />
     <Compile Include="Methods\Timeline\UserTimelineOptions.cs" />
+    <Compile Include="Methods\Trends\AvailableTrendsCommand.cs" />
+    <Compile Include="Methods\Trends\AvailableTrendsOptions.cs" />
+    <Compile Include="Methods\Trends\WeeklyTrendsCommand.cs" />
+    <Compile Include="Methods\Trends\DailyTrendsCommand.cs" />
+    <Compile Include="Methods\Trends\TrendsOptions.cs" />
+    <Compile Include="Methods\Trends\TwitterTrendDictionary.cs" />
+    <Compile Include="Methods\Trends\TwitterTrendLocationPlaceType.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\Trends\LocalTrendsOptions.cs" />
     <Compile Include="Methods\Search\SearchCommand.cs" />
     <Compile Include="Methods\Timeline\TimelineOptions.cs" />
     <Compile Include="Methods\Timeline\TwitterTimeline.cs" />
@@ -272,7 +281,7 @@
     <Compile Include="Methods\List\TwitterList.cs" />
     <Compile Include="Methods\List\TwitterListCollection.cs" />
     <Compile Include="Methods\Account\TwitterRateLimitStatus.cs" />
-    <Compile Include="Methods\Friendship\TwitterRelationship.cs" />
+    <Compile Include="Methods\Friendship\TwitterRelationshipUser.cs" />
     <Compile Include="Methods\TwitterResultTypeEnum.cs" />
     <Compile Include="Methods\Search\TwitterSearch.cs" />
     <Compile Include="Methods\Search\TwitterSearchResult.cs" />
@@ -328,10 +337,6 @@
       <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>
@@ -357,4 +362,4 @@
       <Name>Newtonsoft.Json</Name>
     </ProjectReference>
   </ItemGroup>
-</Project>
+</Project>
\ No newline at end of file
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
deleted file mode 100644
index 6b7e3fc..0000000
--- a/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation-2008.csproj
+++ /dev/null
@@ -1,117 +0,0 @@
-<?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
deleted file mode 100644
index c40e3ee..0000000
--- a/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/CallingConvention.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-/* 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
deleted file mode 100644
index 9045045..0000000
--- a/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/IFieldRef.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-/* 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
deleted file mode 100644
index bcc24f8..0000000
--- a/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/IMethodBuilder.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-/* 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
deleted file mode 100644
index 837a7a2..0000000
--- a/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/IMethodRef.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-/* 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
deleted file mode 100644
index 34e9f4e..0000000
--- a/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/INativeClassFactory.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-/* 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
deleted file mode 100644
index 412ba4d..0000000
--- a/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/IReferenceProvider.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-/* 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
deleted file mode 100644
index 02b98e8..0000000
--- a/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/IReferenceResolver.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-/* 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
deleted file mode 100644
index 8787208..0000000
--- a/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/ITypeEditor.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-/* 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
deleted file mode 100644
index 6f5f2d2..0000000
--- a/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/ITypeRef.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-/* 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
deleted file mode 100644
index d6ccede..0000000
--- a/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Api/InstrumentationException.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-/* 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
deleted file mode 100644
index a9ff4d2..0000000
--- a/lib/db4o-net/Db4objects.Db4o.Instrumentation/Db4objects.Db4o.Instrumentation/Core/DefaultNativeClassFactory.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-/* 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
deleted file mode 100755
index 3fc2e75..0000000
--- a/lib/db4o-net/Db4objects.Db4o.Instrumentation/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-/* 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
deleted file mode 100755
index 9f4858a..0000000
--- a/lib/db4o-net/Db4objects.Db4o.Instrumentation/native/Db4objects.Db4o.Instrumentation/Cecil/CecilFieldRef.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-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
deleted file mode 100755
index 5bccebc..0000000
--- a/lib/db4o-net/Db4objects.Db4o.Instrumentation/native/Db4objects.Db4o.Instrumentation/Cecil/CecilMethodBuilder.cs
+++ /dev/null
@@ -1,147 +0,0 @@
-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
deleted file mode 100755
index 6cbb689..0000000
--- a/lib/db4o-net/Db4objects.Db4o.Instrumentation/native/Db4objects.Db4o.Instrumentation/Cecil/CecilMethodRef.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-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
deleted file mode 100755
index da1a3ae..0000000
--- a/lib/db4o-net/Db4objects.Db4o.Instrumentation/native/Db4objects.Db4o.Instrumentation/Cecil/CecilRef.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-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
deleted file mode 100755
index 963105b..0000000
--- a/lib/db4o-net/Db4objects.Db4o.Instrumentation/native/Db4objects.Db4o.Instrumentation/Cecil/CecilReferenceProvider.cs
+++ /dev/null
@@ -1,72 +0,0 @@
-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
deleted file mode 100755
index f72bb46..0000000
--- a/lib/db4o-net/Db4objects.Db4o.Instrumentation/native/Db4objects.Db4o.Instrumentation/Cecil/CecilReferenceResolver.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-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
deleted file mode 100755
index 1484d6c..0000000
--- a/lib/db4o-net/Db4objects.Db4o.Instrumentation/native/Db4objects.Db4o.Instrumentation/Cecil/CecilTypeEditor.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-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
deleted file mode 100755
index 8e71af6..0000000
--- a/lib/db4o-net/Db4objects.Db4o.Instrumentation/native/Db4objects.Db4o.Instrumentation/Cecil/CecilTypeRef.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-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
deleted file mode 100644
index 120f635..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries-2008.csproj
+++ /dev/null
@@ -1,142 +0,0 @@
-<?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
deleted file mode 100644
index d408377..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/AndExpression.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-/* 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
deleted file mode 100644
index 2396655..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/BinaryExpression.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-/* 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
deleted file mode 100644
index 64f26c7..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/BoolConstExpression.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-/* 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
deleted file mode 100644
index 0acb140..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Build/ExpressionBuilder.cs
+++ /dev/null
@@ -1,198 +0,0 @@
-/* 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
deleted file mode 100644
index cfb0fe1..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/ArithmeticOperator.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-/* 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
deleted file mode 100644
index 9330332..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/ComparisonOperator.cs
+++ /dev/null
@@ -1,78 +0,0 @@
-/* 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
deleted file mode 100644
index 0ff045a..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/ArithmeticExpression.cs
+++ /dev/null
@@ -1,73 +0,0 @@
-/* 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
deleted file mode 100644
index 46e729d..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/ArrayAccessValue.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-/* 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
deleted file mode 100644
index ba1e0c8..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/CandidateFieldRoot.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-/* 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
deleted file mode 100644
index 1ee9e5e..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/ComparisonOperandDescendant.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-/* 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
deleted file mode 100644
index 8e94198..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/ComparisonOperandRoot.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-/* 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
deleted file mode 100644
index c87a7f3..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/ConstValue.cs
+++ /dev/null
@@ -1,72 +0,0 @@
-/* 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
deleted file mode 100644
index 86b8e85..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/FieldValue.cs
+++ /dev/null
@@ -1,64 +0,0 @@
-/* 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
deleted file mode 100644
index e6311f3..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/IComparisonOperand.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-/* 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
deleted file mode 100644
index dc85e70..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/IComparisonOperandAnchor.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-/* 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
deleted file mode 100644
index 0dbdcd8..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/IComparisonOperandVisitor.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-/* 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
deleted file mode 100644
index 170e028..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/MethodCallValue.cs
+++ /dev/null
@@ -1,89 +0,0 @@
-/* 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
deleted file mode 100644
index 5951433..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/PredicateFieldRoot.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-/* 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
deleted file mode 100644
index 564d3fb..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/StaticFieldRoot.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-/* 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
deleted file mode 100644
index 1f86800..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/Cmp/Operand/ThreeWayComparison.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-/* 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
deleted file mode 100644
index 0760629..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/ComparisonExpression.cs
+++ /dev/null
@@ -1,76 +0,0 @@
-/* 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
deleted file mode 100644
index dcee3c2..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/IExpression.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-/* 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
deleted file mode 100644
index ac46943..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/IExpressionPart.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-/* 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
deleted file mode 100644
index eeb379b..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/IExpressionVisitor.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-/* 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
deleted file mode 100644
index b45b276..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/IgnoredExpression.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-/* 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
deleted file mode 100644
index 9c64e79..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/NotExpression.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-/* 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
deleted file mode 100644
index c6176ae..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/OrExpression.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-/* 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
deleted file mode 100644
index 0b25f12..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Expr/TraversingExpressionVisitor.cs
+++ /dev/null
@@ -1,85 +0,0 @@
-/* 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
deleted file mode 100644
index b6f6326..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Instrumentation/ComparisonBytecodeGeneratingVisitor.cs
+++ /dev/null
@@ -1,243 +0,0 @@
-/* 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
deleted file mode 100644
index c0090f6..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Instrumentation/SODAMethodBuilder.cs
+++ /dev/null
@@ -1,250 +0,0 @@
-/* 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
deleted file mode 100644
index 471d580..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Instrumentation/TypeDeducingVisitor.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-/* 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
deleted file mode 100644
index 536baab..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Optimization/ComparisonQueryGeneratingVisitor.cs
+++ /dev/null
@@ -1,224 +0,0 @@
-/* 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
deleted file mode 100644
index d4df5ad..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Db4objects.Db4o.NativeQueries/Optimization/SODAQueryBuilder.cs
+++ /dev/null
@@ -1,143 +0,0 @@
-/* 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
deleted file mode 100755
index 88e5f1b..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-/* 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
deleted file mode 100644
index d7e1ed6..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/native/Db4objects.Db4o.NativeQueries/AssemblyResolver.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-/* 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
deleted file mode 100644
index 5a8c2e8..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/native/Db4objects.Db4o.NativeQueries/ICachingStrategy.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-/* 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
deleted file mode 100755
index 7f77fe5..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/native/Db4objects.Db4o.NativeQueries/NQOptimizer.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-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
deleted file mode 100755
index ad4321f..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/native/Db4objects.Db4o.NativeQueries/Optimization/NativeQueriesPlatform.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-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
deleted file mode 100644
index e3da254..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/native/Db4objects.Db4o.NativeQueries/QueryExpressionBuilder.cs
+++ /dev/null
@@ -1,916 +0,0 @@
-/* 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
deleted file mode 100644
index eb70b65..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/native/Db4objects.Db4o.NativeQueries/SingleItemCachingStrategy.cs
+++ /dev/null
@@ -1,66 +0,0 @@
-/* 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
deleted file mode 100644
index f648282..0000000
--- a/lib/db4o-net/Db4objects.Db4o.NativeQueries/native/Db4objects.Db4o.NativeQueries/UnsupportedPredicateException.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-/* 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/jabber-net/jabber/client/RosterManager.cs b/lib/jabber-net/jabber/client/RosterManager.cs
index 5715848..5b1df37 100644
--- a/lib/jabber-net/jabber/client/RosterManager.cs
+++ b/lib/jabber-net/jabber/client/RosterManager.cs
@@ -284,18 +284,11 @@ namespace jabber.client
                 }
                 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);                
+                // the contact has given us permission to see presence updates
                 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);
+                // the contact does not wish to see our presence updates anymore
+                // that's fine, who cares?
                 break;
             case PresenceType.unsubscribed:
                 bool remove = true;
@@ -304,6 +297,7 @@ namespace jabber.client
 
                 if (remove)
                     Remove(pres.From);
+                // the contact has taken away our permission to see presence updates
                 break;
             }
         }
@@ -352,6 +346,26 @@ namespace jabber.client
                 OnRosterEnd(this);
         }
 
+        public void Add(JID jid)
+        {
+            Item item = this[jid];
+            // only create a new roster item if it does not already exist
+            if (item == null) {
+                RosterIQ iq = new RosterIQ(m_stream.Document);
+                iq.Type = IQType.set;
+                Roster r = iq.Instruction;
+                item = r.AddItem();
+                item.JID = jid;
+                Write(iq);
+            }
+
+            // subscribe to presence
+            Presence sub = new Presence(m_stream.Document);
+            sub.To = jid;
+            sub.Type = PresenceType.subscribe;
+            Write(sub);
+        }
+
         /// <summary>
         /// Allows the subscription request and sends a subscribed to the user.
         /// </summary>
@@ -361,17 +375,19 @@ namespace jabber.client
         public void ReplyAllow(Presence pres)
         {
             Debug.Assert(pres.Type == PresenceType.subscribe);
+            Allow(pres.From);
+        }
+
+        public void Allow(JID jid)
+        {
             Presence reply = new Presence(m_stream.Document);
-            reply.To = pres.From;
+            reply.To = jid;
             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);
+                Add(jid);
             }
         }
 
@@ -384,8 +400,13 @@ namespace jabber.client
         public void ReplyDeny(Presence pres)
         {
             Debug.Assert(pres.Type == PresenceType.subscribe);
+            Deny(pres.From);
+        }
+
+        public void Deny(JID jid)
+        {
             Presence reply = new Presence(m_stream.Document);
-            reply.To = pres.From;
+            reply.To = jid;
             reply.Type = PresenceType.unsubscribed;
             Write(reply);
         }
@@ -423,7 +444,7 @@ C: <iq from='juliet at example.com/balcony' type='set' id='delete_1'>
             RosterIQ iq = new RosterIQ(m_stream.Document);
             iq.Type = IQType.set;
             Roster r = iq.Instruction;
-            r.AppendChild(item);
+            r.AddChild(item);
             Write(iq);  // ignore response
         }
 
diff --git a/lib/jabber-net/jabber/connection/ConferenceManager.cs b/lib/jabber-net/jabber/connection/ConferenceManager.cs
index d238f73..fc3679a 100644
--- a/lib/jabber-net/jabber/connection/ConferenceManager.cs
+++ b/lib/jabber-net/jabber/connection/ConferenceManager.cs
@@ -628,7 +628,7 @@ namespace jabber.connection
         private void m_stream_OnAfterPresenceOut(object sender, Presence pres)
         {
             Presence p = (Presence)pres.CloneNode(true);
-            p.To = m_room;
+            p.To = RoomAndNick;
             m_manager.Write(p);
         }
 
diff --git a/lib/osx/Info.plist.in b/lib/osx/Info.plist.in
index 247fa6b..53fede6 100644
--- a/lib/osx/Info.plist.in
+++ b/lib/osx/Info.plist.in
@@ -24,5 +24,16 @@
 	<string>@VERSION@</string>
 	<key>NSAppleScriptEnabled</key>
 	<string>NO</string>
+	<key>CFBundleURLTypes</key>
+	<array>
+		<dict>
+			<key>CFBundleURLName</key>
+			<string>IRC</string>
+			<key>CFBundleURLSchemes</key>
+			<array>
+				<string>irc</string>
+			</array>
+		</dict>
+	</array>
 </dict>
 </plist>
diff --git a/libtool.m4 b/libtool.m4
new file mode 100644
index 0000000..02b4bbe
--- /dev/null
+++ b/libtool.m4
@@ -0,0 +1,7991 @@
+# 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*)
+	    case `/usr/bin/file conftest.o` in
+	      *x86-64*)
+		LD="${LD-ld} -m elf32_x86_64"
+		;;
+	      *)
+		LD="${LD-ld} -m elf_i386"
+		;;
+	    esac
+	    ;;
+	  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" && \
+	test undefined != "$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
+  ;;
+
+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 | 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
+  ;;
+
+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 | 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 | 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 | 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
+        ;;
+
+      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 | 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/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-Campfire/LINGUAS b/po-Engine-Campfire/LINGUAS
new file mode 100644
index 0000000..3c5409b
--- /dev/null
+++ b/po-Engine-Campfire/LINGUAS
@@ -0,0 +1,5 @@
+da
+de
+fr
+sv
+zh_CN
diff --git a/po-Engine-Campfire/Makefile.in.in b/po-Engine-Campfire/Makefile.in.in
new file mode 100644
index 0000000..3b1b205
--- /dev/null
+++ b/po-Engine-Campfire/Makefile.in.in
@@ -0,0 +1,218 @@
+# Makefile for program source directory in GNU NLS utilities package.
+# Copyright (C) 1995, 1996, 1997 by Ulrich Drepper <drepper at gnu.ai.mit.edu>
+# Copyright (C) 2004-2008 Rodney Dawes <dobey.pwns at gmail.com>
+#
+# This file may be copied and used freely without restrictions.  It may
+# be used in projects which are not available under a GNU Public License,
+# but which still want to provide support for the GNU gettext functionality.
+#
+# - Modified by Owen Taylor <otaylor at redhat.com> to use GETTEXT_PACKAGE
+#   instead of PACKAGE and to look for po2tbl in ./ not in intl/
+#
+# - Modified by jacob berkman <jacob at ximian.com> to install
+#   Makefile.in.in and po2tbl.sed.in for use with glib-gettextize
+#
+# - Modified by Rodney Dawes <dobey.pwns at gmail.com> for use with intltool
+#
+# We have the following line for use by intltoolize:
+# INTLTOOL_MAKEFILE
+
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE_ENGINE_CAMPFIRE@
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+top_builddir = @top_builddir@
+VPATH = @srcdir@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+datadir = @datadir@
+datarootdir = @datarootdir@
+libdir = @libdir@
+DATADIRNAME = @DATADIRNAME@
+itlocaledir = $(prefix)/$(DATADIRNAME)/locale
+subdir = po
+install_sh = @install_sh@
+# Automake >= 1.8 provides @mkdir_p at .
+# Until it can be supposed, use the safe fallback:
+mkdir_p = $(install_sh) -d
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+
+GMSGFMT = @GMSGFMT@
+MSGFMT = @MSGFMT@
+XGETTEXT = @XGETTEXT@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+MSGMERGE = INTLTOOL_EXTRACT=$(INTLTOOL_EXTRACT) srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --dist
+GENPOT   = INTLTOOL_EXTRACT=$(INTLTOOL_EXTRACT) srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --pot
+
+ALL_LINGUAS = @ALL_LINGUAS@
+
+PO_LINGUAS=$(shell if test -r $(srcdir)/LINGUAS; then grep -v "^\#" $(srcdir)/LINGUAS; fi)
+
+USER_LINGUAS=$(shell if test -n "$(LINGUAS)"; then LLINGUAS="$(LINGUAS)"; ALINGUAS="$(ALL_LINGUAS)"; for lang in $$LLINGUAS; do if test -n "`grep ^$$lang$$ $(srcdir)/LINGUAS`" -o -n "`echo $$ALINGUAS|grep ' ?$$lang ?'`"; then printf "$$lang "; fi; done; fi)
+
+USE_LINGUAS=$(shell if test -n "$(USER_LINGUAS)"; then LLINGUAS="$(USER_LINGUAS)"; else if test -n "$(PO_LINGUAS)"; then LLINGUAS="$(PO_LINGUAS)"; else LLINGUAS="$(ALL_LINGUAS)"; fi; fi; for lang in $$LLINGUAS; do printf "$$lang "; done)
+
+POFILES=$(shell LINGUAS="$(USE_LINGUAS)"; for lang in $$LINGUAS; do printf "$$lang.po "; done)
+
+DISTFILES = Makefile.in.in POTFILES.in $(POFILES)
+EXTRA_DISTFILES = POTFILES.skip Makevars LINGUAS
+
+POTFILES = \
+# This comment gets stripped out
+
+CATALOGS=$(shell LINGUAS="$(USE_LINGUAS)"; for lang in $$LINGUAS; do printf "$$lang.gmo "; done)
+
+.SUFFIXES:
+.SUFFIXES: .po .pox .gmo .mo .msg .cat
+
+.po.pox:
+	$(MAKE) $(GETTEXT_PACKAGE).pot
+	$(MSGMERGE) $< $(GETTEXT_PACKAGE).pot -o $*.pox
+
+.po.mo:
+	$(MSGFMT) -o $@ $<
+
+.po.gmo:
+	file=`echo $* | sed 's,.*/,,'`.gmo \
+	  && rm -f $$file && $(GMSGFMT) -o $$file $<
+
+.po.cat:
+	sed -f ../intl/po2msg.sed < $< > $*.msg \
+	  && rm -f $@ && gencat $@ $*.msg
+
+
+all: all- at USE_NLS@
+
+all-yes: $(CATALOGS)
+all-no:
+
+$(GETTEXT_PACKAGE).pot: $(POTFILES)
+	$(GENPOT)
+
+install: install-data
+install-data: install-data- at USE_NLS@
+install-data-no: all
+install-data-yes: all
+	$(mkdir_p) $(DESTDIR)$(itlocaledir)
+	linguas="$(USE_LINGUAS)"; \
+	for lang in $$linguas; do \
+	  dir=$(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES; \
+	  $(mkdir_p) $$dir; \
+	  if test -r $$lang.gmo; then \
+	    $(INSTALL_DATA) $$lang.gmo $$dir/$(GETTEXT_PACKAGE).mo; \
+	    echo "installing $$lang.gmo as $$dir/$(GETTEXT_PACKAGE).mo"; \
+	  else \
+	    $(INSTALL_DATA) $(srcdir)/$$lang.gmo $$dir/$(GETTEXT_PACKAGE).mo; \
+	    echo "installing $(srcdir)/$$lang.gmo as" \
+		 "$$dir/$(GETTEXT_PACKAGE).mo"; \
+	  fi; \
+	  if test -r $$lang.gmo.m; then \
+	    $(INSTALL_DATA) $$lang.gmo.m $$dir/$(GETTEXT_PACKAGE).mo.m; \
+	    echo "installing $$lang.gmo.m as $$dir/$(GETTEXT_PACKAGE).mo.m"; \
+	  else \
+	    if test -r $(srcdir)/$$lang.gmo.m ; then \
+	      $(INSTALL_DATA) $(srcdir)/$$lang.gmo.m \
+		$$dir/$(GETTEXT_PACKAGE).mo.m; \
+	      echo "installing $(srcdir)/$$lang.gmo.m as" \
+		   "$$dir/$(GETTEXT_PACKAGE).mo.m"; \
+	    else \
+	      true; \
+	    fi; \
+	  fi; \
+	done
+
+# Empty stubs to satisfy archaic automake needs
+dvi info tags TAGS ID:
+
+# Define this as empty until I found a useful application.
+install-exec installcheck:
+
+uninstall:
+	linguas="$(USE_LINGUAS)"; \
+	for lang in $$linguas; do \
+	  rm -f $(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE).mo; \
+	  rm -f $(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE).mo.m; \
+	done
+
+check: all $(GETTEXT_PACKAGE).pot
+	rm -f missing notexist
+	srcdir=$(srcdir) $(INTLTOOL_UPDATE) -m
+	if [ -r missing -o -r notexist ]; then \
+	  exit 1; \
+	fi
+
+mostlyclean:
+	rm -f *.pox $(GETTEXT_PACKAGE).pot *.old.po cat-id-tbl.tmp
+	rm -f .intltool-merge-cache
+
+clean: mostlyclean
+
+distclean: clean
+	rm -f Makefile Makefile.in POTFILES stamp-it
+	rm -f *.mo *.msg *.cat *.cat.m *.gmo
+
+maintainer-clean: distclean
+	@echo "This command is intended for maintainers to use;"
+	@echo "it deletes files that may require special tools to rebuild."
+	rm -f Makefile.in.in
+
+distdir = ../$(PACKAGE)-$(VERSION)/$(subdir)
+dist distdir: $(DISTFILES)
+	dists="$(DISTFILES)"; \
+	extra_dists="$(EXTRA_DISTFILES)"; \
+	for file in $$extra_dists; do \
+	  test -f $(srcdir)/$$file && dists="$$dists $(srcdir)/$$file"; \
+	done; \
+	for file in $$dists; do \
+	  test -f $$file || file="$(srcdir)/$$file"; \
+	  ln $$file $(distdir) 2> /dev/null \
+	    || cp -p $$file $(distdir); \
+	done
+
+update-po: Makefile
+	$(MAKE) $(GETTEXT_PACKAGE).pot
+	tmpdir=`pwd`; \
+	linguas="$(USE_LINGUAS)"; \
+	for lang in $$linguas; do \
+	  echo "$$lang:"; \
+	  result="`$(MSGMERGE) -o $$tmpdir/$$lang.new.po $$lang`"; \
+	  if $$result; then \
+	    if cmp $(srcdir)/$$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \
+	      rm -f $$tmpdir/$$lang.new.po; \
+            else \
+	      if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \
+	        :; \
+	      else \
+	        echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \
+	        rm -f $$tmpdir/$$lang.new.po; \
+	        exit 1; \
+	      fi; \
+	    fi; \
+	  else \
+	    echo "msgmerge for $$lang.gmo failed!"; \
+	    rm -f $$tmpdir/$$lang.new.po; \
+	  fi; \
+	done
+
+Makefile POTFILES: stamp-it
+	@if test ! -f $@; then \
+	  rm -f stamp-it; \
+	  $(MAKE) stamp-it; \
+	fi
+
+stamp-it: Makefile.in.in $(top_builddir)/config.status POTFILES.in
+	cd $(top_builddir) \
+	  && CONFIG_FILES=$(subdir)/Makefile.in CONFIG_HEADERS= CONFIG_LINKS= \
+	       $(SHELL) ./config.status
+
+# Tell versions [3.59,3.63) of GNU make not to export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/po-Engine-Campfire/POTFILES.in b/po-Engine-Campfire/POTFILES.in
new file mode 100644
index 0000000..62fd597
--- /dev/null
+++ b/po-Engine-Campfire/POTFILES.in
@@ -0,0 +1 @@
+src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs
diff --git a/po-Engine-Campfire/POTFILES.skip b/po-Engine-Campfire/POTFILES.skip
new file mode 100644
index 0000000..7d74a2d
--- /dev/null
+++ b/po-Engine-Campfire/POTFILES.skip
@@ -0,0 +1,16 @@
+glade/
+src/Common/
+src/Frontend/
+src/Frontend-GNOME/
+src/Frontend-GNOME-IRC/
+src/Frontend-STFL/
+src/Frontend-SWF/
+src/Frontend-WPF/
+src/Engine/
+src/Engine-IRC/
+src/Engine-MSNP/
+src/Engine-OSCAR/
+src/Engine-XMPP/
+src/Engine-Twitter/
+src/Server/
+lib/
diff --git a/po-Engine-Campfire/da.po b/po-Engine-Campfire/da.po
new file mode 100644
index 0000000..9c1bf40
--- /dev/null
+++ b/po-Engine-Campfire/da.po
@@ -0,0 +1,79 @@
+# 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>, 2013.
+msgid ""
+msgstr ""
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2013-04-14 20:01+0200\n"
+"PO-Revision-Date: 2013-04-16 06:30+0000\n"
+"Last-Translator: Joe Hansen <joedalton2 at yahoo.dk>\n"
+"Language-Team: Danish (http://www.transifex.com/projects/p/smuxi/language/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-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:123
+msgid "Connecting to campfire... "
+msgstr "Forbinder til campfire ..."
+
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:149
+msgid "Connected to campfire"
+msgstr "Forbundet til campfire"
+
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of commands below
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:181
+msgid "Campfire Commands"
+msgstr "Campfire-kommandoer"
+
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:242
+msgid "Upload"
+msgstr "Overfør"
+
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:243
+#, csharp-format
+msgid "'{0}' ({1} B) {2}"
+msgstr "»{0}« ({1} B) {2}"
+
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:354
+#, csharp-format
+msgid "has uploaded '{0}' ({1} B) {2}"
+msgstr "har overført »{0}« ({1} B) {2}"
+
+#. TRANSLATOR: {0} is the name of the room
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:386
+#, csharp-format
+msgid "has joined {0}"
+msgstr "er sluttet til {0}"
+
+#. TRANSLATOR: {0} is the name of the room
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:395
+#, csharp-format
+msgid "has left {0}"
+msgstr "har forladt {0}"
+
+#. TRANSLATOR: {0} is the name of the room
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:403
+#, csharp-format
+msgid "has locked {0}"
+msgstr "har låst {0}"
+
+#. TRANSLATOR: {0} is the name of the room
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:407
+#, csharp-format
+msgid "has unlocked {0}"
+msgstr "har åbent {0}"
+
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:412
+msgid "has changed the topic"
+msgstr "har ændret emnet"
+
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:422
+msgid "has performed an unknown action"
+msgstr "har udført ukendt handling"
diff --git a/po-Engine-Campfire/de.po b/po-Engine-Campfire/de.po
new file mode 100644
index 0000000..946c1a2
--- /dev/null
+++ b/po-Engine-Campfire/de.po
@@ -0,0 +1,79 @@
+# 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>, 2013.
+msgid ""
+msgstr ""
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2013-04-14 20:01+0200\n"
+"PO-Revision-Date: 2013-04-14 19:26+0000\n"
+"Last-Translator: Bianca Mix <heavydemon at freenet.de>\n"
+"Language-Team: German (http://www.transifex.com/projects/p/smuxi/language/de/)\n"
+"MIME-Version: 1.0\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-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:123
+msgid "Connecting to campfire... "
+msgstr "verbinde zu campfire..."
+
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:149
+msgid "Connected to campfire"
+msgstr "Verbunden mit campfire"
+
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of commands below
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:181
+msgid "Campfire Commands"
+msgstr "Campfire Kommandos"
+
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:242
+msgid "Upload"
+msgstr "Hochladen"
+
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:243
+#, csharp-format
+msgid "'{0}' ({1} B) {2}"
+msgstr "'{0}' ({1} B) {2}"
+
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:354
+#, csharp-format
+msgid "has uploaded '{0}' ({1} B) {2}"
+msgstr "hat '{0}' ({1} B) hochgeladen {2}"
+
+#. TRANSLATOR: {0} is the name of the room
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:386
+#, csharp-format
+msgid "has joined {0}"
+msgstr "hat {0} betreten"
+
+#. TRANSLATOR: {0} is the name of the room
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:395
+#, csharp-format
+msgid "has left {0}"
+msgstr "hat {0} verlassen"
+
+#. TRANSLATOR: {0} is the name of the room
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:403
+#, csharp-format
+msgid "has locked {0}"
+msgstr "hat {0} gesperrt"
+
+#. TRANSLATOR: {0} is the name of the room
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:407
+#, csharp-format
+msgid "has unlocked {0}"
+msgstr "hat {0} entsperrt"
+
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:412
+msgid "has changed the topic"
+msgstr "hat das Thema geändert"
+
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:422
+msgid "has performed an unknown action"
+msgstr "hat eine unbekannte Aktion ausgeführt"
diff --git a/po-Engine-Campfire/fr.po b/po-Engine-Campfire/fr.po
new file mode 100644
index 0000000..c78756e
--- /dev/null
+++ b/po-Engine-Campfire/fr.po
@@ -0,0 +1,76 @@
+# This file is distributed under the same license as the smuxi package.
+# Clément Bourgeois <moonpyk at gmail.com>, 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-04-10 21:37+0200\n"
+"PO-Revision-Date: 2013-04-14 21:48+0100\n"
+"Last-Translator: Clément Bourgeois <moonpyk at gmail.com>\n"
+"Language-Team: French (http://www.transifex.net/projects/p/smuxi/team/fr/)\n"
+"Language: 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"
+
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:123
+msgid "Connecting to campfire... "
+msgstr "Connexion à campfire..."
+
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:149
+msgid "Connected to campfire"
+msgstr "Connecté à campfire"
+
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of commands below
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:181
+msgid "Campfire Commands"
+msgstr "Commandes Campfire"
+
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:242
+msgid "Upload"
+msgstr "Envoyer"
+
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:243
+#, csharp-format
+msgid "'{0}' ({1} B) {2}"
+msgstr "'{0}' ({1} O) {2}"
+
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:354
+#, csharp-format
+msgid "has uploaded '{0}' ({1} B) {2}"
+msgstr "a envoyé '{0}' ({1} O) {2}"
+
+#. TRANSLATOR: {0} is the name of the room
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:386
+#, csharp-format
+msgid "has joined {0}"
+msgstr "a rejoint {0}"
+
+#. TRANSLATOR: {0} is the name of the room
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:395
+#, csharp-format
+msgid "has left {0}"
+msgstr "a quitté {0}"
+
+#. TRANSLATOR: {0} is the name of the room
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:403
+#, csharp-format
+msgid "has locked {0}"
+msgstr "a bloqué {0}"
+
+#. TRANSLATOR: {0} is the name of the room
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:407
+#, csharp-format
+msgid "has unlocked {0}"
+msgstr "a débloqué {0}"
+
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:412
+msgid "has changed the topic"
+msgstr "a changé le sujet"
+
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:422
+msgid "has performed an unknown action"
+msgstr "a effectué une action inconnue"
diff --git a/po-Engine-Campfire/sv.po b/po-Engine-Campfire/sv.po
new file mode 100644
index 0000000..c3b3ef1
--- /dev/null
+++ b/po-Engine-Campfire/sv.po
@@ -0,0 +1,79 @@
+# 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 <flugsio at gmail.com>, 2013
+msgid ""
+msgstr ""
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2013-04-14 20:01+0200\n"
+"PO-Revision-Date: 2013-04-17 04:07+0000\n"
+"Last-Translator: flugsio <flugsio at gmail.com>\n"
+"Language-Team: Swedish (http://www.transifex.com/projects/p/smuxi/language/sv/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: sv\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:123
+msgid "Connecting to campfire... "
+msgstr "Ansluter till campfire..."
+
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:149
+msgid "Connected to campfire"
+msgstr "Ansluten till campfire"
+
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of commands below
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:181
+msgid "Campfire Commands"
+msgstr "Campfire-kommandon"
+
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:242
+msgid "Upload"
+msgstr "Ladda upp"
+
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:243
+#, csharp-format
+msgid "'{0}' ({1} B) {2}"
+msgstr "'{0}' ({1} B) {2}"
+
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:354
+#, csharp-format
+msgid "has uploaded '{0}' ({1} B) {2}"
+msgstr "har laddat upp '{0}' ({1} B) {2}"
+
+#. TRANSLATOR: {0} is the name of the room
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:386
+#, csharp-format
+msgid "has joined {0}"
+msgstr "har anslutit {0}"
+
+#. TRANSLATOR: {0} is the name of the room
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:395
+#, csharp-format
+msgid "has left {0}"
+msgstr "har lämnat {0}"
+
+#. TRANSLATOR: {0} is the name of the room
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:403
+#, csharp-format
+msgid "has locked {0}"
+msgstr "har låst {0}"
+
+#. TRANSLATOR: {0} is the name of the room
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:407
+#, csharp-format
+msgid "has unlocked {0}"
+msgstr "har låst upp {0}"
+
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:412
+msgid "has changed the topic"
+msgstr "har ändrat rubrik"
+
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:422
+msgid "has performed an unknown action"
+msgstr "har utfört en okänd åtgärd"
diff --git a/po-Engine-Campfire/zh_CN.po b/po-Engine-Campfire/zh_CN.po
new file mode 100644
index 0000000..8cd2f20
--- /dev/null
+++ b/po-Engine-Campfire/zh_CN.po
@@ -0,0 +1,79 @@
+# 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>, 2013.
+msgid ""
+msgstr ""
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2013-04-14 20:01+0200\n"
+"PO-Revision-Date: 2013-04-15 14:11+0000\n"
+"Last-Translator: Dean Lee <xslidian at gmail.com>\n"
+"Language-Team: Chinese (China) (http://www.transifex.com/projects/p/smuxi/language/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-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:123
+msgid "Connecting to campfire... "
+msgstr "正在连接到 campfire..."
+
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:149
+msgid "Connected to campfire"
+msgstr "已连接到 campfire"
+
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of commands below
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:181
+msgid "Campfire Commands"
+msgstr "Campfire 命令"
+
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:242
+msgid "Upload"
+msgstr "上传"
+
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:243
+#, csharp-format
+msgid "'{0}' ({1} B) {2}"
+msgstr "'{0}' ({1} 字节) {2}"
+
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:354
+#, csharp-format
+msgid "has uploaded '{0}' ({1} B) {2}"
+msgstr "已上传 '{0}' ({1} 字节) {2}"
+
+#. TRANSLATOR: {0} is the name of the room
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:386
+#, csharp-format
+msgid "has joined {0}"
+msgstr "已加入 {0}"
+
+#. TRANSLATOR: {0} is the name of the room
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:395
+#, csharp-format
+msgid "has left {0}"
+msgstr "已离开 {0}"
+
+#. TRANSLATOR: {0} is the name of the room
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:403
+#, csharp-format
+msgid "has locked {0}"
+msgstr "已锁定 {0}"
+
+#. TRANSLATOR: {0} is the name of the room
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:407
+#, csharp-format
+msgid "has unlocked {0}"
+msgstr "已解锁 {0}"
+
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:412
+msgid "has changed the topic"
+msgstr "已更改主题"
+
+#: ../src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs:422
+msgid "has performed an unknown action"
+msgstr "已执行未知操作"
diff --git a/po-Engine-IRC/LINGUAS b/po-Engine-IRC/LINGUAS
index aa7a575..857613d 100644
--- a/po-Engine-IRC/LINGUAS
+++ b/po-Engine-IRC/LINGUAS
@@ -5,6 +5,7 @@ de
 en_GB
 es
 es_AR
+fi
 fr
 hr
 it
diff --git a/po-Engine-IRC/POTFILES.skip b/po-Engine-IRC/POTFILES.skip
index 2b6775f..f6b3c95 100644
--- a/po-Engine-IRC/POTFILES.skip
+++ b/po-Engine-IRC/POTFILES.skip
@@ -1,6 +1,7 @@
 glade/
 src/Common/
 src/Engine/
+src/Engine-Campfire/
 src/Engine-MSNP/
 src/Engine-OSCAR/
 src/Engine-XMPP/
diff --git a/po-Engine-IRC/da.po b/po-Engine-IRC/da.po
index afbdc00..e7c89ee 100644
--- a/po-Engine-IRC/da.po
+++ b/po-Engine-IRC/da.po
@@ -3,241 +3,255 @@
 # This file is distributed under the same license as the PACKAGE package.
 # 
 # Translators:
+# Joe Hansen <joedalton2 at yahoo.dk>, 2012-2013.
 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: Danish (http://www.transifex.net/projects/p/smuxi/team/da/)\n"
+"POT-Creation-Date: 2013-04-14 10:14+0200\n"
+"PO-Revision-Date: 2013-04-16 06:21+0000\n"
+"Last-Translator: Joe Hansen <joedalton2 at yahoo.dk>\n"
+"Language-Team: Danish (http://www.transifex.com/projects/p/smuxi/language/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"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
 #. TRANSLATOR: do NOT change the position of {0}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:245
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:244
 #, 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
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:275
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1642
 msgid "away"
 msgstr "fraværende"
 
 #. TRANSLATOR: {0} is the amount of seconds
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:282
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:281
 #, csharp-format
 msgid "lag: {0} seconds"
 msgstr "lag: {0} sekunder"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:288
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:287
 msgid "not connected"
 msgstr "ikke forbundet"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:351
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:347
+#, csharp-format
+msgid "Using proxy: {0}:{1}"
+msgstr "Bruger proxy: {0}:{1}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:354
 #, csharp-format
 msgid "Connecting to {0} port {1}..."
 msgstr "Forbinder til {0} port {1}..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:357
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:463
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:364
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:491
 #, csharp-format
 msgid "Connection to {0} established"
 msgstr "Forbindelse til {0} etableret"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:360
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:371
 msgid "Logging in..."
 msgstr "Logger ind..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:394
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:410
 msgid "Connection failed!"
 msgstr "Forbindelse mislykkedes!"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:395
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:413
 msgid "Connection failed! Reason: "
 msgstr "Forbindelse mislykkedes! Ã…rsag: "
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:404
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:425
 msgid "Disconnecting..."
 msgstr "Afbryder..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:407
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:429
 #, csharp-format
 msgid "Disconnecting from {0}..."
 msgstr "Afbryder fra {0}..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:412
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:435
 #, csharp-format
 msgid "Disconnected from {0}"
 msgstr "Afbrudt fra {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:415
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:440
 msgid "Connection closed"
 msgstr "Forbindelse lukket"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:420
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:477
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:447
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:512
 msgid "Not connected"
 msgstr "Ikke forbundet"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:449
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:478
 msgid "Reconnecting..."
 msgstr "Genforbinder..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:457
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:485
 #, csharp-format
 msgid "Reconnecting to {0}..."
 msgstr "Genforbinder til {0}..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:471
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:502
 msgid "Reconnect Error"
 msgstr "Genforbindingsfejl"
 
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:846
+#, csharp-format
+msgid "Sleeping for {0} milliseconds"
+msgstr "Sover i {0} millisekunder"
+
 #. TRANSLATOR: this line is used as label / category for a
 #. list of commands below
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:875
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:935
 msgid "IrcProtocolManager Commands"
 msgstr "Kommandoer for IrcProtocolManager"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:943
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1008
 #, csharp-format
 msgid "Invalid port: {0}"
 msgstr "Ugyldig port: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1047
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1109
 #, csharp-format
 msgid "Queuing joins: {0}"
 msgstr "Sætter join sammen: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1061
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1121
 #, 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:1096
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1157
 #, 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:1119
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1150
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1180
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1209
 #, csharp-format
 msgid "Joining: {0}"
 msgstr "Joiner: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1121
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1182
 msgid "Remaining"
 msgstr "Tilbage"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1126
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1187
 #, csharp-format
 msgid "active joins: {0}"
 msgstr "aktive join: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1135
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1196
 #, csharp-format
 msgid "queued joins: {0}"
 msgstr "join i kø: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1506
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1629
 msgid "IRC Op"
 msgstr "IRC Op"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1508
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1631
 msgid "Op"
 msgstr "Op"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1510
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1633
 msgid "Voice"
 msgstr "Voice"
 
 #. TRANSLATOR: do NOT change the position of {1}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1570
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1696
 #, csharp-format
 msgid "Topic for {0}: {1}"
 msgstr "Emne for {0}: {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1575
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1699
 #, csharp-format
 msgid "No topic set for {0}"
 msgstr "Intet emne angivet for {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1655
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1781
 msgid "ban"
 msgstr "giv karantæne"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1665
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1792
 msgid "No bans in channel"
 msgstr "Ingen karantæner i kanal"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1777
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1885
+#, csharp-format
+msgid "Your user mode is {0}"
+msgstr "Din brugertilstand er {0}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1906
 #, csharp-format
 msgid "Inviting {0} to {1}"
 msgstr "Inviterer {0} til {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1781
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1913
 #, csharp-format
 msgid "{0} is already on {1}"
 msgstr "{0} er allerede på {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1806
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1940
 msgid "Users"
 msgstr "Brugere"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1848
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1982
 #, 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:1979
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2118
 msgid "Connection error! Reason: "
 msgstr "Forbindelsesfejl! Ã…rsag: "
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1989
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2130
 #, csharp-format
 msgid "Not enough parameters for {0} command"
 msgstr "Ikke nok parametre for {0} kommando"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1999
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2139
 msgid "Not connected to server"
 msgstr "Ikke forbundet til server"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2261
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2330
 #, csharp-format
 msgid "{0}: No such nick/channel"
 msgstr "{0}: Intet sådan brugernavn/kanal"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2390
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2455
 #, csharp-format
 msgid ""
 "Increased send delay to {0}ms to avoid being flooded off the server again."
-msgstr ""
-"Øgede forsinkelse for send til {0}ms for at undgå at blive oversvømmet på "
-"serveren igen."
+msgstr "Øgede forsinkelse for send til {0}ms for at undgå at blive oversvømmet på serveren igen."
 
 #. TRANSLATOR: the final line will look like this:
 #. -!- Nick {0} is already in use
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2404
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2469
 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:2414
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2479
 msgid "is already in use"
 msgstr "er allerede i brug"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2424
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2489
 msgid "Cannot join to channel:"
 msgstr "Kan ikke slutte til kanal:"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2432
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2497
 msgid "You are banned"
 msgstr "Du har karantæne"
 
@@ -245,100 +259,98 @@ 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:2508
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2580
 #, 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:2533
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2607
 #, 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:2541
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2616
 #, csharp-format
 msgid "CTCP {0} reply from {1}: {2}"
 msgstr "CTCP {0} svar fra {1}: {2}"
 
 #. TRANSLATOR: do NOT change the position of {0}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2747
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2822
 #, csharp-format
 msgid "{0} [{1}] has joined {2}"
 msgstr "{0} [{1}] har sluttet sig til {2}"
 
 #. TRANSLATOR: do NOT change the position of {0}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2873
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2948
 #, csharp-format
 msgid "{0} [{1}] has left {2}"
 msgstr "{0} [{1}] har forladt {2}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2898
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2974
 #, csharp-format
-msgid "You were kicked from {0} by {1} [{2}]"
-msgstr "Du blev smidt ud fra {0} af {1} [{2}]"
+msgid "You were kicked from {0} by {1}"
+msgstr "Du blev smidt ud fra {0} af {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2906
+#. TRANSLATOR: do NOT change the position of {0} and {2}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2985
 #, csharp-format
-msgid "{0} was kicked from {1} by {2} [{3}]"
-msgstr "{0} blev smidt ud af {1} af {2} [{3}]"
+msgid "{0} was kicked from {1} by {2}"
+msgstr "{0} blev smidt ud fra {1} af {2}"
 
 #. TRANSLATOR: do NOT change the position of {0}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2923
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2956
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3005
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3038
 #, csharp-format
 msgid "You're now known as {0}"
 msgstr "Du er nu kendt som {0}"
 
 #. TRANSLATOR: do NOT change the position of {0} or {1}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2961
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3043
 #, csharp-format
 msgid "{0} is now known as {1}"
 msgstr "{0} er nu kendt som {1}"
 
 #. TRANSLATOR: do NOT change the position of {0} and {2}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2998
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3079
 #, csharp-format
 msgid "{0} changed the topic of {1} to: {2}"
 msgstr "{0} ændrede emnet på {1} til: {2}"
 
 #. TRANSLATOR: do NOT change the position of {1}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3075
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3159
 #, csharp-format
 msgid "Mode change [{0}] for user {1}"
 msgstr "Tilstandsændring [{0}] for bruger {1}"
 
 #. TRANSLATOR: do NOT change the position of {2}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3085
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3169
 #, csharp-format
 msgid "mode/{0} [{1}] by {2}"
 msgstr "tilstand/{0} [{1}] af {2}"
 
 #. TRANSLATOR: do NOT change the position of {0}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3122
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3206
 #, csharp-format
 msgid "{0} [{1}] has quit"
 msgstr "{0} [{1}] er gået"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3199
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3283
 #, 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..."
+msgstr "Forbindelse til {0} port {1} er mislykkedes (forsøg {2}), forsøger om {3} sekunder..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3248
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3333
 #, csharp-format
 msgid "{0} is away: {1}"
 msgstr "{0} er fraværende: {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3254
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3343
 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:3260
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3353
 msgid "You have been marked as being away"
 msgstr "Du er registreret som fraværende"
-
-
diff --git a/po-Engine-IRC/de.po b/po-Engine-IRC/de.po
index d58360e..c287e99 100644
--- a/po-Engine-IRC/de.po
+++ b/po-Engine-IRC/de.po
@@ -3,243 +3,255 @@
 # This file is distributed under the same license as the PACKAGE package.
 # 
 # Translators:
+# Bianca Mix <heavydemon at freenet.de>, 2012-2013.
 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: German (http://www.transifex.net/projects/p/smuxi/team/de/)\n"
+"POT-Creation-Date: 2013-04-14 10:14+0200\n"
+"PO-Revision-Date: 2013-04-14 19:31+0000\n"
+"Last-Translator: Bianca Mix <heavydemon at freenet.de>\n"
+"Language-Team: German (http://www.transifex.com/projects/p/smuxi/language/de/)\n"
 "MIME-Version: 1.0\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"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
 #. TRANSLATOR: do NOT change the position of {0}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:245
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:244
 #, 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
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:275
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1642
 msgid "away"
 msgstr "abwesend"
 
 #. TRANSLATOR: {0} is the amount of seconds
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:282
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:281
 #, csharp-format
 msgid "lag: {0} seconds"
 msgstr "Verzögerung: {0} Sekunden"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:288
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:287
 msgid "not connected"
 msgstr "nicht verbunden"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:351
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:347
+#, csharp-format
+msgid "Using proxy: {0}:{1}"
+msgstr "Benutze Proxy: {0}:{1}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:354
 #, csharp-format
 msgid "Connecting to {0} port {1}..."
 msgstr "Verbinde zu {0} Port {1}..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:357
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:463
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:364
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:491
 #, csharp-format
 msgid "Connection to {0} established"
 msgstr "Verbindung zu {0} ist hergestellt"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:360
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:371
 msgid "Logging in..."
 msgstr "Anmelden..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:394
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:410
 msgid "Connection failed!"
 msgstr "Verbindung ist fehlgeschlagen!"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:395
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:413
 msgid "Connection failed! Reason: "
 msgstr "Verbindung ist fehlgeschlagen! Ursache: "
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:404
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:425
 msgid "Disconnecting..."
 msgstr "Trenne..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:407
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:429
 #, csharp-format
 msgid "Disconnecting from {0}..."
 msgstr "Trenne von {0}..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:412
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:435
 #, csharp-format
 msgid "Disconnected from {0}"
 msgstr "Getrennt von {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:415
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:440
 msgid "Connection closed"
 msgstr "Verbindung wurde geschlossen"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:420
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:477
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:447
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:512
 msgid "Not connected"
 msgstr "Nicht verbunden"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:449
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:478
 msgid "Reconnecting..."
 msgstr "Verbinde erneut..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:457
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:485
 #, csharp-format
 msgid "Reconnecting to {0}..."
 msgstr "Verbinde erneut zu {0}..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:471
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:502
 msgid "Reconnect Error"
 msgstr "Fehler beim Wiederverbinden"
 
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:846
+#, csharp-format
+msgid "Sleeping for {0} milliseconds"
+msgstr "Warte für {0} Millisekunden"
+
 #. TRANSLATOR: this line is used as label / category for a
 #. list of commands below
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:875
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:935
 msgid "IrcProtocolManager Commands"
 msgstr "IrcProtocolManager Befehle"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:943
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1008
 #, csharp-format
 msgid "Invalid port: {0}"
 msgstr "Ungültiger Port: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1047
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1109
 #, csharp-format
 msgid "Queuing joins: {0}"
 msgstr "Verzögere Beitritte: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1061
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1121
 #, 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:1096
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1157
 #, 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:1119
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1150
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1180
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1209
 #, csharp-format
 msgid "Joining: {0}"
 msgstr "Betrete: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1121
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1182
 msgid "Remaining"
 msgstr "Verbleibend"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1126
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1187
 #, csharp-format
 msgid "active joins: {0}"
 msgstr "Aktive Beitritte: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1135
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1196
 #, csharp-format
 msgid "queued joins: {0}"
 msgstr "Wartende Beitritte: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1506
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1629
 msgid "IRC Op"
 msgstr "IRC Op"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1508
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1631
 msgid "Op"
 msgstr "Op"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1510
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1633
 msgid "Voice"
 msgstr "Voice"
 
 #. TRANSLATOR: do NOT change the position of {1}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1570
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1696
 #, csharp-format
 msgid "Topic for {0}: {1}"
 msgstr "Thema für {0}: {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1575
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1699
 #, csharp-format
 msgid "No topic set for {0}"
 msgstr "Kein Thema für {0} gesetzt"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1655
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1781
 msgid "ban"
 msgstr "Sperre"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1665
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1792
 msgid "No bans in channel"
 msgstr "Keine Sperren in diesem Channel"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1777
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1885
+#, csharp-format
+msgid "Your user mode is {0}"
+msgstr "Ihr Benutzermodus ist {0}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1906
 #, csharp-format
 msgid "Inviting {0} to {1}"
 msgstr "Lade {0} in {1} ein"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1781
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1913
 #, csharp-format
 msgid "{0} is already on {1}"
 msgstr "{0} ist bereits in {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1806
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1940
 msgid "Users"
 msgstr "Benutzer"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1848
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1982
 #, 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:1979
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2118
 msgid "Connection error! Reason: "
 msgstr "Verbindungsfehler! Grund: "
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1989
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2130
 #, 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:1999
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2139
 msgid "Not connected to server"
 msgstr "Nicht mit Server verbunden"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2261
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2330
 #, csharp-format
 msgid "{0}: No such nick/channel"
 msgstr "{0}: Kein solcher Nick/Channel"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2390
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2455
 #, 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."
+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:2404
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2469
 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:2414
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2479
 msgid "is already in use"
 msgstr "wird bereits verwendet"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2424
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2489
 msgid "Cannot join to channel:"
 msgstr "Konnte Channel nicht beitreten:"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2432
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2497
 msgid "You are banned"
 msgstr "Sie sind gesperrt"
 
@@ -247,100 +259,98 @@ 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:2508
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2580
 #, 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:2533
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2607
 #, 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:2541
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2616
 #, csharp-format
 msgid "CTCP {0} reply from {1}: {2}"
 msgstr "CTCP {0} Antwort von {1}: {2}"
 
 #. TRANSLATOR: do NOT change the position of {0}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2747
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2822
 #, csharp-format
 msgid "{0} [{1}] has joined {2}"
 msgstr "{0} [{1}] hat {2} betreten"
 
 #. TRANSLATOR: do NOT change the position of {0}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2873
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2948
 #, csharp-format
 msgid "{0} [{1}] has left {2}"
 msgstr "{0} [{1}] hat {2} verlassen"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2898
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2974
 #, csharp-format
-msgid "You were kicked from {0} by {1} [{2}]"
-msgstr "Sie wurden von {1} aus {0} hinausgeworfen [{2}]"
+msgid "You were kicked from {0} by {1}"
+msgstr "Sie wurden von {1} aus {0} hinausgeworfen"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2906
+#. TRANSLATOR: do NOT change the position of {0} and {2}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2985
 #, csharp-format
-msgid "{0} was kicked from {1} by {2} [{3}]"
-msgstr "{0} wurde von {2} aus {1} hinausgeworfen [{3}]"
+msgid "{0} was kicked from {1} by {2}"
+msgstr "{0} wurde von {2} aus {1} hinausgeworfen"
 
 #. TRANSLATOR: do NOT change the position of {0}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2923
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2956
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3005
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3038
 #, csharp-format
 msgid "You're now known as {0}"
 msgstr "Sie sind nun bekannt als: {0}"
 
 #. TRANSLATOR: do NOT change the position of {0} or {1}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2961
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3043
 #, csharp-format
 msgid "{0} is now known as {1}"
 msgstr "{0} ist nun bekannt als: {1}"
 
 #. TRANSLATOR: do NOT change the position of {0} and {2}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2998
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3079
 #, csharp-format
 msgid "{0} changed the topic of {1} to: {2}"
-msgstr "{0} hat das Thema geändert: von {1} auf {2}"
+msgstr "{0} hat das Thema des Kanals {1} geändert auf: {2}"
 
 #. TRANSLATOR: do NOT change the position of {1}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3075
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3159
 #, csharp-format
 msgid "Mode change [{0}] for user {1}"
 msgstr "Mode für Benutzer {1} geändert [{0}]"
 
 #. TRANSLATOR: do NOT change the position of {2}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3085
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3169
 #, csharp-format
 msgid "mode/{0} [{1}] by {2}"
 msgstr "mode/{0} [{1}] von {2}"
 
 #. TRANSLATOR: do NOT change the position of {0}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3122
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3206
 #, csharp-format
 msgid "{0} [{1}] has quit"
 msgstr "{0} [{1}] hat beendet"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3199
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3283
 #, csharp-format
 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"
+msgstr "Die Verbindung {0} über Port {1} ist fehlgeschlagen (Versuch {2}), erneuter Versuch in {3} Sekunden"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3248
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3333
 #, csharp-format
 msgid "{0} is away: {1}"
 msgstr "{0} ist abwesend: {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3254
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3343
 msgid "You are no longer marked as being away"
 msgstr "Sie sind nicht mehr als abwesend gekenntzeichet"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3260
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3353
 msgid "You have been marked as being away"
 msgstr "Sie sind als abwesend gekenntzeichnet"
-
-
diff --git a/po-Engine-IRC/fi.po b/po-Engine-IRC/fi.po
new file mode 100644
index 0000000..86eb65f
--- /dev/null
+++ b/po-Engine-IRC/fi.po
@@ -0,0 +1,356 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+# Kalle Kaitala <cobrian at cobrian.net>, 2013
+msgid ""
+msgstr ""
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2013-04-14 10:14+0200\n"
+"PO-Revision-Date: 2013-05-01 09:46+0000\n"
+"Last-Translator: Kalle Kaitala <cobrian at cobrian.net>\n"
+"Language-Team: Finnish (http://www.transifex.com/projects/p/smuxi/language/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"
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:244
+#, csharp-format
+msgid "{0} invites you to {1}"
+msgstr "{0} kutsuu sinut kanavalle {1}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:275
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1642
+msgid "away"
+msgstr "poissa"
+
+#. TRANSLATOR: {0} is the amount of seconds
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:281
+#, csharp-format
+msgid "lag: {0} seconds"
+msgstr "viive {0} sekuntia"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:287
+msgid "not connected"
+msgstr "ei yhteydessä"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:347
+#, csharp-format
+msgid "Using proxy: {0}:{1}"
+msgstr "Käytetään välityspalvelinta: {0}:{1}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:354
+#, csharp-format
+msgid "Connecting to {0} port {1}..."
+msgstr "Yhdistetään palvelimeen {0} porttiin {1}..."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:364
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:491
+#, csharp-format
+msgid "Connection to {0} established"
+msgstr "Yhteys palvelimeen {0} muodostettu"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:371
+msgid "Logging in..."
+msgstr "Kirjaudutaan sisään..."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:410
+msgid "Connection failed!"
+msgstr "Yhteydenmuodostus epäonnistui!"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:413
+msgid "Connection failed! Reason: "
+msgstr "Yhteydenmuodostus epäonnistui! Syy:"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:425
+msgid "Disconnecting..."
+msgstr "Katkaistaan..."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:429
+#, csharp-format
+msgid "Disconnecting from {0}..."
+msgstr "Katkaistaan yhteyttä palvelimeen {0}..."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:435
+#, csharp-format
+msgid "Disconnected from {0}"
+msgstr "Yhteys palvelimeen {0} katkaistu"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:440
+msgid "Connection closed"
+msgstr "Yhteys katkaistu"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:447
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:512
+msgid "Not connected"
+msgstr "Ei yhdistetty"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:478
+msgid "Reconnecting..."
+msgstr "Yhdistetään uudelleen..."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:485
+#, csharp-format
+msgid "Reconnecting to {0}..."
+msgstr "Yhdistetään uudelleen palvelimeen {0}..."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:502
+msgid "Reconnect Error"
+msgstr "Virhe uudelleenyhdistämisessä"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:846
+#, csharp-format
+msgid "Sleeping for {0} milliseconds"
+msgstr "Nukutaan {0} millisekuntia"
+
+#. TRANSLATOR: this line is used as label / category for a
+#. list of commands below
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:935
+msgid "IrcProtocolManager Commands"
+msgstr "IrcProtocolManager -komennot"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1008
+#, csharp-format
+msgid "Invalid port: {0}"
+msgstr "Epäkelpo portti: {0}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1109
+#, csharp-format
+msgid "Queuing joins: {0}"
+msgstr "Liittymisiä jonossa: {0}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1121
+#, csharp-format
+msgid "Already joined to channel: {0}. Type /window {0} to switch to it."
+msgstr "Kanava {0} on jo auki. Kirjoita /window {0} siirtyäksesi sinne."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1157
+#, csharp-format
+msgid "Active joins: {0} - Queued joins: {1}"
+msgstr "Aktiivisia liittymisiä: {0} - Liittymisiä jonossa: {1}"
+
+#. TRANSLATORS: final message will look like this:
+#. Joining: #chan1 - Remaining active joins: #chan2 / queued joins: #chan3
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1180
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1209
+#, csharp-format
+msgid "Joining: {0}"
+msgstr "Liitytään: {0}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1182
+msgid "Remaining"
+msgstr "Jäljellä"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1187
+#, csharp-format
+msgid "active joins: {0}"
+msgstr "aktiivisia liittymisiä: {0}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1196
+#, csharp-format
+msgid "queued joins: {0}"
+msgstr "liittymisiä jonossa: {0}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1629
+msgid "IRC Op"
+msgstr "IRC-operaattori"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1631
+msgid "Op"
+msgstr "Operaattori"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1633
+msgid "Voice"
+msgstr "Ääni"
+
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1696
+#, csharp-format
+msgid "Topic for {0}: {1}"
+msgstr "Aihe kanavalle {0}: {1}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1699
+#, csharp-format
+msgid "No topic set for {0}"
+msgstr "Ei aihetta kanavalle {0}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1781
+msgid "ban"
+msgstr "Porttikielto"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1792
+msgid "No bans in channel"
+msgstr "Ei porttikieltoja kanavalla"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1885
+#, csharp-format
+msgid "Your user mode is {0}"
+msgstr "Käyttäjätilasi on {0}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1906
+#, csharp-format
+msgid "Inviting {0} to {1}"
+msgstr "Kutsutaan {0} kanavalle {1}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1913
+#, csharp-format
+msgid "{0} is already on {1}"
+msgstr "{0} on jo kanavalla {1}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1940
+msgid "Users"
+msgstr "Käyttäjät"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1982
+#, csharp-format
+msgid "Total of {0} users [{1} ops, {2} voices, {3} normal]"
+msgstr "Yhteensä {0} käyttäjää [{1} operaattoria, {2} äänellistä, {3} normaalia]"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2118
+msgid "Connection error! Reason: "
+msgstr "Yhteysvirhe! Syy:"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2130
+#, csharp-format
+msgid "Not enough parameters for {0} command"
+msgstr "Ei tarpeeksi parametrejä komennolle {0}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2139
+msgid "Not connected to server"
+msgstr "Ei yhdistettynä palvelimelle"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2330
+#, csharp-format
+msgid "{0}: No such nick/channel"
+msgstr "{0}: Ei tällaista käyttäjää/kanavaa"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2455
+#, csharp-format
+msgid ""
+"Increased send delay to {0}ms to avoid being flooded off the server again."
+msgstr "Korotettiin lähetysviivettä {0}ms jotta vältytään ylivuotokatkaisulta jatkossa."
+
+#. TRANSLATOR: the final line will look like this:
+#. -!- Nick {0} is already in use
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2469
+msgid "Nick"
+msgstr "Lempinimi"
+
+#. TRANSLATOR: the final line will look like this:
+#. -!- Nick {0} is already in use
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2479
+msgid "is already in use"
+msgstr "on jo käytössä"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2489
+msgid "Cannot join to channel:"
+msgstr "Ei voi liittyä kanavalle:"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2497
+msgid "You are banned"
+msgstr "Sinulla on porttikielto"
+
+#. 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:2580
+#, csharp-format
+msgid "{0} [{1}] requested CTCP {2} from {3}: {4}"
+msgstr "{0} [{1}] teki CTCP {2} -pyynnön {3}: {4}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2607
+#, csharp-format
+msgid "CTCP PING reply from {0}: {1} seconds"
+msgstr "CTCP PING -vastaus käyttäjältä {0}: {1} sekuntia"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2616
+#, csharp-format
+msgid "CTCP {0} reply from {1}: {2}"
+msgstr "CTCP {0} -vastaus käyttäjältä {1}: {2}"
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2822
+#, csharp-format
+msgid "{0} [{1}] has joined {2}"
+msgstr "{0} [{1}] liittyi kanavalle {2}"
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2948
+#, csharp-format
+msgid "{0} [{1}] has left {2}"
+msgstr "{0} [{1}] on poistunut kanavalta {2}"
+
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2974
+#, csharp-format
+msgid "You were kicked from {0} by {1}"
+msgstr "{1} potkaisi sinut kanavalta {0}"
+
+#. TRANSLATOR: do NOT change the position of {0} and {2}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2985
+#, csharp-format
+msgid "{0} was kicked from {1} by {2}"
+msgstr "{0} poistettiin kanavalta {1} käyttäjän {2} toimesta"
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3005
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3038
+#, csharp-format
+msgid "You're now known as {0}"
+msgstr "Sinut tunnetaan nyt nimellä {0}"
+
+#. TRANSLATOR: do NOT change the position of {0} or {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3043
+#, csharp-format
+msgid "{0} is now known as {1}"
+msgstr "{0} on nyt nimeltään {1}"
+
+#. TRANSLATOR: do NOT change the position of {0} and {2}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3079
+#, csharp-format
+msgid "{0} changed the topic of {1} to: {2}"
+msgstr "{0} muutti kanavan {1} aiheeksi: {2}"
+
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3159
+#, csharp-format
+msgid "Mode change [{0}] for user {1}"
+msgstr "Tilan vaihto [{0}] käyttäjälle {1}"
+
+#. TRANSLATOR: do NOT change the position of {2}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3169
+#, csharp-format
+msgid "mode/{0} [{1}] by {2}"
+msgstr "tila/{0} [{1}] asettajana {2}"
+
+#. TRANSLATOR: do NOT change the position of {0}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3206
+#, csharp-format
+msgid "{0} [{1}] has quit"
+msgstr "{0} [{1}] lopetti"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3283
+#, csharp-format
+msgid ""
+"Connection to {0} port {1} has failed (attempt {2}), retrying in {3} "
+"seconds..."
+msgstr "Yhteys palvelimeen {0} portti {1} on epäonnistunut (yritys {2}), yritetään uudelleen {3} sekunnin kuluttua..."
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3333
+#, csharp-format
+msgid "{0} is away: {1}"
+msgstr "{0} on poissa: {1}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3343
+msgid "You are no longer marked as being away"
+msgstr "Poissaolomerkintä poistettu"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3353
+msgid "You have been marked as being away"
+msgstr "Poissaolomerkintä päällä"
diff --git a/po-Engine-IRC/fr.po b/po-Engine-IRC/fr.po
index 3ed0e19..83a2512 100644
--- a/po-Engine-IRC/fr.po
+++ b/po-Engine-IRC/fr.po
@@ -1,222 +1,237 @@
 # 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"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-04-10 21:37+0200\n"
+"PO-Revision-Date: 2013-04-10 22:29+0100\n"
+"Last-Translator: Clément Bourgeois <moonpyk at gmail.com>\n"
 "Language-Team: French (http://www.transifex.net/projects/p/smuxi/team/fr/)\n"
+"Language: 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"
 
 #. TRANSLATOR: do NOT change the position of {0}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:245
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:244
 #, 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
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:275
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1642
 msgid "away"
 msgstr "parti"
 
 #. TRANSLATOR: {0} is the amount of seconds
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:282
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:281
 #, csharp-format
 msgid "lag: {0} seconds"
 msgstr "lag : {0} secondes"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:288
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:287
 msgid "not connected"
 msgstr "non connecté"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:351
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:347
+#, csharp-format
+msgid "Using proxy: {0}:{1}"
+msgstr "Utilisation du proxy {0}:{1}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:354
 #, 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:357
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:463
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:364
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:491
 #, csharp-format
 msgid "Connection to {0} established"
 msgstr "Connexion au serveur {0} établie"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:360
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:371
 msgid "Logging in..."
 msgstr "Enregistrement en cours..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:394
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:410
 msgid "Connection failed!"
 msgstr "Connexion impossible !"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:395
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:413
 msgid "Connection failed! Reason: "
 msgstr "Connexion impossible ! Raison :"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:404
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:425
 msgid "Disconnecting..."
 msgstr "Déconnexion en cours..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:407
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:429
 #, csharp-format
 msgid "Disconnecting from {0}..."
 msgstr "Déconnexion de {0} en cours..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:412
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:435
 #, csharp-format
 msgid "Disconnected from {0}"
 msgstr "Déconnecté de {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:415
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:440
 msgid "Connection closed"
 msgstr "Connexion fermée"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:420
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:477
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:447
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:512
 msgid "Not connected"
 msgstr "Non connecté"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:449
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:478
 msgid "Reconnecting..."
 msgstr "Reconnexion en cours..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:457
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:485
 #, csharp-format
 msgid "Reconnecting to {0}..."
 msgstr "Reconnexion à {0} en cours..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:471
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:502
 msgid "Reconnect Error"
 msgstr "Erreur à la reconnexion"
 
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:846
+#, csharp-format
+msgid "Sleeping for {0} milliseconds"
+msgstr "Mis en pause pendant {0} millisecondes"
+
 #. TRANSLATOR: this line is used as label / category for a
 #. list of commands below
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:875
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:935
 msgid "IrcProtocolManager Commands"
 msgstr "Commandes IrcProtocolManager"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:943
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1008
 #, csharp-format
 msgid "Invalid port: {0}"
 msgstr "Port invalide : {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1047
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1109
 #, csharp-format
 msgid "Queuing joins: {0}"
 msgstr "Mise des en attente des inscriptions en cours : {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1061
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1121
 #, 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:1096
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1157
 #, 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:1119
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1150
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1180
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1209
 #, csharp-format
 msgid "Joining: {0}"
 msgstr "Raccordement : {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1121
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1182
 msgid "Remaining"
 msgstr "Restant"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1126
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1187
 #, csharp-format
 msgid "active joins: {0}"
 msgstr "raccordements actifs : {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1135
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1196
 #, csharp-format
 msgid "queued joins: {0}"
 msgstr "raccordements en attente : {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1506
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1629
 msgid "IRC Op"
 msgstr "Opérateur IRC"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1508
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1631
 msgid "Op"
 msgstr "Opérateur"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1510
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1633
 msgid "Voice"
 msgstr "Voicé"
 
 #. TRANSLATOR: do NOT change the position of {1}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1570
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1696
 #, csharp-format
 msgid "Topic for {0}: {1}"
 msgstr "Sujet de {0} : {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1575
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1699
 #, csharp-format
 msgid "No topic set for {0}"
 msgstr "Pas de sujet sélectionné pour {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1655
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1781
 msgid "ban"
 msgstr "ban"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1665
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1792
 msgid "No bans in channel"
 msgstr "Aucun utilisateur banni sur le canal"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1777
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1885
+#, csharp-format
+msgid "Your user mode is {0}"
+msgstr "Votre mode utilisateur est {0}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1906
 #, csharp-format
 msgid "Inviting {0} to {1}"
 msgstr "Invitation de {0} par {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1781
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1913
 #, csharp-format
 msgid "{0} is already on {1}"
 msgstr "{0} est déjà sur {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1806
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1940
 msgid "Users"
 msgstr "Utilisateurs"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1848
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1982
 #, 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:1979
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2118
 msgid "Connection error! Reason: "
 msgstr "Erreur de connexion ! Raison :"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1989
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2130
 #, 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:1999
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2139
 msgid "Not connected to server"
 msgstr "Non connecté au serveur"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2261
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2330
 #, csharp-format
 msgid "{0}: No such nick/channel"
 msgstr "{0}: Impossible de trouver le surnom/canal"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2390
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2455
 #, csharp-format
 msgid ""
 "Increased send delay to {0}ms to avoid being flooded off the server again."
@@ -226,21 +241,21 @@ msgstr ""
 
 #. TRANSLATOR: the final line will look like this:
 #. -!- Nick {0} is already in use
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2404
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2469
 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:2414
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2479
 msgid "is already in use"
 msgstr "est déjà en cours d'utilisation"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2424
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2489
 msgid "Cannot join to channel:"
 msgstr "Impossible de rejoindre le canal :"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2432
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2497
 msgid "You are banned"
 msgstr "Vous êtes banni"
 
@@ -248,81 +263,83 @@ 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:2508
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2580
 #, 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:2533
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2607
 #, 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:2541
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2616
 #, csharp-format
 msgid "CTCP {0} reply from {1}: {2}"
 msgstr "Réponse CTCP {0} de {1} : {2}"
 
 #. TRANSLATOR: do NOT change the position of {0}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2747
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2822
 #, csharp-format
 msgid "{0} [{1}] has joined {2}"
 msgstr "{0} [{1}] a rejoint {2}"
 
 #. TRANSLATOR: do NOT change the position of {0}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2873
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2948
 #, csharp-format
 msgid "{0} [{1}] has left {2}"
 msgstr "{0} [{1}] a quitté {2}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2898
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2974
 #, csharp-format
-msgid "You were kicked from {0} by {1} [{2}]"
-msgstr "Vous avez été kické du canal {0} par {1} [{2}]"
+msgid "You were kicked from {0} by {1}"
+msgstr "Vous avez été kické de {0} par {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2906
+#. TRANSLATOR: do NOT change the position of {0} and {2}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2985
 #, csharp-format
-msgid "{0} was kicked from {1} by {2} [{3}]"
-msgstr "{0} a été kické de {1} par {2} [{3}]"
+msgid "{0} was kicked from {1} by {2}"
+msgstr "{0} a été kické de {1} par {2}"
 
 #. TRANSLATOR: do NOT change the position of {0}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2923
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2956
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3005
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3038
 #, csharp-format
 msgid "You're now known as {0}"
 msgstr "Vous êtes maintenant connu en tant que {0}"
 
 #. TRANSLATOR: do NOT change the position of {0} or {1}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2961
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3043
 #, csharp-format
 msgid "{0} is now known as {1}"
 msgstr "{0} est maintenant connu en tant que {1}"
 
 #. TRANSLATOR: do NOT change the position of {0} and {2}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2998
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3079
 #, csharp-format
 msgid "{0} changed the topic of {1} to: {2}"
 msgstr "{0} a changé le sujet de {1} en : {2}"
 
 #. TRANSLATOR: do NOT change the position of {1}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3075
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3159
 #, csharp-format
 msgid "Mode change [{0}] for user {1}"
 msgstr "Changement de mode [{0}] pour l'utilisateur {1}"
 
 #. TRANSLATOR: do NOT change the position of {2}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3085
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3169
 #, csharp-format
 msgid "mode/{0} [{1}] by {2}"
 msgstr "mode/{0} [{1}] par {2}"
 
 #. TRANSLATOR: do NOT change the position of {0}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3122
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3206
 #, csharp-format
 msgid "{0} [{1}] has quit"
 msgstr "{0} [{1}] a quitté"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3199
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3283
 #, csharp-format
 msgid ""
 "Connection to {0} port {1} has failed (attempt {2}), retrying in {3} "
@@ -331,17 +348,15 @@ msgstr ""
 "La connexion vers {0}, port {1} a échoué (essai {2}), nouvel essai dans {3} "
 "secondes..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3248
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3333
 #, csharp-format
 msgid "{0} is away: {1}"
 msgstr "{0} est parti : {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3254
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3343
 msgid "You are no longer marked as being away"
 msgstr "Vous êtes marqué comme étant revenu"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3260
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3353
 msgid "You have been marked as being away"
 msgstr "Vous avez été marqué comme étant parti"
-
-
diff --git a/po-Engine-IRC/sv.po b/po-Engine-IRC/sv.po
index 02b0eff..d85a5f0 100644
--- a/po-Engine-IRC/sv.po
+++ b/po-Engine-IRC/sv.po
@@ -3,345 +3,355 @@
 # This file is distributed under the same license as the PACKAGE package.
 # 
 # Translators:
-#   <flugsio at gmail.com>, 2011.
+# flugsio <flugsio at gmail.com>, 2013
+# flugsio <flugsio at gmail.com>, 2011, 2012
 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-31 10:37+0000\n"
+"POT-Creation-Date: 2013-04-14 10:14+0200\n"
+"PO-Revision-Date: 2013-04-17 04:10+0000\n"
 "Last-Translator: flugsio <flugsio at gmail.com>\n"
-"Language-Team: Swedish (http://www.transifex.net/projects/p/smuxi/team/sv/)\n"
+"Language-Team: Swedish (http://www.transifex.com/projects/p/smuxi/language/sv/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Language: sv\n"
-"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
 #. TRANSLATOR: do NOT change the position of {0}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:245
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:244
 #, 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
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:275
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1642
 msgid "away"
 msgstr "borta"
 
 #. TRANSLATOR: {0} is the amount of seconds
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:282
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:281
 #, csharp-format
 msgid "lag: {0} seconds"
 msgstr "lagg: {0} sekunder"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:288
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:287
 msgid "not connected"
 msgstr "inte ansluten"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:351
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:347
+#, csharp-format
+msgid "Using proxy: {0}:{1}"
+msgstr "Använder proxy: {0}:{1}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:354
 #, csharp-format
 msgid "Connecting to {0} port {1}..."
 msgstr "Anluter till {0} port {1}..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:357
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:463
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:364
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:491
 #, csharp-format
 msgid "Connection to {0} established"
 msgstr "Anslutning till {0} upprättad"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:360
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:371
 msgid "Logging in..."
-msgstr "Logga in..."
+msgstr "Loggar in..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:394
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:410
 msgid "Connection failed!"
 msgstr "Anslutning misslyckades!"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:395
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:413
 msgid "Connection failed! Reason: "
 msgstr "Anslutning misslyckades! Anledning: "
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:404
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:425
 msgid "Disconnecting..."
-msgstr "Kopplar från..."
+msgstr "Kopplar ner..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:407
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:429
 #, csharp-format
 msgid "Disconnecting from {0}..."
-msgstr "Kopplar från {0}..."
+msgstr "Kopplar ner från {0}..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:412
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:435
 #, csharp-format
 msgid "Disconnected from {0}"
-msgstr "Anslutning bortkopplad från {0}"
+msgstr "Anslutning nerkopplad från {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:415
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:440
 msgid "Connection closed"
 msgstr "Anslutning stängd"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:420
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:477
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:447
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:512
 msgid "Not connected"
 msgstr "Inte ansluten"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:449
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:478
 msgid "Reconnecting..."
 msgstr "Ã…teransluter..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:457
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:485
 #, csharp-format
 msgid "Reconnecting to {0}..."
 msgstr "Ã…teransluter till {0}..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:471
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:502
 msgid "Reconnect Error"
 msgstr "Ã…teranslutningsfel"
 
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:846
+#, csharp-format
+msgid "Sleeping for {0} milliseconds"
+msgstr "Väntar i {0} millisekunder"
+
 #. TRANSLATOR: this line is used as label / category for a
 #. list of commands below
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:875
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:935
 msgid "IrcProtocolManager Commands"
 msgstr "Kommandon för IRC-protokollhanterare"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:943
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1008
 #, csharp-format
 msgid "Invalid port: {0}"
 msgstr "Felaktig port: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1047
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1109
 #, csharp-format
 msgid "Queuing joins: {0}"
 msgstr "Köar kanalanslutningar: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1061
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1121
 #, 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:1096
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1157
 #, 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:1119
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1150
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1180
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1209
 #, csharp-format
 msgid "Joining: {0}"
 msgstr "Ansluter till kanal: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1121
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1182
 msgid "Remaining"
-msgstr "Återstår"
+msgstr "Återstående"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1126
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1187
 #, csharp-format
 msgid "active joins: {0}"
 msgstr "aktiva kanalanslutningar: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1135
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1196
 #, csharp-format
 msgid "queued joins: {0}"
 msgstr "köade kanalanslutningar: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1506
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1629
 msgid "IRC Op"
 msgstr "IRC Operatör"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1508
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1631
 msgid "Op"
 msgstr "Operatör"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1510
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1633
 msgid "Voice"
 msgstr "Voice"
 
 #. TRANSLATOR: do NOT change the position of {1}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1570
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1696
 #, csharp-format
 msgid "Topic for {0}: {1}"
-msgstr "Rubrik för {0}: {1}"
+msgstr "Ämne för {0}: {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1575
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1699
 #, csharp-format
 msgid "No topic set for {0}"
-msgstr "Ingen rubrik satt för {0}"
+msgstr "Inget ämne satt för {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1655
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1781
 msgid "ban"
-msgstr "utestäng"
+msgstr "bannlys"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1665
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1792
 msgid "No bans in channel"
-msgstr "Ingen är utestängd ur kanalen"
+msgstr "Ingen är bannlyst ur kanalen"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1777
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1885
+#, csharp-format
+msgid "Your user mode is {0}"
+msgstr "Ditt användarläge är {0}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1906
 #, csharp-format
 msgid "Inviting {0} to {1}"
 msgstr "Bjuder in {0} till {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1781
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1913
 #, csharp-format
 msgid "{0} is already on {1}"
 msgstr "{0} är redan på {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1806
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1940
 msgid "Users"
 msgstr "Användare"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1848
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1982
 #, 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:1979
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2118
 msgid "Connection error! Reason: "
 msgstr "Fel i anslutning! Anledning: "
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1989
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2130
 #, 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:1999
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2139
 msgid "Not connected to server"
 msgstr "Inte ansluten till server"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2261
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2330
 #, csharp-format
 msgid "{0}: No such nick/channel"
 msgstr "{0}: Smeknamnet/kanalen finns inte"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2390
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2455
 #, 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."
+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:2404
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2469
 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:2414
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2479
 msgid "is already in use"
 msgstr "används redan"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2424
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2489
 msgid "Cannot join to channel:"
 msgstr "Kan inte ansluta till kanalen:"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2432
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2497
 msgid "You are banned"
-msgstr "Du är utestängd"
+msgstr "Du är bannlyst"
 
 #. 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
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2580
 #, 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:2533
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2607
 #, 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:2541
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2616
 #, csharp-format
 msgid "CTCP {0} reply from {1}: {2}"
 msgstr "CTCP {0}-svar från {1}: {2}"
 
 #. TRANSLATOR: do NOT change the position of {0}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2747
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2822
 #, csharp-format
 msgid "{0} [{1}] has joined {2}"
 msgstr "{0} [{1}] anslöt till {2}"
 
 #. TRANSLATOR: do NOT change the position of {0}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2873
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2948
 #, csharp-format
 msgid "{0} [{1}] has left {2}"
 msgstr "{0} [{1}] har lämnat {2}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2898
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2974
 #, csharp-format
-msgid "You were kicked from {0} by {1} [{2}]"
-msgstr "Du sparkades från {0} av {1} [{2}]"
+msgid "You were kicked from {0} by {1}"
+msgstr "Du sparkades från {0} av {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2906
+#. TRANSLATOR: do NOT change the position of {0} and {2}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2985
 #, csharp-format
-msgid "{0} was kicked from {1} by {2} [{3}]"
-msgstr "{0} sparkades från {1} av {2} [{3}]"
+msgid "{0} was kicked from {1} by {2}"
+msgstr "{0} blev sparkad från {1} av {2}"
 
 #. TRANSLATOR: do NOT change the position of {0}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2923
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2956
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3005
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3038
 #, csharp-format
 msgid "You're now known as {0}"
 msgstr "Du kallas numera {0}"
 
 #. TRANSLATOR: do NOT change the position of {0} or {1}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2961
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3043
 #, csharp-format
 msgid "{0} is now known as {1}"
 msgstr "{0} kallas numera {1}"
 
 #. TRANSLATOR: do NOT change the position of {0} and {2}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2998
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3079
 #, csharp-format
 msgid "{0} changed the topic of {1} to: {2}"
-msgstr "{0} bytte rubrik för {1} till: {2}"
+msgstr "{0} bytte ämne för {1} till: {2}"
 
 #. TRANSLATOR: do NOT change the position of {1}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3075
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3159
 #, csharp-format
 msgid "Mode change [{0}] for user {1}"
 msgstr "Ändrat användartillstånd [{0}] för användaren {1}"
 
 #. TRANSLATOR: do NOT change the position of {2}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3085
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3169
 #, csharp-format
 msgid "mode/{0} [{1}] by {2}"
 msgstr "användartillstånd/{0} [{1}] av {2}"
 
 #. TRANSLATOR: do NOT change the position of {0}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3122
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3206
 #, csharp-format
 msgid "{0} [{1}] has quit"
 msgstr "{0} [{1}] har avslutat"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3199
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3283
 #, 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..."
+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:3248
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3333
 #, csharp-format
 msgid "{0} is away: {1}"
 msgstr "{0} är borta: {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3254
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3343
 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:3260
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3353
 msgid "You have been marked as being away"
-msgstr "Du har markerats tom borta"
-
-
+msgstr "Du har markerats som borta"
diff --git a/po-Engine-IRC/zh_CN.po b/po-Engine-IRC/zh_CN.po
index 3d77f3c..280ad96 100644
--- a/po-Engine-IRC/zh_CN.po
+++ b/po-Engine-IRC/zh_CN.po
@@ -3,217 +3,233 @@
 # This file is distributed under the same license as the PACKAGE package.
 # 
 # Translators:
+# Dean Lee <xslidian at gmail.com>, 2012-2013.
 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"
+"POT-Creation-Date: 2013-04-14 10:14+0200\n"
+"PO-Revision-Date: 2013-04-14 14:03+0000\n"
+"Last-Translator: Dean Lee <xslidian at gmail.com>\n"
+"Language-Team: Chinese (China) (http://www.transifex.com/projects/p/smuxi/language/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"
+"Plural-Forms: nplurals=1; plural=0;\n"
 
 #. TRANSLATOR: do NOT change the position of {0}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:245
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:244
 #, 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
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:275
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1642
 msgid "away"
 msgstr "离开"
 
 #. TRANSLATOR: {0} is the amount of seconds
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:282
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:281
 #, csharp-format
 msgid "lag: {0} seconds"
 msgstr "延后: {0} 秒"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:288
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:287
 msgid "not connected"
 msgstr "未连接"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:351
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:347
+#, csharp-format
+msgid "Using proxy: {0}:{1}"
+msgstr "使用代理: {0}:{1}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:354
 #, 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
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:364
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:491
 #, csharp-format
 msgid "Connection to {0} established"
 msgstr "到 {0} 的连接已建立"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:360
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:371
 msgid "Logging in..."
 msgstr "正在登录..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:394
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:410
 msgid "Connection failed!"
 msgstr "连接失败!"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:395
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:413
 msgid "Connection failed! Reason: "
 msgstr "连接失败! 原因: "
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:404
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:425
 msgid "Disconnecting..."
 msgstr "正在断开连接..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:407
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:429
 #, csharp-format
 msgid "Disconnecting from {0}..."
 msgstr "正在从 {0} 断开连接..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:412
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:435
 #, csharp-format
 msgid "Disconnected from {0}"
 msgstr "已从 {0} 断开连接"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:415
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:440
 msgid "Connection closed"
 msgstr "连接已关闭"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:420
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:477
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:447
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:512
 msgid "Not connected"
 msgstr "未连接"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:449
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:478
 msgid "Reconnecting..."
 msgstr "正在重新连接..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:457
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:485
 #, csharp-format
 msgid "Reconnecting to {0}..."
 msgstr "正在重新连接到 {0}..."
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:471
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:502
 msgid "Reconnect Error"
 msgstr "重新连接出错"
 
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:846
+#, csharp-format
+msgid "Sleeping for {0} milliseconds"
+msgstr "睡眠 {0} 毫秒"
+
 #. TRANSLATOR: this line is used as label / category for a
 #. list of commands below
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:875
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:935
 msgid "IrcProtocolManager Commands"
 msgstr "IrcProtocolManager 命令"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:943
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1008
 #, csharp-format
 msgid "Invalid port: {0}"
 msgstr "端口无效: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1047
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1109
 #, csharp-format
 msgid "Queuing joins: {0}"
 msgstr "正等待加入: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1061
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1121
 #, 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
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1157
 #, 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
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1180
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1209
 #, csharp-format
 msgid "Joining: {0}"
 msgstr "正在加入: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1121
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1182
 msgid "Remaining"
 msgstr "剩余"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1126
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1187
 #, csharp-format
 msgid "active joins: {0}"
 msgstr "已经加入: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1135
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1196
 #, csharp-format
 msgid "queued joins: {0}"
 msgstr "等待加入: {0}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1506
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1629
 msgid "IRC Op"
 msgstr "IRC 版主"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1508
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1631
 msgid "Op"
 msgstr "版主"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1510
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1633
 msgid "Voice"
 msgstr "认证用户"
 
 #. TRANSLATOR: do NOT change the position of {1}!
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1570
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1696
 #, csharp-format
 msgid "Topic for {0}: {1}"
 msgstr "{0} 的主题: {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1575
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1699
 #, csharp-format
 msgid "No topic set for {0}"
 msgstr "{0} 尚未设定主题"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1655
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1781
 msgid "ban"
 msgstr "封禁"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1665
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1792
 msgid "No bans in channel"
 msgstr "频道内无被封禁用户"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1777
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1885
+#, csharp-format
+msgid "Your user mode is {0}"
+msgstr "您的用户模式为 {0}"
+
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1906
 #, csharp-format
 msgid "Inviting {0} to {1}"
 msgstr "正在邀请 {0} 加入 {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1781
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1913
 #, csharp-format
 msgid "{0} is already on {1}"
 msgstr "{0} 已在 {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1806
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1940
 msgid "Users"
 msgstr "用户"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1848
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1982
 #, 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
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2118
 msgid "Connection error! Reason: "
 msgstr "连接出错! 原因: "
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1989
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2130
 #, csharp-format
 msgid "Not enough parameters for {0} command"
 msgstr "{0} 命令参数不足"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:1999
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2139
 msgid "Not connected to server"
 msgstr "未连接到服务器"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2261
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2330
 #, csharp-format
 msgid "{0}: No such nick/channel"
 msgstr "{0}: 无此昵称/频道"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2390
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2455
 #, csharp-format
 msgid ""
 "Increased send delay to {0}ms to avoid being flooded off the server again."
@@ -221,21 +237,21 @@ 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
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2469
 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
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2479
 msgid "is already in use"
 msgstr "已被占用"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2424
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2489
 msgid "Cannot join to channel:"
 msgstr "无法加入频道:"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2432
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2497
 msgid "You are banned"
 msgstr "您已被封禁"
 
@@ -243,98 +259,98 @@ msgstr "您已被封禁"
 #. {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
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2580
 #, 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
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2607
 #, csharp-format
 msgid "CTCP PING reply from {0}: {1} seconds"
 msgstr "CTCP PING 回复来自 {0}: {1} 秒"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2541
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2616
 #, 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
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2822
 #, 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
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2948
 #, csharp-format
 msgid "{0} [{1}] has left {2}"
 msgstr "{0} [{1}] 已离开 {2}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2898
+#. TRANSLATOR: do NOT change the position of {1}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2974
 #, csharp-format
-msgid "You were kicked from {0} by {1} [{2}]"
-msgstr "您被 {1} [{2}] 从 {0} 踢出"
+msgid "You were kicked from {0} by {1}"
+msgstr "您被 {1} 从 {0} 踢出"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2906
+#. TRANSLATOR: do NOT change the position of {0} and {2}!
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:2985
 #, csharp-format
-msgid "{0} was kicked from {1} by {2} [{3}]"
-msgstr "{0} 被 {2} [{3}] 从 {1} 踢出"
+msgid "{0} was kicked from {1} by {2}"
+msgstr "{0} 被 {2} 从 {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
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3005
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3038
 #, 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
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3043
 #, 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
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3079
 #, 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
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3159
 #, 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
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3169
 #, 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
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3206
 #, csharp-format
 msgid "{0} [{1}] has quit"
 msgstr "{0} [{1}] 已退出"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3199
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3283
 #, 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
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3333
 #, csharp-format
 msgid "{0} is away: {1}"
 msgstr "{0} 离开: {1}"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3254
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3343
 msgid "You are no longer marked as being away"
 msgstr "您不再被标为离开状态"
 
-#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3260
+#: ../src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs:3353
 msgid "You have been marked as being away"
 msgstr "您已被标为离开状态"
-
-
diff --git a/po-Engine-Twitter/POTFILES.skip b/po-Engine-Twitter/POTFILES.skip
index e3ffa22..dfa80f9 100644
--- a/po-Engine-Twitter/POTFILES.skip
+++ b/po-Engine-Twitter/POTFILES.skip
@@ -1,6 +1,7 @@
 glade/
 src/Common/
 src/Engine/
+src/Engine-Campfire/
 src/Engine-IRC/
 src/Engine-MSNP/
 src/Engine-OSCAR/
diff --git a/po-Engine-Twitter/da.po b/po-Engine-Twitter/da.po
index 1d41785..035270b 100644
--- a/po-Engine-Twitter/da.po
+++ b/po-Engine-Twitter/da.po
@@ -3,173 +3,169 @@
 # This file is distributed under the same license as the PACKAGE package.
 # 
 # Translators:
-# Joe Hansen <joedalton2 at yahoo.dk>, 2011.
+# Joe Hansen <joedalton2 at yahoo.dk>, 2011,2013.
 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-29 19:50+0000\n"
+"POT-Creation-Date: 2013-04-14 10:15+0200\n"
+"PO-Revision-Date: 2013-04-16 06:16+0000\n"
 "Last-Translator: Joe Hansen <joedalton2 at yahoo.dk>\n"
-"Language-Team: Danish (http://www.transifex.net/projects/p/smuxi/team/da/)\n"
+"Language-Team: Danish (http://www.transifex.com/projects/p/smuxi/language/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"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:124
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:127
 msgid "Home Timeline"
 msgstr "Hjemmetidslinje"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:135
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:138
 msgid "Replies"
 msgstr "Svar"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:146
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:149
 msgid "Direct Messages"
 msgstr "Direkte beskeder"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:189
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:197
+#, csharp-format
+msgid "Using proxy: {0}:{1}"
+msgstr "Bruger proxy: {0}:{1}"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:204
 msgid "Connecting to Twitter..."
 msgstr "Tilslutter til Twitter..."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:228
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:242
 msgid "Twitter authorization required."
 msgstr "Twittergodkendelse krævet."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:235
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:249
 #, 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}"
+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
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:265
 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."
+msgstr "Når du har tilladt Smuxi at tilgå din Twitterkonto, vil Twitter tilbyde en PIN."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:258
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:272
 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
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:279
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:319
 msgid "Connection failed!"
 msgstr "Tilslutning mislykkedes!"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:267
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:307
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:281
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:321
 msgid "Connection failed! Reason: "
 msgstr "Tilslutning mislykkedes! Ã…rsag: "
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:280
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:294
 msgid "Fetching user details from Twitter, please wait..."
 msgstr "Henter brugerdetaljer fra Twitter, vent venligst..."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:285
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:299
 msgid "Finished fetching user details."
 msgstr "Færdig med hentning af brugerdetaljer."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:290
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:304
 msgid "Successfully connected to Twitter."
 msgstr "Tilsluttet Twitter."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:299
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:313
 msgid "Failed to fetch user details from Twitter. Reason: "
 msgstr "Kunne ikke hente brugerdetaljer fra Twitter. Ã…rsag: "
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:320
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:334
 msgid "Fetching friends from Twitter, please wait..."
 msgstr "Henter venneliste fra Twitter, vent venligst..."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:325
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:339
 msgid "Finished fetching friends."
 msgstr "Afsluttede hentning af venneliste."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:328
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:342
 msgid "Failed to fetch friends from Twitter. Reason: "
 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:605
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:619
 msgid "Twitter Commands"
 msgstr "Twitterkommandoer"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:647
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:661
 msgid "No pending authorization request!"
 msgstr "Ingen igangværende godkendelsesforespørgsel!"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:668
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:682
 #, 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
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:690
 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
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:698
 #, 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«."
+msgstr "Forsøg igen ved at lukke dette faneblad og forbinde igen til Twitter »{0}-kontoen«."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:725
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:739
 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
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:753
 #, csharp-format
 msgid "Successfully authorized Twitter account \"{0}\" for Smuxi"
 msgstr "Godkendte Twitterkonto »{0}« til Smuxi"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:761
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:775
 #, csharp-format
 msgid "Could not update status - Reason: {0}"
 msgstr "Kunne ikke opdatere status - årsag: {0}"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:770
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:784
 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:783
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:820
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:797
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:834
 #, csharp-format
 msgid "Could not send message - Reason: {0}"
 msgstr "Kunne ikke sende besked - årsag: {0}"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:807
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:821
 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:896
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:910
 msgid ""
 "An error occurred while fetching the friends timeline from Twitter. Reason: "
 msgstr "En fejl opstod under hentning af vennetidslinjen fra Twitter. Ã…rsag: "
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1001
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1017
 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:1097
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1113
 msgid ""
 "An error occurred while fetching direct messages from Twitter. Reason: "
-msgstr ""
-"En fejl opstod under hentning af direkte beskeder fra Twitter. Ã…rsag: "
+msgstr "En fejl opstod under hentning af direkte beskeder fra Twitter. Ã…rsag: "
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1441
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1457
 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 a9d997e..918c548 100644
--- a/po-Engine-Twitter/de.po
+++ b/po-Engine-Twitter/de.po
@@ -3,183 +3,169 @@
 # This file is distributed under the same license as the PACKAGE package.
 # 
 # Translators:
-# Bianca Mix <heavydemon at freenet.de>, 2011.
+# Bianca Mix <heavydemon at freenet.de>, 2011,2013.
 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 22:59+0000\n"
+"POT-Creation-Date: 2013-04-14 10:15+0200\n"
+"PO-Revision-Date: 2013-04-14 19:27+0000\n"
 "Last-Translator: Bianca Mix <heavydemon at freenet.de>\n"
-"Language-Team: German (http://www.transifex.net/projects/p/smuxi/team/de/)\n"
+"Language-Team: German (http://www.transifex.com/projects/p/smuxi/language/de/)\n"
 "MIME-Version: 1.0\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"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:124
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:127
 msgid "Home Timeline"
 msgstr "Zuhause Zeitachse"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:135
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:138
 msgid "Replies"
 msgstr "Antworten"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:146
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:149
 msgid "Direct Messages"
 msgstr "Direktnachrichten"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:189
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:197
+#, csharp-format
+msgid "Using proxy: {0}:{1}"
+msgstr "Benutze Proxy: {0}:{1}"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:204
 msgid "Connecting to Twitter..."
 msgstr "Verbinde zu Twitter..."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:228
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:242
 msgid "Twitter authorization required."
 msgstr "Twitter Autorisierung erfolgreich"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:235
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:249
 #, 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}"
+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:251
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:265
 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"
+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
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:272
 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
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:279
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:319
 msgid "Connection failed!"
 msgstr "Verbindung ist fehlgeschlagen!"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:267
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:307
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:281
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:321
 msgid "Connection failed! Reason: "
 msgstr "Verbindung ist fehlgeschlagen! Grund: "
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:280
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:294
 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:285
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:299
 msgid "Finished fetching user details."
 msgstr "Abrufen der Benutzerinformationen abgeschlossen."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:290
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:304
 msgid "Successfully connected to Twitter."
 msgstr "Erfolgreich zu Twitter verbunden."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:299
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:313
 msgid "Failed to fetch user details from Twitter. Reason: "
 msgstr "Abrufen der Benutzerinformationen fehlgeschlagen. Grund:"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:320
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:334
 msgid "Fetching friends from Twitter, please wait..."
 msgstr "Rufe Freunde von Twitter ab, bitte warten Sie..."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:325
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:339
 msgid "Finished fetching friends."
 msgstr "Abrufen der Freunde abgeschlossen."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:328
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:342
 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:605
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:619
 msgid "Twitter Commands"
 msgstr "Twitter Befehle"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:647
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:661
 msgid "No pending authorization request!"
 msgstr "Keine ausstehenden Autorisierungsanfragen!"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:668
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:682
 #, csharp-format
 msgid "Failed to authorize with Twitter: {0}"
 msgstr "Autorisierung gegenüber Twitter fehlgeschlagen: {0}"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:676
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:690
 msgid "Twitter did not accept your PIN.  Did you enter it correctly?"
-msgstr ""
-"Twitter hat Ihre PIN nicht akzeptiert. Haben Sie sie korrekt eingegeben?"
+msgstr "Twitter hat Ihre PIN nicht akzeptiert. Haben Sie sie korrekt eingegeben?"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:684
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:698
 #, 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."
+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
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:739
 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
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:753
 #, 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
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:775
 #, csharp-format
 msgid "Could not update status - Reason: {0}"
 msgstr "Konnte den Status nicht aktualisieren - Ursache: {0}"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:770
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:784
 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:783
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:820
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:797
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:834
 #, csharp-format
 msgid "Could not send message - Reason: {0}"
 msgstr "Konnte Nachricht nicht senden - Ursache: {0}"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:807
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:821
 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:896
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:910
 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:"
+msgstr "Ein Fehler ist aufgetreten, während die Freunde Zeitachse von Twitter abgerufen wurde. Grund:"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1001
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1017
 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
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1113
 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:"
+msgstr "Während des Abrufens der Direktenachrichten von Twitter ist ein Fehler aufgetreten. Grund:"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1441
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1457
 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."
-
-
+msgstr "Twitter hat keine gültige Antwort gesendet. Der Dienst ist womöglich überbeansprucht."
diff --git a/po-Engine-Twitter/fr.po b/po-Engine-Twitter/fr.po
index 8261402..2de3b6d 100644
--- a/po-Engine-Twitter/fr.po
+++ b/po-Engine-Twitter/fr.po
@@ -1,44 +1,49 @@
 # 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 - 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"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-04-10 21:38+0200\n"
+"PO-Revision-Date: 2013-04-10 22:27+0100\n"
 "Last-Translator: Clément Bourgeois <moonpyk at gmail.com>\n"
 "Language-Team: French (http://www.transifex.net/projects/p/smuxi/team/fr/)\n"
+"Language: 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/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:124
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:127
 msgid "Home Timeline"
 msgstr "Chronologie générale"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:135
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:138
 msgid "Replies"
 msgstr "Réponses"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:146
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:149
 msgid "Direct Messages"
 msgstr "Messages directs"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:189
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:197
+#, csharp-format
+msgid "Using proxy: {0}:{1}"
+msgstr "Utilisation du proxy: {0}:{1}"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:204
 msgid "Connecting to Twitter..."
 msgstr "Connexion à Twitter..."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:228
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:242
 msgid "Twitter authorization required."
 msgstr "Autorisation de Twitter nécessaire"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:235
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:249
 #, csharp-format
 msgid ""
 "Please open the following URL and click \"Allow\" to allow Smuxi to connect "
@@ -47,7 +52,7 @@ 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
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:265
 msgid ""
 "Once you have allowed Smuxi to access your Twitter account, Twitter will "
 "provide a PIN."
@@ -55,71 +60,70 @@ msgstr ""
 "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
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:272
 msgid "Please type: /pin PIN_FROM_TWITTER"
 msgstr "Veuillez taper : /pin CODE_PIN_DE_TWITTER"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:265
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:305
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:279
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:319
 msgid "Connection failed!"
 msgstr "Connexion impossible !"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:267
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:307
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:281
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:321
 msgid "Connection failed! Reason: "
 msgstr "Connexion impossible ! Raison : "
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:280
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:294
 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:285
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:299
 msgid "Finished fetching user details."
 msgstr "Téléchargement des détails utilisateur terminée."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:290
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:304
 msgid "Successfully connected to Twitter."
 msgstr "Connexion à Twitter réussie."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:299
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:313
 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:320
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:334
 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:325
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:339
 msgid "Finished fetching friends."
 msgstr "Téléchargement de la liste des amis terminée."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:328
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:342
 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:605
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:619
 msgid "Twitter Commands"
 msgstr "Commandes Twitter"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:647
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:661
 msgid "No pending authorization request!"
 msgstr "Aucune requête d'autorisation en attente !"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:668
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:682
 #, 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
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:690
 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
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:698
 #, csharp-format
 msgid ""
 "Please retry by closing this tab and reconnecting to the Twitter \"{0}\" "
@@ -128,62 +132,59 @@ 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
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:739
 msgid "Migrated Twitter account from basic auth to OAuth."
 msgstr ""
-"Le compte Twitter géré par autorisation basique à été migré la methode "
-"OAuth."
+"Le compte Twitter géré par autorisation basique à été migré la methode OAuth."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:739
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:753
 #, csharp-format
 msgid "Successfully authorized Twitter account \"{0}\" for Smuxi"
-msgstr "Twitter a accepté la demande d'autorisation Smuxi pour le compte \"{0}\"."
+msgstr ""
+"Twitter a accepté la demande d'autorisation Smuxi pour le compte \"{0}\"."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:761
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:775
 #, 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:770
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:784
 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:783
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:820
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:797
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:834
 #, csharp-format
 msgid "Could not send message - Reason: {0}"
 msgstr "Impossible d'envoyer le message - Raison : {0}"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:807
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:821
 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:896
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:910
 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:1001
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1017
 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:1097
-msgid ""
-"An error occurred while fetching direct messages from Twitter. Reason: "
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1113
+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
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1457
 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/sv.po b/po-Engine-Twitter/sv.po
index 966ae26..c15e05d 100644
--- a/po-Engine-Twitter/sv.po
+++ b/po-Engine-Twitter/sv.po
@@ -3,178 +3,170 @@
 # This file is distributed under the same license as the PACKAGE package.
 # 
 # Translators:
-#   <flugsio at gmail.com>, 2011.
+# flugsio <flugsio at gmail.com>, 2013
+# flugsio <flugsio 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-31 11:10+0000\n"
+"POT-Creation-Date: 2013-04-14 10:15+0200\n"
+"PO-Revision-Date: 2013-04-17 04:23+0000\n"
 "Last-Translator: flugsio <flugsio at gmail.com>\n"
-"Language-Team: Swedish (http://www.transifex.net/projects/p/smuxi/team/sv/)\n"
+"Language-Team: Swedish (http://www.transifex.com/projects/p/smuxi/language/sv/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Language: sv\n"
-"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:124
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:127
 msgid "Home Timeline"
 msgstr "Hem Tidslinje"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:135
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:138
 msgid "Replies"
 msgstr "Svar"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:146
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:149
 msgid "Direct Messages"
 msgstr "Direktmeddelanden"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:189
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:197
+#, csharp-format
+msgid "Using proxy: {0}:{1}"
+msgstr "Använder proxy: {0}:{1}"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:204
 msgid "Connecting to Twitter..."
 msgstr "Ansluter till Twitter..."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:228
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:242
 msgid "Twitter authorization required."
 msgstr "Inloggning till Twitter krävs."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:235
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:249
 #, 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}"
+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
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:265
 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."
+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:258
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:272
 msgid "Please type: /pin PIN_FROM_TWITTER"
 msgstr "Vänligen skriv: /pin PIN_KOD_FRÅN_TWITTER"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:265
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:305
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:279
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:319
 msgid "Connection failed!"
 msgstr "Anslutning misslyckades!"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:267
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:307
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:281
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:321
 msgid "Connection failed! Reason: "
 msgstr "Anslutning misslyckades! Anledning: "
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:280
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:294
 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:285
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:299
 msgid "Finished fetching user details."
 msgstr "Hämtade användarinformation."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:290
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:304
 msgid "Successfully connected to Twitter."
 msgstr "Ansluten till Twitter."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:299
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:313
 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:320
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:334
 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:325
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:339
 msgid "Finished fetching friends."
 msgstr "Hämtade vänner."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:328
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:342
 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:605
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:619
 msgid "Twitter Commands"
 msgstr "Twitter-kommandon"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:647
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:661
 msgid "No pending authorization request!"
 msgstr "Ingen pågående auktoriseringsansökan!"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:668
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:682
 #, csharp-format
 msgid "Failed to authorize with Twitter: {0}"
 msgstr "Misslyckades att autorisera med Twitter: {0}"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:676
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:690
 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
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:698
 #, 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}\"."
+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
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:739
 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
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:753
 #, 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
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:775
 #, csharp-format
 msgid "Could not update status - Reason: {0}"
 msgstr "Kunde inte uppdatera status - Anledning: {0}"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:770
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:784
 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:783
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:820
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:797
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:834
 #, csharp-format
 msgid "Could not send message - Reason: {0}"
 msgstr "Kunde inte skicka meddelande - Anledning: {0}"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:807
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:821
 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:896
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:910
 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:1001
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1017
 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:1097
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1113
 msgid ""
 "An error occurred while fetching direct messages from Twitter. Reason: "
-msgstr ""
-"Ett fel uppstod vid hämtning av direktmeddelanden från Twitter. Anledning: "
+msgstr "Ett fel uppstod vid hämtning av direktmeddelanden från Twitter. Anledning: "
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1441
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1457
 msgid "Twitter didn't send a valid response, they're probably overloaded"
-msgstr ""
-"Twitter skickade inte ett giltigt svar, de är antagligen överbelastade"
-
-
+msgstr "Twitter skickade inte ett giltigt svar, de är antagligen överbelastade"
diff --git a/po-Engine-Twitter/zh_CN.po b/po-Engine-Twitter/zh_CN.po
index 0bb2246..e01e2f9 100644
--- a/po-Engine-Twitter/zh_CN.po
+++ b/po-Engine-Twitter/zh_CN.po
@@ -3,166 +3,169 @@
 # This file is distributed under the same license as the PACKAGE package.
 # 
 # Translators:
-# Dean Lee <xslidian at gmail.com>, 2011.
+# Dean Lee <xslidian at gmail.com>, 2011,2013.
 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"
+"POT-Creation-Date: 2013-04-14 10:15+0200\n"
+"PO-Revision-Date: 2013-04-14 13:57+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"
+"Language-Team: Chinese (China) (http://www.transifex.com/projects/p/smuxi/language/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"
+"Plural-Forms: nplurals=1; plural=0;\n"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:124
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:127
 msgid "Home Timeline"
 msgstr "主时间线"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:135
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:138
 msgid "Replies"
 msgstr "回复"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:146
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:149
 msgid "Direct Messages"
 msgstr "私信"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:189
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:197
+#, csharp-format
+msgid "Using proxy: {0}:{1}"
+msgstr "使用代理: {0}:{1}"
+
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:204
 msgid "Connecting to Twitter..."
 msgstr "正在连接到 Twitter..."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:228
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:242
 msgid "Twitter authorization required."
 msgstr "需要 Twitter 认证。"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:235
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:249
 #, 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
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:265
 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
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:272
 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
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:279
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:319
 msgid "Connection failed!"
 msgstr "连接失败!"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:267
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:307
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:281
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:321
 msgid "Connection failed! Reason: "
 msgstr "连接失败! 原因: "
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:280
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:294
 msgid "Fetching user details from Twitter, please wait..."
 msgstr "正在从 Twitter 装载用户详细信息,请稍候..."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:285
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:299
 msgid "Finished fetching user details."
 msgstr "装载用户详细信息完成。"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:290
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:304
 msgid "Successfully connected to Twitter."
 msgstr "成功连接到 Twitter。"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:299
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:313
 msgid "Failed to fetch user details from Twitter. Reason: "
 msgstr "从 Twitter 装载用户详细信息失败。原因: "
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:320
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:334
 msgid "Fetching friends from Twitter, please wait..."
 msgstr "正在从 Twitter 装载好友,请稍候..."
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:325
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:339
 msgid "Finished fetching friends."
 msgstr "装载好友完成。"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:328
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:342
 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
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:619
 msgid "Twitter Commands"
 msgstr "Twitter 命令"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:647
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:661
 msgid "No pending authorization request!"
 msgstr "无待处理的认证请求!"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:668
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:682
 #, csharp-format
 msgid "Failed to authorize with Twitter: {0}"
 msgstr "Twitter 认证失败: {0}"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:676
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:690
 msgid "Twitter did not accept your PIN.  Did you enter it correctly?"
 msgstr "Twitter 不接受您提供的 PIN。您是否已经正确输入?"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:684
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:698
 #, 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
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:739
 msgid "Migrated Twitter account from basic auth to OAuth."
 msgstr "Twitter 账户已从 basic auth 迁移至 OAuth。"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:739
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:753
 #, csharp-format
 msgid "Successfully authorized Twitter account \"{0}\" for Smuxi"
 msgstr "Smuxi 成功认证 Twitter 账户 \"{0}\""
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:761
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:775
 #, csharp-format
 msgid "Could not update status - Reason: {0}"
 msgstr "无法更新状态 - 原因: {0}"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:770
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:784
 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
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:797
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:834
 #, csharp-format
 msgid "Could not send message - Reason: {0}"
 msgstr "无法发送信息 - 原因: {0}"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:807
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:821
 msgid "Could not send message - the specified user does not exist."
 msgstr "无法发送信息 - 指定用户不存在。"
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:896
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:910
 msgid ""
 "An error occurred while fetching the friends timeline from Twitter. Reason: "
 msgstr "从 Twitter 装载好友时间线失败。原因: "
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1001
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1017
 msgid "An error occurred while fetching the replies from Twitter. Reason: "
 msgstr "从 Twitter 装载回复失败。原因: "
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1097
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1113
 msgid ""
 "An error occurred while fetching direct messages from Twitter. Reason: "
 msgstr "从 Twitter 装载私信失败。原因: "
 
-#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1441
+#: ../src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs:1457
 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 9456ea6..770cabe 100644
--- a/po-Engine/LINGUAS
+++ b/po-Engine/LINGUAS
@@ -4,6 +4,7 @@ de
 en_GB
 es
 es_AR
+fi
 fr
 hr
 it
diff --git a/po-Engine/POTFILES.skip b/po-Engine/POTFILES.skip
index 7f8925d..8931ca8 100644
--- a/po-Engine/POTFILES.skip
+++ b/po-Engine/POTFILES.skip
@@ -6,6 +6,8 @@ src/Frontend-GNOME-IRC/
 src/Frontend-STFL/
 src/Frontend-SWF/
 src/Frontend-WPF/
+src/Engine/Config/ServerModel.cs
+src/Engine-Campfire/
 src/Engine-IRC/
 src/Engine-MSNP/
 src/Engine-OSCAR/
diff --git a/po-Engine/da.po b/po-Engine/da.po
index dbb7535..5d026ac 100644
--- a/po-Engine/da.po
+++ b/po-Engine/da.po
@@ -3,20 +3,20 @@
 # This file is distributed under the same license as the PACKAGE package.
 # 
 # Translators:
-# Joe Hansen <joedalton2 at yahoo.dk>, 2011, 2012.
+# Joe Hansen <joedalton2 at yahoo.dk>, 2011-2013.
 msgid ""
 msgstr ""
 "Project-Id-Version: Smuxi - IRC client\n"
 "Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
-"POT-Creation-Date: 2012-01-01 18:47+0100\n"
-"PO-Revision-Date: 2012-01-07 10:33+0000\n"
+"POT-Creation-Date: 2013-04-14 10:13+0200\n"
+"PO-Revision-Date: 2013-04-16 06:28+0000\n"
 "Last-Translator: Joe Hansen <joedalton2 at yahoo.dk>\n"
-"Language-Team: Danish (http://www.transifex.net/projects/p/smuxi/team/da/)\n"
+"Language-Team: Danish (http://www.transifex.com/projects/p/smuxi/language/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"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
 #: ../src/Engine/FrontendManager.cs:233
 msgid "No network connections"
@@ -36,143 +36,148 @@ msgstr "Kunne ikke optimere: {0}. Ã…rsag: {1}"
 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."
+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
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:166
 msgid "Not connected to server"
 msgstr "Ikke forbundet til server"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:178
-#: ../src/Engine/Session.cs:778
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:174
+#: ../src/Engine/Session.cs:846
 #, csharp-format
 msgid "Not enough parameters for {0} command"
 msgstr "Ikke nok parametre for kommandoen {0}"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:189
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:185
 #, csharp-format
 msgid "Connected to {0}"
 msgstr "Forbundet til {0}"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:207
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:203
 #, csharp-format
 msgid "Disconnected from {0}"
 msgstr "Ikke længere forbundet til {0}"
 
-#: ../src/Engine/Session.cs:218
+#: ../src/Engine/Session.cs:217
 #, 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:416
+#: ../src/Engine/Session.cs:415
 msgid "Engine Commands"
 msgstr "Motorkommandoer"
 
-#: ../src/Engine/Session.cs:527
+#: ../src/Engine/Session.cs:540
 msgid "Connect failed!"
 msgstr "Tilslutning mislykkedes!"
 
-#: ../src/Engine/Session.cs:550
+#: ../src/Engine/Session.cs:563
 #, csharp-format
 msgid "Disconnect failed - could not find server: {0}"
 msgstr "Afbrydelse fejlede - kunne ikke finde server: {0}"
 
-#: ../src/Engine/Session.cs:589
+#: ../src/Engine/Session.cs:603
 msgid "Reconnect failed!"
 msgstr "Gentilslutning mislykkedes!"
 
-#: ../src/Engine/Session.cs:608
+#: ../src/Engine/Session.cs:625
 msgid "Configuration reloaded"
 msgstr "Konfiguration genindlæst"
 
-#: ../src/Engine/Session.cs:613
+#: ../src/Engine/Session.cs:629
 msgid "Configuration saved"
 msgstr "Konfiguration gemt"
 
-#: ../src/Engine/Session.cs:617
+#: ../src/Engine/Session.cs:633
 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:676
+#: ../src/Engine/Session.cs:702
 msgid "Invalid parameter for network; use list, switch, or close"
-msgstr ""
-"Ugyldigt parameter for netværk; brug list (vis), switch (skift) eller close "
-"(luk)"
+msgstr "Ugyldigt parameter for netværk; brug list (vis), switch (skift) eller close (luk)"
 
-#: ../src/Engine/Session.cs:687
-msgid "Networks"
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of networks below
+#: ../src/Engine/Session.cs:733
+msgid "Connected Networks"
+msgstr "Forbundne netværk"
+
+#: ../src/Engine/Session.cs:738 ../src/Engine/Session.cs:762
+msgid "Network"
 msgstr "Netværk"
 
-#: ../src/Engine/Session.cs:691
+#: ../src/Engine/Session.cs:739
 msgid "Protocol"
 msgstr "Protokol"
 
-#: ../src/Engine/Session.cs:692
-msgid "Network"
-msgstr "Netværk"
-
-#: ../src/Engine/Session.cs:693
+#: ../src/Engine/Session.cs:740
 msgid "Host"
 msgstr "Vært"
 
-#: ../src/Engine/Session.cs:694
+#: ../src/Engine/Session.cs:741
 msgid "Port"
 msgstr "Port"
 
-#: ../src/Engine/Session.cs:709
+#. TRANSLATOR: no connected networks
+#. TRANSLATOR: no available networks
+#: ../src/Engine/Session.cs:747 ../src/Engine/Session.cs:768
+msgid "None"
+msgstr "Ingen"
+
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of networks below
+#: ../src/Engine/Session.cs:754
+msgid "Available Networks"
+msgstr "Tilgængelige netværk"
+
+#: ../src/Engine/Session.cs:783
 #, csharp-format
 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:748
+#: ../src/Engine/Session.cs:821
 #, csharp-format
 msgid "Network switch failed - could not find network: {0}"
 msgstr "Netværksomskifter fejlede - kunne ikke finde netværk: {0}"
 
-#: ../src/Engine/Session.cs:767
+#: ../src/Engine/Session.cs:839
 msgid "Not connected to any network"
 msgstr "Ikke tilsluttet til noget netværk"
 
-#: ../src/Engine/Session.cs:1013
+#: ../src/Engine/Session.cs:1093
 #, 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}"
+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:1185
+#: ../src/Engine/Session.cs:1266
 msgid "Connect failed."
 msgstr "Tilslutning mislykkedes."
 
-#: ../src/Engine/Session.cs:1216
+#: ../src/Engine/Session.cs:1297
 #, 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
+#: ../src/Engine/Session.cs:1529
 msgid "Welcome to Smuxi"
 msgstr "Velkommen til Smuxi"
 
-#: ../src/Engine/Session.cs:1455
+#: ../src/Engine/Session.cs:1536
 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
+#: ../src/Engine/Session.cs:1542
 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."
+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."
@@ -192,35 +197,33 @@ msgstr "Bruger »{0}« findes ikke."
 msgid "User \"{0}\" already exists."
 msgstr "Bruger »{0}« findes allerede."
 
-#: ../src/Engine/Config/ServerListController.cs:131
+#: ../src/Engine/Config/ServerListController.cs:118
+msgid "Network must not be empty."
+msgstr "Netværk må ikke være tomt."
+
+#: ../src/Engine/Config/ServerListController.cs:138
 msgid "Server hostname must not be empty."
 msgstr "Serverværtsnavn må ikke være tomt."
 
-#: ../src/Engine/Config/ServerListController.cs:134
+#: ../src/Engine/Config/ServerListController.cs:141
 msgid "Server hostname contains invalid characters (newline)."
 msgstr "Serverværtsnavn indeholder ugyldige tegn (nylinje)."
 
-#: ../src/Engine/Config/ServerListController.cs:140
+#: ../src/Engine/Config/ServerListController.cs:148
 #, csharp-format
-msgid "Server '{0}' already exists."
-msgstr "Server '{0}' findes allerede."
+msgid "Server ID '{0}' already exists."
+msgstr "Server-id »{0}« findes allerede."
 
 #: ../src/Engine/Chats/ChatModel.cs:105
 #, csharp-format
 msgid ""
 "Failed to load chat history. Your chat history will not be preserved. "
 "Reason: {0}"
-msgstr ""
-"Kunne ikke indlæse snakkehistorik. Din snakkehistorik vil ikke blive "
-"bevaret. Ã…rsag: {0}"
+msgstr "Kunne ikke indlæse snakkehistorik. Din snakkehistorik vil ikke blive bevaret. Årsag: {0}"
 
-#: ../src/Engine/Chats/ChatModel.cs:290
+#: ../src/Engine/Chats/ChatModel.cs:298
 #, csharp-format
 msgid ""
 "Failed to open chat history for writing. Your chat history will not be "
 "preserved. Reason: {0}"
-msgstr ""
-"Kunne ikke åbne snakkehistorik for skrivning. Din snakkehistorik vil ikke "
-"blive bevaret. Ã…rsag: {0}"
-
-
+msgstr "Kunne ikke åbne snakkehistorik for skrivning. Din snakkehistorik vil ikke blive bevaret. Årsag: {0}"
diff --git a/po-Engine/de.po b/po-Engine/de.po
index 313ea7b..9101a14 100644
--- a/po-Engine/de.po
+++ b/po-Engine/de.po
@@ -3,20 +3,20 @@
 # This file is distributed under the same license as the PACKAGE package.
 # 
 # Translators:
-# Bianca Mix <heavydemon at freenet.de>, 2011.
+# Bianca Mix <heavydemon at freenet.de>, 2011-2013.
 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 22:34+0000\n"
+"POT-Creation-Date: 2013-04-14 10:13+0200\n"
+"PO-Revision-Date: 2013-04-14 19:44+0000\n"
 "Last-Translator: Bianca Mix <heavydemon at freenet.de>\n"
-"Language-Team: German (http://www.transifex.net/projects/p/smuxi/team/de/)\n"
+"Language-Team: German (http://www.transifex.com/projects/p/smuxi/language/de/)\n"
 "MIME-Version: 1.0\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"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
 #: ../src/Engine/FrontendManager.cs:233
 msgid "No network connections"
@@ -36,149 +36,148 @@ msgstr "Optimierung fehlgeschlagen: {0}. Grund: {1}"
 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."
+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
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:166
 msgid "Not connected to server"
 msgstr "Nicht mit dem Server verbunden"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:178
-#: ../src/Engine/Session.cs:778
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:174
+#: ../src/Engine/Session.cs:846
 #, csharp-format
 msgid "Not enough parameters for {0} command"
 msgstr "Nicht genügend Parameter für den Befehl: {0}"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:189
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:185
 #, csharp-format
 msgid "Connected to {0}"
 msgstr "Verbunden zu {0}"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:207
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:203
 #, csharp-format
 msgid "Disconnected from {0}"
 msgstr "Getrennt von {0}"
 
-#: ../src/Engine/Session.cs:218
+#: ../src/Engine/Session.cs:217
 #, 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:416
+#: ../src/Engine/Session.cs:415
 msgid "Engine Commands"
 msgstr "Engine Befehle"
 
-#: ../src/Engine/Session.cs:527
+#: ../src/Engine/Session.cs:540
 msgid "Connect failed!"
 msgstr "Verbindung ist fehlgeschlagen!"
 
-#: ../src/Engine/Session.cs:550
+#: ../src/Engine/Session.cs:563
 #, 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:589
+#: ../src/Engine/Session.cs:603
 msgid "Reconnect failed!"
 msgstr "Wiederverbinden ist fehlgeschlagen!"
 
-#: ../src/Engine/Session.cs:608
+#: ../src/Engine/Session.cs:625
 msgid "Configuration reloaded"
 msgstr "Konfiguration wurde erneuert"
 
-#: ../src/Engine/Session.cs:613
+#: ../src/Engine/Session.cs:629
 msgid "Configuration saved"
 msgstr "Konfiguration wurde gespeichert"
 
-#: ../src/Engine/Session.cs:617
+#: ../src/Engine/Session.cs:633
 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:676
+#: ../src/Engine/Session.cs:702
 msgid "Invalid parameter for network; use list, switch, or close"
-msgstr ""
-"Ungültiger Parameter für \"network\", verwenden Sie \"list\", \"switch\" "
-"oder \"close\""
-
-#: ../src/Engine/Session.cs:687
-msgid "Networks"
-msgstr "Netzwerke"
+msgstr "Ungültiger Parameter für \"network\", verwenden Sie \"list\", \"switch\" oder \"close\""
 
-#: ../src/Engine/Session.cs:691
-msgid "Protocol"
-msgstr "Protokoll"
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of networks below
+#: ../src/Engine/Session.cs:733
+msgid "Connected Networks"
+msgstr "Verbundene Netzwerke"
 
-#: ../src/Engine/Session.cs:692
+#: ../src/Engine/Session.cs:738 ../src/Engine/Session.cs:762
 msgid "Network"
 msgstr "Netzwerk"
 
-#: ../src/Engine/Session.cs:693
+#: ../src/Engine/Session.cs:739
+msgid "Protocol"
+msgstr "Protokoll"
+
+#: ../src/Engine/Session.cs:740
 msgid "Host"
 msgstr "Host"
 
-#: ../src/Engine/Session.cs:694
+#: ../src/Engine/Session.cs:741
 msgid "Port"
 msgstr "Port"
 
-#: ../src/Engine/Session.cs:709
+#. TRANSLATOR: no connected networks
+#. TRANSLATOR: no available networks
+#: ../src/Engine/Session.cs:747 ../src/Engine/Session.cs:768
+msgid "None"
+msgstr "Keines"
+
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of networks below
+#: ../src/Engine/Session.cs:754
+msgid "Available Networks"
+msgstr "Verfügbare Netzwerke"
+
+#: ../src/Engine/Session.cs:783
 #, csharp-format
 msgid "Network close failed - could not find network: {0}"
-msgstr ""
-"Schließen des Netzwerks fehlgeschlagen - Netzwerk konnte nicht gefunden "
-"werden: {0}"
+msgstr "Schließen des Netzwerks fehlgeschlagen - Netzwerk konnte nicht gefunden werden: {0}"
 
-#: ../src/Engine/Session.cs:748
+#: ../src/Engine/Session.cs:821
 #, csharp-format
 msgid "Network switch failed - could not find network: {0}"
-msgstr ""
-"Wechseln des Netzwerks fehlgeschlagen - Netzwerk konnte nicht gefunden "
-"werden: {0}"
+msgstr "Wechseln des Netzwerks fehlgeschlagen - Netzwerk konnte nicht gefunden werden: {0}"
 
-#: ../src/Engine/Session.cs:767
+#: ../src/Engine/Session.cs:839
 msgid "Not connected to any network"
 msgstr "Zu keinem Netzwerk verbunden"
 
-#: ../src/Engine/Session.cs:1013
+#: ../src/Engine/Session.cs:1093
 #, 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}"
+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:1185
+#: ../src/Engine/Session.cs:1266
 msgid "Connect failed."
 msgstr "Verbindung ist fehlgeschlagen."
 
-#: ../src/Engine/Session.cs:1216
+#: ../src/Engine/Session.cs:1297
 #, 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
+#: ../src/Engine/Session.cs:1529
 msgid "Welcome to Smuxi"
 msgstr "Willkommen bei Smuxi"
 
-#: ../src/Engine/Session.cs:1455
+#: ../src/Engine/Session.cs:1536
 msgid "Type /help to get a list of available commands."
-msgstr ""
-"Geben Sie /help ein, um eine Liste der verfügbaren Befehle zu erhalten."
+msgstr "Geben Sie /help ein, um eine Liste der verfügbaren Befehle zu erhalten."
 
-#: ../src/Engine/Session.cs:1461
+#: ../src/Engine/Session.cs:1542
 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"
+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."
@@ -198,17 +197,33 @@ msgstr "Benutzer \"{0}\" ist nicht vorhanden."
 msgid "User \"{0}\" already exists."
 msgstr "Benutzer \"{0}\" ist bereits vorhanden."
 
-#: ../src/Engine/Config/ServerListController.cs:131
+#: ../src/Engine/Config/ServerListController.cs:118
+msgid "Network must not be empty."
+msgstr "Netzwerk darf nicht leer sein."
+
+#: ../src/Engine/Config/ServerListController.cs:138
 msgid "Server hostname must not be empty."
 msgstr "Hostname des Servers darf nicht leer sein."
 
-#: ../src/Engine/Config/ServerListController.cs:134
+#: ../src/Engine/Config/ServerListController.cs:141
 msgid "Server hostname contains invalid characters (newline)."
 msgstr "Hostname des Servers enthält unzuläissige Zeichen (neue Zeile)."
 
-#: ../src/Engine/Config/ServerListController.cs:140
+#: ../src/Engine/Config/ServerListController.cs:148
 #, csharp-format
-msgid "Server '{0}' already exists."
-msgstr "Server \"{0}\" ist bereits vorhanden."
+msgid "Server ID '{0}' already exists."
+msgstr "Die Server ID {0} ist bereits vorhanden."
 
+#: ../src/Engine/Chats/ChatModel.cs:105
+#, csharp-format
+msgid ""
+"Failed to load chat history. Your chat history will not be preserved. "
+"Reason: {0}"
+msgstr "Laden des Gesprächverlaufs fehlgeschlagen. Ihr Gesprächsverlauf wird nicht vorgehalten. Grund: {0}"
 
+#: ../src/Engine/Chats/ChatModel.cs:298
+#, csharp-format
+msgid ""
+"Failed to open chat history for writing. Your chat history will not be "
+"preserved. Reason: {0}"
+msgstr "Öffnen des Gesprächverlaufs zum Schreiben fehlgeschlagen. Ihr Gesprächsverlauf wird nicht vorgehalten. Grund: {0}"
diff --git a/po-Engine/fi.po b/po-Engine/fi.po
new file mode 100644
index 0000000..f300434
--- /dev/null
+++ b/po-Engine/fi.po
@@ -0,0 +1,229 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+# Kalle Kaitala <cobrian at cobrian.net>, 2013
+msgid ""
+msgstr ""
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2013-04-14 10:13+0200\n"
+"PO-Revision-Date: 2013-05-01 13:33+0000\n"
+"Last-Translator: Kalle Kaitala <cobrian at cobrian.net>\n"
+"Language-Team: Finnish (http://www.transifex.com/projects/p/smuxi/language/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/FrontendManager.cs:233
+msgid "No network connections"
+msgstr "Ei verkkoyhteyttä"
+
+#: ../src/Engine/MessageBuffers/Db4oMessageBuffer.cs:295
+#, csharp-format
+msgid "Optimizing: {0}..."
+msgstr "Optimoidaan: {0}..."
+
+#: ../src/Engine/MessageBuffers/Db4oMessageBuffer.cs:313
+#, csharp-format
+msgid "Failed to optimize: {0}. Reason: {1}"
+msgstr "Optimointi epäonnistui: {0}. Syy: {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 "Viestihistoriasi ei ole saatavilla virheen vuoksi mutta se tallennetaan tästä eteenpäin."
+
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:166
+msgid "Not connected to server"
+msgstr "Yhteys palvelimeen katkaistu"
+
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:174
+#: ../src/Engine/Session.cs:846
+#, csharp-format
+msgid "Not enough parameters for {0} command"
+msgstr "Ei tarpeeksi parametrejä komennolle {0}"
+
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:185
+#, csharp-format
+msgid "Connected to {0}"
+msgstr "Yhdistetty kohteeseen {0}"
+
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:203
+#, csharp-format
+msgid "Disconnected from {0}"
+msgstr "Yhteys katkaistu kohteesta {0}"
+
+#: ../src/Engine/Session.cs:217
+#, csharp-format
+msgid "Automatic connect to {0} failed!"
+msgstr "Automaattinen yhdistys palvelimeen {0} epäonnistui!"
+
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of commands below
+#: ../src/Engine/Session.cs:415
+msgid "Engine Commands"
+msgstr "Moottorin komennot"
+
+#: ../src/Engine/Session.cs:540
+msgid "Connect failed!"
+msgstr "Yhdistäminen epäonnistui!"
+
+#: ../src/Engine/Session.cs:563
+#, csharp-format
+msgid "Disconnect failed - could not find server: {0}"
+msgstr "Yhteyden katkaisu epäonnistui - palvelinta {0} ei löydetty"
+
+#: ../src/Engine/Session.cs:603
+msgid "Reconnect failed!"
+msgstr "Uudelleenyhdistäminen epäonnistui!"
+
+#: ../src/Engine/Session.cs:625
+msgid "Configuration reloaded"
+msgstr "Asetukset ladattu uudelleen"
+
+#: ../src/Engine/Session.cs:629
+msgid "Configuration saved"
+msgstr "Asetukset tallennettu"
+
+#: ../src/Engine/Session.cs:633
+msgid "Invalid parameter for config; use load or save"
+msgstr "Epäkelpo parametri config:lle; käytä komentoja load tai save"
+
+#: ../src/Engine/Session.cs:702
+msgid "Invalid parameter for network; use list, switch, or close"
+msgstr "Epäkelpo parametri network:lle, käytä komentoja list, switch tai close"
+
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of networks below
+#: ../src/Engine/Session.cs:733
+msgid "Connected Networks"
+msgstr "Yhdistetyt Verkot"
+
+#: ../src/Engine/Session.cs:738 ../src/Engine/Session.cs:762
+msgid "Network"
+msgstr "Verkko"
+
+#: ../src/Engine/Session.cs:739
+msgid "Protocol"
+msgstr "Protokolla"
+
+#: ../src/Engine/Session.cs:740
+msgid "Host"
+msgstr "Isäntä"
+
+#: ../src/Engine/Session.cs:741
+msgid "Port"
+msgstr "Portti"
+
+#. TRANSLATOR: no connected networks
+#. TRANSLATOR: no available networks
+#: ../src/Engine/Session.cs:747 ../src/Engine/Session.cs:768
+msgid "None"
+msgstr "Ei mitään"
+
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of networks below
+#: ../src/Engine/Session.cs:754
+msgid "Available Networks"
+msgstr "Saatavilla olevat verkot"
+
+#: ../src/Engine/Session.cs:783
+#, csharp-format
+msgid "Network close failed - could not find network: {0}"
+msgstr "Verkon sulkeminen epäonnistui - verkkoa ei löytynyt: {0}"
+
+#: ../src/Engine/Session.cs:821
+#, csharp-format
+msgid "Network switch failed - could not find network: {0}"
+msgstr "Verkon vaihtaminen epäonnistui - verkkoa ei löytynyt: {0}"
+
+#: ../src/Engine/Session.cs:839
+msgid "Not connected to any network"
+msgstr "Ei yhdistettynä yhteenkään verkkoon"
+
+#: ../src/Engine/Session.cs:1093
+#, csharp-format
+msgid ""
+"Failed to write to chat history. Your chat history will not be preserved. "
+"Reason: {0}"
+msgstr "Chat-historian tallennus epäonnistui. Chat-historiaasi ei säilötä. Syy: {0}"
+
+#. just in case the ProtocolManager is not setting the
+#. protocol chat
+#: ../src/Engine/Session.cs:1266
+msgid "Connect failed."
+msgstr "Yhdistäminen epäonnistui."
+
+#: ../src/Engine/Session.cs:1297
+#, csharp-format
+msgid "No protocol manager found for the protocol: {0}"
+msgstr "Protokollan hallintaa ei löydetty protokollalle {0}"
+
+#: ../src/Engine/Session.cs:1529
+msgid "Welcome to Smuxi"
+msgstr "Tervetuloa Smuxiin"
+
+#: ../src/Engine/Session.cs:1536
+msgid "Type /help to get a list of available commands."
+msgstr "Kirjoita /help saadaksesi listan käytössäolevista komennoista."
+
+#: ../src/Engine/Session.cs:1542
+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 "Yhteydenmuodostuksen jälkeen lista käytettävistä komennoista muuttuu. Mene uuteen avautuneeseen yhteysvälilehteen ja käytä /help -komentoa nähdäksesi laajennetun komentolistauksen."
+
+#: ../src/Engine/Config/UserListController.cs:117
+msgid "Username must not be empty."
+msgstr "Käyttäjänimi ei saa olla tyhjä."
+
+#: ../src/Engine/Config/UserListController.cs:127
+msgid "Password must not be empty."
+msgstr "Salasana ei saa olla tyhjä."
+
+#: ../src/Engine/Config/UserListController.cs:136
+#, csharp-format
+msgid "User \"{0}\" doesn't exist."
+msgstr "Käyttäjää \"{0}\" ei ole olemassa."
+
+#: ../src/Engine/Config/UserListController.cs:145
+#, csharp-format
+msgid "User \"{0}\" already exists."
+msgstr "Käyttäjä \"{0}\" on jo olemassa."
+
+#: ../src/Engine/Config/ServerListController.cs:118
+msgid "Network must not be empty."
+msgstr "Verkko ei saa olla tyhjä."
+
+#: ../src/Engine/Config/ServerListController.cs:138
+msgid "Server hostname must not be empty."
+msgstr "Palvelimen isäntänimi ei saa olla tyhjä."
+
+#: ../src/Engine/Config/ServerListController.cs:141
+msgid "Server hostname contains invalid characters (newline)."
+msgstr "Palvelimen isäntänimi sisältää epäkelpoja merkkejä (rivinvaihto)."
+
+#: ../src/Engine/Config/ServerListController.cs:148
+#, csharp-format
+msgid "Server ID '{0}' already exists."
+msgstr "Palvelin ID:llä '{0}' on jo olemassa."
+
+#: ../src/Engine/Chats/ChatModel.cs:105
+#, csharp-format
+msgid ""
+"Failed to load chat history. Your chat history will not be preserved. "
+"Reason: {0}"
+msgstr "Chat-historian lataaminen epäonnistui. Chat-historiaasi ei tallenneta. Syy: {0}"
+
+#: ../src/Engine/Chats/ChatModel.cs:298
+#, csharp-format
+msgid ""
+"Failed to open chat history for writing. Your chat history will not be "
+"preserved. Reason: {0}"
+msgstr "Chat-historian avaaminen tallentamista varten epäonnistui. Chat-historiaasi ei tallenneta. Syy: {0}"
diff --git a/po-Engine/fr.po b/po-Engine/fr.po
index 8d1a3de..a2781b0 100644
--- a/po-Engine/fr.po
+++ b/po-Engine/fr.po
@@ -1,21 +1,21 @@
 # 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 - 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"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-04-10 21:36+0200\n"
+"PO-Revision-Date: 2013-04-10 22:40+0100\n"
 "Last-Translator: Clément Bourgeois <moonpyk at gmail.com>\n"
 "Language-Team: French (http://www.transifex.net/projects/p/smuxi/team/fr/)\n"
+"Language: 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/Engine/FrontendManager.cs:233
@@ -40,103 +40,116 @@ 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
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:166
 msgid "Not connected to server"
 msgstr "Pas de connexion au serveur"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:178
-#: ../src/Engine/Session.cs:778
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:174
+#: ../src/Engine/Session.cs:846
 #, csharp-format
 msgid "Not enough parameters for {0} command"
 msgstr "Pas assez d'arguments pour la commande {0}"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:189
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:185
 #, csharp-format
 msgid "Connected to {0}"
 msgstr "Connecté à {0}"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:207
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:203
 #, csharp-format
 msgid "Disconnected from {0}"
 msgstr "Deconnecté de {0}"
 
-#: ../src/Engine/Session.cs:218
+#: ../src/Engine/Session.cs:217
 #, 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:416
+#: ../src/Engine/Session.cs:415
 msgid "Engine Commands"
 msgstr "Commandes du moteur"
 
-#: ../src/Engine/Session.cs:527
+#: ../src/Engine/Session.cs:540
 msgid "Connect failed!"
 msgstr "Connexion impossible !"
 
-#: ../src/Engine/Session.cs:550
+#: ../src/Engine/Session.cs:563
 #, csharp-format
 msgid "Disconnect failed - could not find server: {0}"
 msgstr "Déconnexion impossible : serveur \"{0}\" introuvable"
 
-#: ../src/Engine/Session.cs:589
+#: ../src/Engine/Session.cs:603
 msgid "Reconnect failed!"
 msgstr "Reconnexion impossible !"
 
-#: ../src/Engine/Session.cs:608
+#: ../src/Engine/Session.cs:625
 msgid "Configuration reloaded"
 msgstr "Configuration rechargée"
 
-#: ../src/Engine/Session.cs:613
+#: ../src/Engine/Session.cs:629
 msgid "Configuration saved"
 msgstr "Configuration sauvegardée"
 
-#: ../src/Engine/Session.cs:617
+#: ../src/Engine/Session.cs:633
 msgid "Invalid parameter for config; use load or save"
 msgstr "Paramètre invalide pour la configuration ; utilisez load ou save"
 
-#: ../src/Engine/Session.cs:676
+#: ../src/Engine/Session.cs:702
 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:687
-msgid "Networks"
-msgstr "Réseaux"
-
-#: ../src/Engine/Session.cs:691
-msgid "Protocol"
-msgstr "Protocole"
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of networks below
+#: ../src/Engine/Session.cs:733
+msgid "Connected Networks"
+msgstr "Réseaux connectés"
 
-#: ../src/Engine/Session.cs:692
+#: ../src/Engine/Session.cs:738 ../src/Engine/Session.cs:762
 msgid "Network"
 msgstr "Réseau"
 
-#: ../src/Engine/Session.cs:693
+#: ../src/Engine/Session.cs:739
+msgid "Protocol"
+msgstr "Protocole"
+
+#: ../src/Engine/Session.cs:740
 msgid "Host"
 msgstr "Hôte"
 
-#: ../src/Engine/Session.cs:694
+#: ../src/Engine/Session.cs:741
 msgid "Port"
 msgstr "Port"
 
-#: ../src/Engine/Session.cs:709
+#. TRANSLATOR: no connected networks
+#. TRANSLATOR: no available networks
+#: ../src/Engine/Session.cs:747 ../src/Engine/Session.cs:768
+msgid "None"
+msgstr "Aucun"
+
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of networks below
+#: ../src/Engine/Session.cs:754
+msgid "Available Networks"
+msgstr "Réseaux disponibles"
+
+#: ../src/Engine/Session.cs:783
 #, csharp-format
 msgid "Network close failed - could not find network: {0}"
-msgstr ""
-"Impossible de fermer le réseau - impossible de trouver le réseau : {0}"
+msgstr "Impossible de fermer le réseau - impossible de trouver le réseau : {0}"
 
-#: ../src/Engine/Session.cs:748
+#: ../src/Engine/Session.cs:821
 #, csharp-format
 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:767
+#: ../src/Engine/Session.cs:839
 msgid "Not connected to any network"
 msgstr "Aucun réseau connecté"
 
-#: ../src/Engine/Session.cs:1013
+#: ../src/Engine/Session.cs:1093
 #, csharp-format
 msgid ""
 "Failed to write to chat history. Your chat history will not be preserved. "
@@ -147,32 +160,32 @@ msgstr ""
 
 #. just in case the ProtocolManager is not setting the
 #. protocol chat
-#: ../src/Engine/Session.cs:1185
+#: ../src/Engine/Session.cs:1266
 msgid "Connect failed."
 msgstr "Connexion impossible."
 
-#: ../src/Engine/Session.cs:1216
+#: ../src/Engine/Session.cs:1297
 #, 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
+#: ../src/Engine/Session.cs:1529
 msgid "Welcome to Smuxi"
 msgstr "Bienvenue dans Smuxi"
 
-#: ../src/Engine/Session.cs:1455
+#: ../src/Engine/Session.cs:1536
 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
+#: ../src/Engine/Session.cs:1542
 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."
+"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."
@@ -192,17 +205,37 @@ msgstr "L'utilisateur \"{0}\"  n'existe pas."
 msgid "User \"{0}\" already exists."
 msgstr "L'utilisateur \"{0}\" existe déjà."
 
-#: ../src/Engine/Config/ServerListController.cs:131
+#: ../src/Engine/Config/ServerListController.cs:118
+msgid "Network must not be empty."
+msgstr "Le réseau ne peut pas être vide."
+
+#: ../src/Engine/Config/ServerListController.cs:138
 msgid "Server hostname must not be empty."
 msgstr "Le nom d'hôte ne peut pas être vide."
 
-#: ../src/Engine/Config/ServerListController.cs:134
+#: ../src/Engine/Config/ServerListController.cs:141
 msgid "Server hostname contains invalid characters (newline)."
 msgstr "Le nom d'hôte contient des caractères invalides."
 
-#: ../src/Engine/Config/ServerListController.cs:140
+#: ../src/Engine/Config/ServerListController.cs:148
 #, csharp-format
-msgid "Server '{0}' already exists."
-msgstr "Le serveur \"{0}\" existe déjà."
+msgid "Server ID '{0}' already exists."
+msgstr "L'identifiant de serveur \"{0}\" existe déjà."
 
+#: ../src/Engine/Chats/ChatModel.cs:105
+#, csharp-format
+msgid ""
+"Failed to load chat history. Your chat history will not be preserved. "
+"Reason: {0}"
+msgstr ""
+"Impossible de charger votre historique de discussion, celui-ci ne sera pas "
+"préservé. Raison : {0}"
 
+#: ../src/Engine/Chats/ChatModel.cs:298
+#, csharp-format
+msgid ""
+"Failed to open chat history for writing. Your chat history will not be "
+"preserved. Reason: {0}"
+msgstr ""
+"Impossible d'ouvrir en écriture votre historique de discussion, celui-ci ne "
+"sera pas préservé. Raison : {0}"
diff --git a/po-Engine/sv.po b/po-Engine/sv.po
index 0630d15..a30bbef 100644
--- a/po-Engine/sv.po
+++ b/po-Engine/sv.po
@@ -3,21 +3,22 @@
 # This file is distributed under the same license as the PACKAGE package.
 # 
 # Translators:
-#   <flugsio at gmail.com>, 2011.
-# Martin Bagge <brother at bsnet.se>, 2012.
+# flugsio <flugsio at gmail.com>, 2013
+# flugsio <flugsio at gmail.com>, 2011, 2012
+# Martin Bagge <brother at bsnet.se>, 2012
 msgid ""
 msgstr ""
 "Project-Id-Version: Smuxi - IRC client\n"
 "Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
-"POT-Creation-Date: 2012-01-01 18:47+0100\n"
-"PO-Revision-Date: 2012-01-07 12:07+0000\n"
-"Last-Translator: Martin Bagge <brother at bsnet.se>\n"
-"Language-Team: Swedish (http://www.transifex.net/projects/p/smuxi/team/sv/)\n"
+"POT-Creation-Date: 2013-04-14 10:13+0200\n"
+"PO-Revision-Date: 2013-04-17 04:01+0000\n"
+"Last-Translator: flugsio <flugsio at gmail.com>\n"
+"Language-Team: Swedish (http://www.transifex.com/projects/p/smuxi/language/sv/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Language: sv\n"
-"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
 #: ../src/Engine/FrontendManager.cs:233
 msgid "No network connections"
@@ -37,151 +38,156 @@ msgstr "Misslyckades att optimera: {0}. Anledning: {1}"
 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."
+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
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:166
 msgid "Not connected to server"
 msgstr "Inte ansluten till server"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:178
-#: ../src/Engine/Session.cs:778
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:174
+#: ../src/Engine/Session.cs:846
 #, csharp-format
 msgid "Not enough parameters for {0} command"
 msgstr "Inte tillräckligt med parametrar för kommandot {0}"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:189
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:185
 #, csharp-format
 msgid "Connected to {0}"
 msgstr "Ansluten till {0}"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:207
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:203
 #, csharp-format
 msgid "Disconnected from {0}"
 msgstr "Frånkopplad från {0}"
 
-#: ../src/Engine/Session.cs:218
+#: ../src/Engine/Session.cs:217
 #, 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:416
+#: ../src/Engine/Session.cs:415
 msgid "Engine Commands"
 msgstr "Kommandon för motorn"
 
-#: ../src/Engine/Session.cs:527
+#: ../src/Engine/Session.cs:540
 msgid "Connect failed!"
 msgstr "Anslutning misslyckades!"
 
-#: ../src/Engine/Session.cs:550
+#: ../src/Engine/Session.cs:563
 #, csharp-format
 msgid "Disconnect failed - could not find server: {0}"
 msgstr "Nedkoppling misslyckades - kunde inte hitta servern: {0}"
 
-#: ../src/Engine/Session.cs:589
+#: ../src/Engine/Session.cs:603
 msgid "Reconnect failed!"
 msgstr "Ã…teranslutning misslyckades!"
 
-#: ../src/Engine/Session.cs:608
+#: ../src/Engine/Session.cs:625
 msgid "Configuration reloaded"
-msgstr "Laddade om inställningar"
+msgstr "Inställningarna laddades"
 
-#: ../src/Engine/Session.cs:613
+#: ../src/Engine/Session.cs:629
 msgid "Configuration saved"
-msgstr "Sparade inställningar"
+msgstr "Inställningarna sparades"
 
-#: ../src/Engine/Session.cs:617
+#: ../src/Engine/Session.cs:633
 msgid "Invalid parameter for config; use load or save"
-msgstr "Ogiltig parameter för inställningar; använd load eller save"
+msgstr "Ogiltig parameter för inställning; använd load eller save"
 
-#: ../src/Engine/Session.cs:676
+#: ../src/Engine/Session.cs:702
 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:687
-msgid "Networks"
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of networks below
+#: ../src/Engine/Session.cs:733
+msgid "Connected Networks"
+msgstr "Anslutna nätverk"
+
+#: ../src/Engine/Session.cs:738 ../src/Engine/Session.cs:762
+msgid "Network"
 msgstr "Nätverk"
 
-#: ../src/Engine/Session.cs:691
+#: ../src/Engine/Session.cs:739
 msgid "Protocol"
 msgstr "Protokoll"
 
-#: ../src/Engine/Session.cs:692
-msgid "Network"
-msgstr "Nätverk"
-
-#: ../src/Engine/Session.cs:693
+#: ../src/Engine/Session.cs:740
 msgid "Host"
 msgstr "Värd"
 
-#: ../src/Engine/Session.cs:694
+#: ../src/Engine/Session.cs:741
 msgid "Port"
 msgstr "Port"
 
-#: ../src/Engine/Session.cs:709
+#. TRANSLATOR: no connected networks
+#. TRANSLATOR: no available networks
+#: ../src/Engine/Session.cs:747 ../src/Engine/Session.cs:768
+msgid "None"
+msgstr "Ingen"
+
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of networks below
+#: ../src/Engine/Session.cs:754
+msgid "Available Networks"
+msgstr "Tillgängliga nätverk"
+
+#: ../src/Engine/Session.cs:783
 #, csharp-format
 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}"
+msgstr "Stängning av nätverk misslyckades - kunde inte hitta nätverket med värdnamn: {0}"
 
-#: ../src/Engine/Session.cs:748
+#: ../src/Engine/Session.cs:821
 #, csharp-format
 msgid "Network switch failed - could not find network: {0}"
-msgstr ""
-"Byte av nätverk misslyckades - kunde inte hitta nätverk med värden: {0}"
+msgstr "Byte av nätverk misslyckades - kunde inte hitta nätverket med värdnamn: {0}"
 
-#: ../src/Engine/Session.cs:767
+#: ../src/Engine/Session.cs:839
 msgid "Not connected to any network"
 msgstr "Inte ansluten till något nätverk"
 
-#: ../src/Engine/Session.cs:1013
+#: ../src/Engine/Session.cs:1093
 #, 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}"
+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:1185
+#: ../src/Engine/Session.cs:1266
 msgid "Connect failed."
 msgstr "Anslutning misslyckades."
 
-#: ../src/Engine/Session.cs:1216
+#: ../src/Engine/Session.cs:1297
 #, csharp-format
 msgid "No protocol manager found for the protocol: {0}"
 msgstr "Ingen protokollshanterare funnen för protokollet: {0}"
 
-#: ../src/Engine/Session.cs:1448
+#: ../src/Engine/Session.cs:1529
 msgid "Welcome to Smuxi"
 msgstr "Välkommen till Smuxi"
 
-#: ../src/Engine/Session.cs:1455
+#: ../src/Engine/Session.cs:1536
 msgid "Type /help to get a list of available commands."
-msgstr "Skriv /help för en lista med tillgängliga kommandon."
+msgstr "Skriv /help för att få en lista med tillgängliga kommandon."
 
-#: ../src/Engine/Session.cs:1461
+#: ../src/Engine/Session.cs:1542
 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."
+msgstr "Efter att du har kopplat upp dig så uppdateras listan med tillgängliga kommandon. Gå till den nyligen öppnade anslutningsfliken och använd kommandot /help 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."
+msgstr "Användarnamnet får inte lämnas tomt."
 
 #: ../src/Engine/Config/UserListController.cs:127
 msgid "Password must not be empty."
-msgstr "Lösenordet får inte vara tomt."
+msgstr "Lösenordet får inte lämnas tomt."
 
 #: ../src/Engine/Config/UserListController.cs:136
 #, csharp-format
@@ -193,35 +199,33 @@ msgstr "Användaren \"{0}\" finns inte."
 msgid "User \"{0}\" already exists."
 msgstr "Användaren \"{0}\" finns redan."
 
-#: ../src/Engine/Config/ServerListController.cs:131
+#: ../src/Engine/Config/ServerListController.cs:118
+msgid "Network must not be empty."
+msgstr "Nätverk får inte lämnas tomt."
+
+#: ../src/Engine/Config/ServerListController.cs:138
 msgid "Server hostname must not be empty."
 msgstr "Servers värdnamn får inte lämnas tomt."
 
-#: ../src/Engine/Config/ServerListController.cs:134
+#: ../src/Engine/Config/ServerListController.cs:141
 msgid "Server hostname contains invalid characters (newline)."
 msgstr "Serverns värdnamn innehåller ogiltiga tecken (ny rad)."
 
-#: ../src/Engine/Config/ServerListController.cs:140
+#: ../src/Engine/Config/ServerListController.cs:148
 #, csharp-format
-msgid "Server '{0}' already exists."
-msgstr "Servern '{0}' finns redan."
+msgid "Server ID '{0}' already exists."
+msgstr "Server ID '{0}' finns redan."
 
 #: ../src/Engine/Chats/ChatModel.cs:105
 #, csharp-format
 msgid ""
 "Failed to load chat history. Your chat history will not be preserved. "
 "Reason: {0}"
-msgstr ""
-"Kunde inte läsa in chatthistoriken. Din chatthistorik kommer inte att "
-"sparas. Anledning: {0}"
+msgstr "Kunde inte läsa in chatthistoriken. Din chatthistorik kommer inte att sparas. Anledning: {0}"
 
-#: ../src/Engine/Chats/ChatModel.cs:290
+#: ../src/Engine/Chats/ChatModel.cs:298
 #, csharp-format
 msgid ""
 "Failed to open chat history for writing. Your chat history will not be "
 "preserved. Reason: {0}"
-msgstr ""
-"Kunde inte öppna chatthistoriken för skrivning. Din chatthistorik kommer "
-"inte att sparas. Anledning: {0}"
-
-
+msgstr "Kunde inte öppna chatthistoriken med skrivrättighet. Din chatthistorik kommer inte att sparas. Anledning: {0}"
diff --git a/po-Engine/zh_CN.po b/po-Engine/zh_CN.po
index 0147eb6..cda2eb6 100644
--- a/po-Engine/zh_CN.po
+++ b/po-Engine/zh_CN.po
@@ -3,20 +3,20 @@
 # This file is distributed under the same license as the PACKAGE package.
 # 
 # Translators:
-# Dean Lee <xslidian at gmail.com>, 2011, 2012.
+# Dean Lee <xslidian at gmail.com>, 2011-2013.
 msgid ""
 msgstr ""
 "Project-Id-Version: Smuxi - IRC client\n"
 "Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
-"POT-Creation-Date: 2012-01-01 18:47+0100\n"
-"PO-Revision-Date: 2012-01-07 09:53+0000\n"
+"POT-Creation-Date: 2013-04-14 10:13+0200\n"
+"PO-Revision-Date: 2013-04-14 14:06+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"
+"Language-Team: Chinese (China) (http://www.transifex.com/projects/p/smuxi/language/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"
+"Plural-Forms: nplurals=1; plural=0;\n"
 
 #: ../src/Engine/FrontendManager.cs:233
 msgid "No network connections"
@@ -38,101 +38,115 @@ msgid ""
 "preserved from now on."
 msgstr "由于发生错误,您的聊天历史不再可用;但今后的聊天历史将会保留。"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:170
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:166
 msgid "Not connected to server"
 msgstr "未连接到服务器"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:178
-#: ../src/Engine/Session.cs:778
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:174
+#: ../src/Engine/Session.cs:846
 #, csharp-format
 msgid "Not enough parameters for {0} command"
 msgstr "{0} 命令参数不足"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:189
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:185
 #, csharp-format
 msgid "Connected to {0}"
 msgstr "已连接到 {0}"
 
-#: ../src/Engine/Protocols/ProtocolManagerBase.cs:207
+#: ../src/Engine/Protocols/ProtocolManagerBase.cs:203
 #, csharp-format
 msgid "Disconnected from {0}"
 msgstr "已从 {0} 断开连接"
 
-#: ../src/Engine/Session.cs:218
+#: ../src/Engine/Session.cs:217
 #, 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
+#: ../src/Engine/Session.cs:415
 msgid "Engine Commands"
 msgstr "引擎命令"
 
-#: ../src/Engine/Session.cs:527
+#: ../src/Engine/Session.cs:540
 msgid "Connect failed!"
 msgstr "连接失败!"
 
-#: ../src/Engine/Session.cs:550
+#: ../src/Engine/Session.cs:563
 #, csharp-format
 msgid "Disconnect failed - could not find server: {0}"
 msgstr "连接断开失败 - 找不到服务器: {0}"
 
-#: ../src/Engine/Session.cs:589
+#: ../src/Engine/Session.cs:603
 msgid "Reconnect failed!"
 msgstr "重新连接失败!"
 
-#: ../src/Engine/Session.cs:608
+#: ../src/Engine/Session.cs:625
 msgid "Configuration reloaded"
 msgstr "配置已重新载入"
 
-#: ../src/Engine/Session.cs:613
+#: ../src/Engine/Session.cs:629
 msgid "Configuration saved"
 msgstr "配置已保存"
 
-#: ../src/Engine/Session.cs:617
+#: ../src/Engine/Session.cs:633
 msgid "Invalid parameter for config; use load or save"
 msgstr "config 的参数无效; 使用 load 或 save"
 
-#: ../src/Engine/Session.cs:676
+#: ../src/Engine/Session.cs:702
 msgid "Invalid parameter for network; use list, switch, or close"
 msgstr "network 的参数无效; 使用 list、switch 或 close"
 
-#: ../src/Engine/Session.cs:687
-msgid "Networks"
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of networks below
+#: ../src/Engine/Session.cs:733
+msgid "Connected Networks"
+msgstr "已连接网络"
+
+#: ../src/Engine/Session.cs:738 ../src/Engine/Session.cs:762
+msgid "Network"
 msgstr "网络"
 
-#: ../src/Engine/Session.cs:691
+#: ../src/Engine/Session.cs:739
 msgid "Protocol"
 msgstr "协议"
 
-#: ../src/Engine/Session.cs:692
-msgid "Network"
-msgstr "网络"
-
-#: ../src/Engine/Session.cs:693
+#: ../src/Engine/Session.cs:740
 msgid "Host"
 msgstr "主机"
 
-#: ../src/Engine/Session.cs:694
+#: ../src/Engine/Session.cs:741
 msgid "Port"
 msgstr "端口"
 
-#: ../src/Engine/Session.cs:709
+#. TRANSLATOR: no connected networks
+#. TRANSLATOR: no available networks
+#: ../src/Engine/Session.cs:747 ../src/Engine/Session.cs:768
+msgid "None"
+msgstr "æ— "
+
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of networks below
+#: ../src/Engine/Session.cs:754
+msgid "Available Networks"
+msgstr "可用网络"
+
+#: ../src/Engine/Session.cs:783
 #, csharp-format
 msgid "Network close failed - could not find network: {0}"
 msgstr "网络关闭失败——无法找到网络: {0}"
 
-#: ../src/Engine/Session.cs:748
+#: ../src/Engine/Session.cs:821
 #, csharp-format
 msgid "Network switch failed - could not find network: {0}"
 msgstr "网络切换失败——无法找到网络: {0}"
 
-#: ../src/Engine/Session.cs:767
+#: ../src/Engine/Session.cs:839
 msgid "Not connected to any network"
 msgstr "未连接到任何网络"
 
-#: ../src/Engine/Session.cs:1013
+#: ../src/Engine/Session.cs:1093
 #, csharp-format
 msgid ""
 "Failed to write to chat history. Your chat history will not be preserved. "
@@ -141,24 +155,24 @@ msgstr "无法写入聊天历史。您的聊天历史将不会保存。原因: {
 
 #. just in case the ProtocolManager is not setting the
 #. protocol chat
-#: ../src/Engine/Session.cs:1185
+#: ../src/Engine/Session.cs:1266
 msgid "Connect failed."
 msgstr "连接失败。"
 
-#: ../src/Engine/Session.cs:1216
+#: ../src/Engine/Session.cs:1297
 #, csharp-format
 msgid "No protocol manager found for the protocol: {0}"
 msgstr "未找到该协议的协议管理器: {0}"
 
-#: ../src/Engine/Session.cs:1448
+#: ../src/Engine/Session.cs:1529
 msgid "Welcome to Smuxi"
 msgstr "欢迎来到 Smuxi"
 
-#: ../src/Engine/Session.cs:1455
+#: ../src/Engine/Session.cs:1536
 msgid "Type /help to get a list of available commands."
 msgstr "输入 /help 获取可用命令列表。"
 
-#: ../src/Engine/Session.cs:1461
+#: ../src/Engine/Session.cs:1542
 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 "
@@ -183,18 +197,22 @@ msgstr "用户 \"{0}\" 不存在。"
 msgid "User \"{0}\" already exists."
 msgstr "用户名 \"{0}\" 已存在。"
 
-#: ../src/Engine/Config/ServerListController.cs:131
+#: ../src/Engine/Config/ServerListController.cs:118
+msgid "Network must not be empty."
+msgstr "网络不能为空。"
+
+#: ../src/Engine/Config/ServerListController.cs:138
 msgid "Server hostname must not be empty."
 msgstr "服务器主机名不能为空。"
 
-#: ../src/Engine/Config/ServerListController.cs:134
+#: ../src/Engine/Config/ServerListController.cs:141
 msgid "Server hostname contains invalid characters (newline)."
 msgstr "服务器主机名包含无效字符 (换行)。"
 
-#: ../src/Engine/Config/ServerListController.cs:140
+#: ../src/Engine/Config/ServerListController.cs:148
 #, csharp-format
-msgid "Server '{0}' already exists."
-msgstr "服务器 '{0}' 已存在。"
+msgid "Server ID '{0}' already exists."
+msgstr "服务器 ID '{0}' 已存在。"
 
 #: ../src/Engine/Chats/ChatModel.cs:105
 #, csharp-format
@@ -203,11 +221,9 @@ msgid ""
 "Reason: {0}"
 msgstr "无法加载聊天历史。您的聊天历史将不会保留。原因: {0}"
 
-#: ../src/Engine/Chats/ChatModel.cs:290
+#: ../src/Engine/Chats/ChatModel.cs:298
 #, csharp-format
 msgid ""
 "Failed to open chat history for writing. Your chat history will not be "
 "preserved. Reason: {0}"
 msgstr "聊天历史无法打开写入。您的聊天历史将不会保留。原因: {0}"
-
-
diff --git a/po-Frontend-GNOME-IRC/POTFILES.skip b/po-Frontend-GNOME-IRC/POTFILES.skip
index e193022..1f55a38 100644
--- a/po-Frontend-GNOME-IRC/POTFILES.skip
+++ b/po-Frontend-GNOME-IRC/POTFILES.skip
@@ -1,6 +1,7 @@
 glade/
 src/Common/
 src/Engine/
+src/Engine-Campfire/
 src/Engine-IRC/
 src/Engine-MSNP/
 src/Engine-OSCAR/
diff --git a/po-Frontend-GNOME-IRC/fr.po b/po-Frontend-GNOME-IRC/fr.po
index b5d6da2..0fe38b6 100644
--- a/po-Frontend-GNOME-IRC/fr.po
+++ b/po-Frontend-GNOME-IRC/fr.po
@@ -1,70 +1,70 @@
 # 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"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-04-10 21:43+0200\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"
+"Language: 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-GNOME-IRC/IrcGroupChatView.cs:381
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:384
 msgid "Op"
 msgstr "Opper"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:385
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:388
 msgid "Deop"
 msgstr "Enlever l'Op"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:389
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:392
 msgid "Voice"
 msgstr "Voicer"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:393
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:396
 msgid "Devoice"
 msgstr "Enlever le Voice"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:397
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:400
 msgid "Kick"
 msgstr "Kicker"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:401
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:404
 msgid "Kick + Ban"
 msgstr "Kicker + Bannir"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:405
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:408
 msgid "Ban"
 msgstr "Bannir"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:409
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:412
 msgid "Unban"
 msgstr "Enlever le ban"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:415
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:418
 msgid "Query"
 msgstr "Chat privé"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:419
-#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:64
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:422
+#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:63
 msgid "Whois"
 msgstr "Whois"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:423
-#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:68
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:426
+#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:67
 msgid "CTCP"
 msgstr "CTCP"
 
-#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:432
-#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:75
+#: ../src/Frontend-GNOME-IRC/IrcGroupChatView.cs:435
+#: ../src/Frontend-GNOME-IRC/IrcPersonChatView.cs:74
 msgid "Invite to"
 msgstr "Inviter à"
 
@@ -87,5 +87,3 @@ msgstr "Finger"
 #: ../src/Frontend-GNOME-IRC/CtcpMenu.cs:92
 msgid "Userinfo"
 msgstr "Userinfo"
-
-
diff --git a/po-Frontend-GNOME/LINGUAS b/po-Frontend-GNOME/LINGUAS
index 8459d25..9934fe9 100644
--- a/po-Frontend-GNOME/LINGUAS
+++ b/po-Frontend-GNOME/LINGUAS
@@ -5,6 +5,7 @@ de
 es
 es_AR
 en_GB
+fi
 fr
 hr
 it
diff --git a/po-Frontend-GNOME/POTFILES.in b/po-Frontend-GNOME/POTFILES.in
index 53827e1..ea6c50c 100644
--- a/po-Frontend-GNOME/POTFILES.in
+++ b/po-Frontend-GNOME/POTFILES.in
@@ -15,6 +15,8 @@ src/Frontend-GNOME/NotifyManager.cs
 src/Frontend-GNOME/QuickConnectDialog.cs
 src/Frontend-GNOME/ChatTypeWidget.cs
 src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs
+src/Frontend-GNOME/Views/JoinWidget.cs
+src/Frontend-GNOME/Views/MenuWidget.cs
 src/Frontend-GNOME/Views/MessageTextView.cs
 src/Frontend-GNOME/Views/FilterListWidget.cs
 src/Frontend-GNOME/Views/Chats/ChatView.cs
@@ -24,6 +26,7 @@ src/Frontend-GNOME/Preferences/ServerListView.cs
 src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs
 src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs
 src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.JoinWidget.cs
+src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs
 src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs
 src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs
 src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs
diff --git a/po-Frontend-GNOME/POTFILES.skip b/po-Frontend-GNOME/POTFILES.skip
index 4ec6ba2..8e6fdd8 100644
--- a/po-Frontend-GNOME/POTFILES.skip
+++ b/po-Frontend-GNOME/POTFILES.skip
@@ -7,6 +7,7 @@ src/Frontend-STFL/
 src/Frontend-SWF/
 src/Frontend-WPF/
 src/Engine/
+src/Engine-Campfire/
 src/Engine-IRC/
 src/Engine-MSNP/
 src/Engine-OSCAR/
diff --git a/po-Frontend-GNOME/da.po b/po-Frontend-GNOME/da.po
index a83ead8..6fe91fb 100644
--- a/po-Frontend-GNOME/da.po
+++ b/po-Frontend-GNOME/da.po
@@ -3,211 +3,194 @@
 # This file is distributed under the same license as the PACKAGE package.
 # 
 # Translators:
-# Joe Hansen <joedalton2 at yahoo.dk>, 2011.
+# Joe Hansen <joedalton2 at yahoo.dk>, 2011-2013.
 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: 2011-12-29 20:04+0000\n"
+"POT-Creation-Date: 2013-04-14 10:19+0200\n"
+"PO-Revision-Date: 2013-04-16 06:27+0000\n"
 "Last-Translator: Joe Hansen <joedalton2 at yahoo.dk>\n"
-"Language-Team: Danish (http://www.transifex.net/projects/p/smuxi/team/da/)\n"
+"Language-Team: Danish (http://www.transifex.com/projects/p/smuxi/language/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"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:1
-msgid "<b> Chat </b>"
-msgstr "<b> Snak </b>"
+msgid "Smuxi Preferences"
+msgstr "Præferencer for Smuxi"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:2
-msgid "<b> Color </b>"
-msgstr "<b> Farve </b>"
+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 "Brugernavnet. Du kan angive yderligere brugernavne (adskilt af mellemrum) 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:3
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1172
-msgid "<b> Entry Field </b>"
-msgstr "<b> Indtastningsfelt </b>"
+msgid "Nickname(s):"
+msgstr "Brugernavne:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:4
-msgid "<b> Font </b>"
-msgstr "<b> Skrifttype </b>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:315
+msgid "Username:"
+msgstr "Brugernavn:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:5
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1502
-msgid "<b> Highlighting </b>"
-msgstr "<b> Fremhævelse </b>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:338
+msgid "Realname:"
+msgstr "Navn:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:6
-msgid "<b> Notification Area Icon </b>"
-msgstr "<b> Ikon for statusfelt </b>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:359
+msgid "Encoding:"
+msgstr "Kodning:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:7
-msgid "<b> Person List Position </b>"
-msgstr "<b> Placering af personliste </b>"
+msgid "<b>General</b>"
+msgstr "<b>Generelt</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> Fanebladsfarver </b>"
+msgid "Type:"
+msgstr "Type:"
 
 #: ../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> Fanebladsplacering </b>"
+msgid "Host:"
+msgstr "Vært:"
 
 #: ../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> Emneplacering </b>"
+msgid "Password:"
+msgstr "Adgangskode:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:11
-msgid "<b>Advanced</b>"
-msgstr "<b>Avanceret</b>"
+msgid "Port:"
+msgstr "Port:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:12
-msgid "<b>General</b>"
-msgstr "<b>Generelt</b>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:170
+msgid "Show Password"
+msgstr "Vis adgangskode"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:13
-msgid "<b>Global Commands</b>"
-msgstr "<b>Globale kommandoer</b>"
+msgid "<b>Network Proxy</b>"
+msgstr "<b>Netværksproxy</b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:14
-msgid "<b>Message Buffer</b>"
-msgstr "<b>Beskedmellemlager</b>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:381
+msgid "On Connect Commands:"
+msgstr "Ingen tilslutningskommandoer:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:15
-msgid "<b>Messaging Menu</b>"
-msgstr "<b>Beskedmenu</b>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:427
+msgid "On Startup Commands:"
+msgstr "Ingen opstartskommandoer:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:16
-msgid "<b>Network Proxy</b>"
-msgstr "<b>Netværksproxy</b>"
+msgid "<b>Global Commands</b>"
+msgstr "<b>Globale kommandoer</b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:17
-msgid "<b>Notification Popups</b>"
-msgstr "<b>PÃ¥mindelses-pop op'er</b>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:471
+msgid "C_onnection"
+msgstr "_Tilslutning"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:18
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:961
-msgid "Activity"
-msgstr "Aktivitet"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:526
+msgid "Timestamp Format:"
+msgstr "Tidsstempelformat:"
 
 #: ../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:20
-msgid "Background"
-msgstr "Baggrund"
-
-#: ../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: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: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:24
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:546
 msgid "Buffer Lines:"
 msgstr "Mellemlagerlinjer:"
 
-#: ../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:26
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1112
-msgid "Command Character:"
-msgstr "Kommandotegn:"
-
-#: ../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:28
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1092
-msgid "Completion Character:"
-msgstr "Afslutningstegn:"
+#: ../glade/smuxi-frontend-gnome.glade.h:20
+#: ../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:29
-msgid "Enable"
-msgstr "Aktiver"
+#: ../glade/smuxi-frontend-gnome.glade.h:21
+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 = sekunder\nmm = minutter\nhh = timer (01 - 12)\nHH = timer (00 - 23)\ntt = AM/PM\n\ndd = dag\nMM = måned\nyy/yyyy = år"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:30
-msgid "Enabled"
-msgstr "Aktiveret"
+msgid "Persistency Type:"
+msgstr "Persistenstype:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:31
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:359
-msgid "Encoding:"
-msgstr "Kodning:"
+msgid "Volatile Buffer Lines:"
+msgstr "Ustabile mellemlagerlinjer:"
 
 #: ../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:"
+msgid "Persistent Buffer Lines:"
+msgstr "Mellemlagerlinjer for persistens:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:33
-msgid "Foreground"
-msgstr "Forgrund"
+msgid "<b>Message Buffer</b>"
+msgstr "<b>Beskedmellemlager</b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:34
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:725
-msgid "General"
-msgstr "Generelt"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:628
+msgid "Strip Colors"
+msgstr "Fjern farver"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:35
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:981
-msgid "Highlight"
-msgstr "Fremhæv"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:667
+msgid "Strip Formattings"
+msgstr "Fjern formater"
 
 #: ../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:"
+#: ../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:37
-msgid "Host:"
-msgstr "Vært:"
+msgid "Show Advanced Settings"
+msgstr "Vis avanceret opsætning"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:38
-msgid "Hostname:"
-msgstr "Værtsnavn:"
+msgid "<b>Advanced</b>"
+msgstr "<b>Avanceret</b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:39
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1181
-msgid "Input"
-msgstr "Inddata"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:725
+msgid "General"
+msgstr "Generelt"
 
+#. Container child vbox6.Gtk.Box+BoxChild
+#. Container child vbox11.Gtk.Box+BoxChild
 #: ../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"
+#: ../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"
 
 #. Container child vbox6.Gtk.Box+BoxChild
-#. Container child vbox12.Gtk.Box+BoxChild
+#. Container child vbox11.Gtk.Box+BoxChild
 #: ../glade/smuxi-frontend-gnome.glade.h:41
+#: ../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"
+
+#. Container child vbox6.Gtk.Box+BoxChild
+#. Container child vbox12.Gtk.Box+BoxChild
+#: ../glade/smuxi-frontend-gnome.glade.h:42
 #: ../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
@@ -215,260 +198,273 @@ msgstr "Deltag/del/tilstand"
 msgid "Left"
 msgstr "Venstre"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:42
-msgid "Log Filtered Messages"
-msgstr "Logfiltrerede beskeder"
-
+#. Container child vbox6.Gtk.Box+BoxChild
+#. Container child vbox12.Gtk.Box+BoxChild
 #: ../glade/smuxi-frontend-gnome.glade.h:43
-msgid "Network:"
-msgstr "Netværk:"
-
-#: ../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:45
-msgid "Nickname(s):"
-msgstr "Brugernavne:"
-
-#: ../glade/smuxi-frontend-gnome.glade.h:46
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:953
-msgid "No Activity"
-msgstr "Ingen aktivitet"
+#: ../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"
 
 #. 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
+#: ../glade/smuxi-frontend-gnome.glade.h:44
 #: ../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:45
+#: ../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:46
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:981
+msgid "Highlight"
+msgstr "Fremhæv"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:47
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:961
+msgid "Activity"
+msgstr "Aktivitet"
+
 #: ../glade/smuxi-frontend-gnome.glade.h:48
-msgid "Notification"
-msgstr "PÃ¥mindelse"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:953
+msgid "No Activity"
+msgstr "Ingen aktivitet"
 
 #: ../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:"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:971
+msgid "Join/Part/Mode"
+msgstr "Deltag/del/tilstand"
 
 #: ../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:"
+#: ../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:51
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1514
-msgid "Output"
-msgstr "Uddata"
+msgid "Automatically switch to newly opened person chats"
+msgstr "Skift automatisk til seneste åbnede personlige samtaler (chat)"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:52
-msgid "Override"
-msgstr "Overskriv"
+msgid "Automatically switch to newly opened group chats"
+msgstr "Skift automatisk til seneste åbnede gruppesamtaler (chat)"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:53
-msgid "Password:"
-msgstr "Adgangskode:"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1022
+msgid "Tabs"
+msgstr "Faneblade"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:54
-msgid "Persistency Type:"
-msgstr "Persistenstype:"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1092
+msgid "Completion Character:"
+msgstr "Afslutningstegn:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:55
-msgid "Persistent Buffer Lines:"
-msgstr "Mellemlagerlinjer for persistens:"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1112
+msgid "Command Character:"
+msgstr "Kommandotegn:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:56
-msgid "Port:"
-msgstr "Port:"
+#: ../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:57
-msgid "Protocol:"
-msgstr "Protokol:"
+#: ../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:58
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:338
-msgid "Realname:"
-msgstr "Navn:"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1172
+msgid "<b> Entry Field </b>"
+msgstr "<b> Indtastningsfelt </b>"
 
-#. 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 "Højre"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1181
+msgid "Input"
+msgstr "Inddata"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:60
-msgid "Show Advanced Settings"
-msgstr "Vis avanceret opsætning"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1202
+msgid "Nick Colors"
+msgstr "Farver for brugernavn"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:61
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:170
-msgid "Show Password"
-msgstr "Vis adgangskode"
+msgid "<b> Person List Position </b>"
+msgstr "<b> Placering af personliste </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:62
-msgid "Show Smuxi in the messaging menu"
-msgstr "Vis Smuxi i beskedmenuen"
+msgid "Override"
+msgstr "Overskriv"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:63
-msgid "Show always"
-msgstr "Vis altid"
+msgid "<b> Font </b>"
+msgstr "<b> Skrifttype </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:64
-msgid "Show notification popups"
-msgstr "Vis påmindelses-pop op'er"
+#: ../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:65
-msgid "Show when window is closed"
-msgstr "Vis når vinduet er lukket"
+msgid "Foreground"
+msgstr "Forgrund"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:66
-msgid "Show when window is minimized"
-msgstr "Vis når vinduet er minimeret"
+msgid "Background"
+msgstr "Baggrund"
 
 #: ../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:68
-msgid "Smuxi Preferences"
-msgstr "Præferencer for Smuxi"
+msgid "<b> Color </b>"
+msgstr "<b> Farve </b>"
 
+#. This is a setting for character based line wrapping vs word based when
+#. showing messages
 #: ../glade/smuxi-frontend-gnome.glade.h:69
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:628
-msgid "Strip Colors"
-msgstr "Fjern farver"
+msgid "_Wrap Mode:"
+msgstr "_Ombrydningstilstand:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:70
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:667
-msgid "Strip Formattings"
-msgstr "Fjern formater"
+msgid "<b> Chat </b>"
+msgstr "<b> Snak </b>"
 
 #: ../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"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1466
+msgid "Highlight words:"
+msgstr "Fremhæv ord:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:72
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1022
-msgid "Tabs"
-msgstr "Faneblade"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1490
+msgid "Beep on highlight"
+msgstr "Beep ved fremhævelse"
 
 #: ../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 ""
-"Brugernavnet. Du kan angive yderligere brugernavne (adskilt af mellemrum) "
-"som vil blive brugt hvis det første valg ikke er tilgængeligt. Som standard "
-"vil $nick_ og $nick__ blive anvendt."
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1502
+msgid "<b> Highlighting </b>"
+msgstr "<b> Fremhævelse </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:74
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:526
-msgid "Timestamp Format:"
-msgstr "Tidsstempelformat:"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1514
+msgid "Output"
+msgstr "Uddata"
 
-#. 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 "Øverst"
+msgid "Enable"
+msgstr "Aktiver"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:76
-msgid "Type:"
-msgstr "Type:"
+msgid "Show always"
+msgstr "Vis altid"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:77
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:315
-msgid "Username:"
-msgstr "Brugernavn:"
+msgid "Show when window is minimized"
+msgstr "Vis når vinduet er minimeret"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:78
-msgid "Volatile Buffer Lines:"
-msgstr "Ustabile mellemlagerlinjer:"
+msgid "Show when window is closed"
+msgstr "Vis når vinduet er lukket"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:79
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1681
-msgid "_Filters"
-msgstr "_Filtre"
+msgid "<b> Notification Area Icon </b>"
+msgstr "<b> Ikon for statusfelt </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:80
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1523
-msgid "_Interface"
-msgstr "_Grænseflade"
+msgid "Show Smuxi in the messaging menu"
+msgstr "Vis Smuxi i beskedmenuen"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:81
-msgid "_Logging"
-msgstr "_Logning"
+msgid "<b>Messaging Menu</b>"
+msgstr "<b>Beskedmenu</b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:82
+msgid "Show notification popups"
+msgstr "Vis påmindelses-pop op'er"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:83
+msgid "<b>Notification Popups</b>"
+msgstr "<b>PÃ¥mindelses-pop op'er</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:84
+msgid "Notification"
+msgstr "PÃ¥mindelse"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:85
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1523
+msgid "_Interface"
+msgstr "_Grænseflade"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:86
 #: ../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:84
-msgid "_Wrap Mode:"
-msgstr "_Ombrydningstilstand:"
+#: ../glade/smuxi-frontend-gnome.glade.h:87
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1681
+msgid "_Filters"
+msgstr "_Filtre"
 
-#: ../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 = sekunder\n"
-"mm = minutter\n"
-"hh = timer (01 - 12)\n"
-"HH = timer (00 - 23)\n"
-"tt = AM/PM\n"
-"\n"
-"dd = dag\n"
-"MM = måned\n"
-"yy/yyyy = år"
+#: ../glade/smuxi-frontend-gnome.glade.h:88
+msgid "Enabled"
+msgstr "Aktiveret"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:89
+msgid "Log Filtered Messages"
+msgstr "Logfiltrerede beskeder"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:90
+msgid "_Logging"
+msgstr "_Logning"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:91
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerDialog.cs:16
+msgid "Smuxi - Server"
+msgstr "Smuxi - Server"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:92
+#: ../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:93
+msgid "Protocol:"
+msgstr "Protokol:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:94
+msgid "Network:"
+msgstr "Netværk:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:95
+msgid "Hostname:"
+msgstr "Værtsnavn:"
 
 #: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:1
-msgid "Chat with other people on IRC"
-msgstr "Snak med andre via IRC"
+msgid "Smuxi"
+msgstr "Smuxi"
 
 #: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:2
 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:60
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:4
+msgid "Chat with other people on IRC"
+msgstr "Snak med andre via IRC"
+
+#: ../src/Frontend-GNOME/AboutDialog.cs:65
 msgid "translator-credits"
 msgstr "Joe Hansen <joedalton2 at yahoo.dk>"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:65
+#: ../src/Frontend-GNOME/AboutDialog.cs:72
 msgid "Smuxi Website"
 msgstr "Smuxis hjemmeside"
 
@@ -488,237 +484,134 @@ msgstr "Her er stacktracen, rapporter venligst denne fejl!"
 msgid "_Report Bug"
 msgstr "_Rapporter fejl"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:61
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:66
+msgid "Engine not found."
+msgstr "Motor blev ikke fundet."
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:81
 msgid "Engine Manager"
 msgstr "Motorhåndtering"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:80
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:100
 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:86
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:106
 msgid "Engine:"
 msgstr "Motor:"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:97
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:117
 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
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:141
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:201
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:383
 msgid "Local Engine"
 msgstr "Lokal motor"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:173
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:193
 msgid "Please select an engine!"
 msgstr "Vælg venligst en motor!"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:194
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:219
 #, 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:221
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:246
 msgid "An error occurred while connecting to the engine!"
 msgstr "En fejl opstod under tilslutning til motoren!"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:222
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:247
 #, csharp-format
 msgid "Engine URL: {0}"
 msgstr "Motor-URL: {0}"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:225
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:250
 #, csharp-format
 msgid "Error: {0}"
 msgstr "Fejl: {0}"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:295
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:320
 #, 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:443
+#: ../src/Frontend-GNOME/Entry.cs:474
 #, 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:547
+#: ../src/Frontend-GNOME/Entry.cs:587
 msgid "Frontend Commands"
 msgstr "Grænsefladekommandoer"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:252
-msgid "_File"
-msgstr "_Fil"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:276
-msgid "_Server"
-msgstr "_Server"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:280
-msgid "_Quick Connect"
-msgstr "_Hurtig tilslutning"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:291
-msgid "_Manage"
-msgstr "_HÃ¥ndter"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:298
-msgid "_Chat"
-msgstr "_Snak"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:302
-msgid "Open / Join Chat"
-msgstr "Ã…bn / tilslut snak"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:308
-msgid "_Find Group Chat"
-msgstr "_Find gruppesnak"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:314
-msgid "C_lear All Activity"
-msgstr "_Ryd al aktivitet"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:321
-msgid "_Next Chat"
-msgstr "_Næste snak"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:335
-msgid "_Previous Chat"
-msgstr "_Forrige snak"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:389
-msgid "Open Log"
-msgstr "Ã…bn log"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:407
-msgid "_Engine"
-msgstr "_Motor"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:411
-msgid "_Use Local Engine"
-msgstr "_Brug lokal motor"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:417
-msgid "_Add Remote Engine"
-msgstr "_Tilføj ekstern motor"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:422
-msgid "_Switch Remote Engine"
-msgstr "_Skift ekstern motor"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:429
-msgid "_View"
-msgstr "_Vis"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:433
-msgid "_Caret Mode"
-msgstr "_Markørtilstand"
-
-#: ../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:768
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:225
-msgid "Unable to add server: "
-msgstr "Kunne ikke tilføje server: "
-
-#: ../src/Frontend-GNOME/MainWindow.cs:828
-#, csharp-format
-msgid "Unknown ChatType: {0}"
-msgstr "Ukendt snaktype: {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 ""
-"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:1139
-msgid ""
-"Switching the remote engine will disconnect you from the current engine!\n"
-"Are you sure you want to do this?"
-msgstr ""
-"Skift af den eksterne motor vil afbryde dig fra den aktuelle motor!\n"
-"Er du sikker på, at du ønsker at gøre dette?"
-
 #: ../src/Frontend-GNOME/NotImplementedMessageDialog.cs:40
 msgid "Sorry, not implemented yet!"
 msgstr "Beklager, ikke implementeret endnu!"
 
 #. fill ListStore
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:179
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:185
 msgid "Character"
 msgstr "Tegn"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:180
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:186
 msgid "Word"
 msgstr "Ord"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:197
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:203
 msgid "Volatile"
 msgstr "Ustabile"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:199
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:205
 msgid "Persistent"
 msgstr "Persistent"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:222
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:228
 msgid "No Proxy"
 msgstr "Ingen proxy"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:224
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:307
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:230
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:318
 msgid "System Default"
 msgstr "Systemstandard"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:238
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:244
 #: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:140
 msgid "Connection"
 msgstr "Tilslutning"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:242
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:248
 msgid "Interface"
 msgstr "Grænseflade"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:246
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:252
 msgid "Servers"
 msgstr "Servere"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:253
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:259
 msgid "Filters"
 msgstr "Filtre"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:257
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:263
 msgid "Logging"
 msgstr "Logning"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:642
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:666
 msgid "Nicknames(s) field must not be empty."
 msgstr "Brugernavnsfelter må ikke være tomme."
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:823
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:857
 #, csharp-format
 msgid "Invalid highlight regex: '{0}'. Reason: {1}"
 msgstr "Ugyldigt fremhævet regulært udtryk: '{0}'. Årsag: {1}"
 
 #: ../src/Frontend-GNOME/FindGroupChatDialog.cs:81
 #: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:106
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:271
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:265
 msgid "Name"
 msgstr "Navn"
 
@@ -730,78 +623,70 @@ msgstr "Emne"
 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 ""
-"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?"
+msgstr "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: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:325
+#: ../src/Frontend-GNOME/Frontend.cs:400
 msgid "Disconnected from engine."
 msgstr "Afbrudt fra motor."
 
-#: ../src/Frontend-GNOME/Frontend.cs:368
+#: ../src/Frontend-GNOME/Frontend.cs:442
 #, csharp-format
 msgid "Reconnecting to engine... (attempt {0})"
 msgstr "Forbinder til motor igen... (forsøg {0})"
 
-#: ../src/Frontend-GNOME/Frontend.cs:465
+#: ../src/Frontend-GNOME/Frontend.cs:540
 #, csharp-format
 msgid "Cause: {0}"
 msgstr "Ã…rsag: {0}"
 
-#: ../src/Frontend-GNOME/Frontend.cs:583
+#: ../src/Frontend-GNOME/Frontend.cs:666
 msgid ""
 "The frontend has lost the connection to the server.\n"
 "Do you want to reconnect now?"
-msgstr ""
-"Grænsefladen har mistet forbindelsen til serveren.\n"
-"Ønsker du at tilslutte nu?"
+msgstr "Grænsefladen har mistet forbindelsen til serveren.\nØnsker du at tilslutte nu?"
 
-#: ../src/Frontend-GNOME/Frontend.cs:602
+#: ../src/Frontend-GNOME/Frontend.cs:685
 msgid ""
 "Reconnecting to the server has failed.\n"
 "Do you want to try again?"
-msgstr ""
-"Gentilslutning til serveren mislykkedes.\n"
-"Ønsker du at forsøge igen?"
+msgstr "Gentilslutning til serveren mislykkedes.\nØnsker du at forsøge igen?"
 
-#: ../src/Frontend-GNOME/Frontend.cs:705
+#: ../src/Frontend-GNOME/Frontend.cs:974
 msgid ""
 "The server has lost the connection to the frontend.\n"
 "Do you want to reconnect now?"
-msgstr ""
-"Serveren har mistet forbindelsen til grænsefladen.\n"
-"Ønsker du at tilslutte igen?"
+msgstr "Serveren har mistet forbindelsen til grænsefladen.\nØnsker du at tilslutte igen?"
 
-#: ../src/Frontend-GNOME/NotifyManager.cs:267
+#: ../src/Frontend-GNOME/NotifyManager.cs:336
 msgid "Show"
 msgstr "Vis"
 
-#: ../src/Frontend-GNOME/QuickConnectDialog.cs:62
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:238
+#: ../src/Frontend-GNOME/QuickConnectDialog.cs:58
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:233
 #: ../src/Frontend-GNOME/Preferences/ServerListView.cs:70
 msgid "Protocol"
 msgstr "Protokol"
 
-#: ../src/Frontend-GNOME/QuickConnectDialog.cs:63
+#: ../src/Frontend-GNOME/QuickConnectDialog.cs:59
 #: ../src/Frontend-GNOME/Preferences/ServerListView.cs:71
 msgid "Hostname"
 msgstr "Værtsnavn"
 
-#: ../src/Frontend-GNOME/QuickConnectDialog.cs:166
+#: ../src/Frontend-GNOME/QuickConnectDialog.cs:162
 msgid "Unable to load server: "
 msgstr "Kunne ikke indlæse server: "
 
 #: ../src/Frontend-GNOME/ChatTypeWidget.cs:54
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:244
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:239
 msgid "Person / Private"
 msgstr "Person / privat"
 
 #: ../src/Frontend-GNOME/ChatTypeWidget.cs:55
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:245
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:240
 msgid "Group / Public"
 msgstr "Gruppe / offenlig"
 
@@ -834,82 +719,116 @@ 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:204
+#: ../src/Frontend-GNOME/Views/JoinWidget.cs:87
+msgid "Enter which chat to join"
+msgstr "Indtast hvilken samtale (chat) du ønsker at deltage i"
+
+#: ../src/Frontend-GNOME/Views/MenuWidget.cs:140
+msgid "About Smuxi"
+msgstr "Om Smuxi"
+
+#. TODO: add cmd+, accelerator
+#: ../src/Frontend-GNOME/Views/MenuWidget.cs:144
+msgid "Preferences"
+msgstr "Præferencer"
+
+#: ../src/Frontend-GNOME/Views/MenuWidget.cs:238
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:227
+msgid "Unable to add server: "
+msgstr "Kunne ikke tilføje server: "
+
+#: ../src/Frontend-GNOME/Views/MenuWidget.cs:359
+msgid ""
+"Switching to local engine will disconnect you from the current engine!\n"
+"Are you sure you want to do this?"
+msgstr "Skift til lokal motor vil afbryde dig fra den aktuelle motor!\nEr du sikker på, at du ønsker at gøre dette?"
+
+#: ../src/Frontend-GNOME/Views/MenuWidget.cs:403
+msgid ""
+"Switching the remote engine will disconnect you from the current engine!\n"
+"Are you sure you want to do this?"
+msgstr "Skift af den eksterne motor vil afbryde dig fra den aktuelle motor!\nEr du sikker på, at du ønsker at gøre dette?"
+
+#: ../src/Frontend-GNOME/Views/MessageTextView.cs:273
 #, csharp-format
 msgid "Day changed from {0} to {1}"
 msgstr "Dag ændret fra {0} til {1}"
 
-#: ../src/Frontend-GNOME/Views/MessageTextView.cs:210
+#: ../src/Frontend-GNOME/Views/MessageTextView.cs:277
 #, csharp-format
 msgid "Day changed to {0}"
 msgstr "Dag ændret til {0}"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:123
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:133
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:120
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:130
 #, csharp-format
 msgid "Invalid filter regex: '{0}'. Reason: {1}"
 msgstr "Ugyldig filter for regulært udtryk: '{0}'. Årsag: {1}"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:200
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:197
 msgid "Are you sure you want to delete the selected filter?"
 msgstr "Er du sikker på, at du ønsker at slette det valgte filter?"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:246
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:241
 msgid "Protocol / Server"
 msgstr "Protokol / server"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:253
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:248
 msgid "Chat Type"
 msgstr "Snaktype"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:287
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:281
 msgid "Normal"
 msgstr "Normal"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:288
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:282
 msgid "Event"
 msgstr "Begivenhed"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:295
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:289
 msgid "Type"
 msgstr "Type"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:321
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:314
 msgid "Pattern"
 msgstr "Mønster"
 
-#: ../src/Frontend-GNOME/Views/Chats/ChatView.cs:506
+#: ../src/Frontend-GNOME/Views/Chats/ChatView.cs:538
 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
+#: ../src/Frontend-GNOME/Views/Chats/ChatView.cs:764
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:135
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:136
+msgid "Show _Menubar"
+msgstr "Vis _menubjælke"
+
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:275
 #, 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:279
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:309
 msgid "done."
 msgstr "færdig."
 
-#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:290
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:320
 msgid "Person"
 msgstr "Person"
 
-#: ../src/Frontend-GNOME/Views/Chats/ProtocolChatView.cs:69
+#: ../src/Frontend-GNOME/Views/Chats/ProtocolChatView.cs:146
 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"
-"Er du sikker på, at du ønsker at gøre dette?"
+msgstr "Lukning af protokolsamtalen vil også lukke alle åbne samtalerum der er forbundet til den!\nEr du sikker på, at du ønsker at gøre dette?"
 
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:187
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:189
 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:243
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:277
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:245
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:279
 msgid "Unable to edit server: "
 msgstr "Kunne ikke redigere server: "
 
@@ -942,13 +861,169 @@ msgid "Smuxi - Find Group Chat"
 msgstr "Smuxi - Find gruppesnak"
 
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:47
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:73
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:71
 msgid "_Name:"
 msgstr "_Navn:"
 
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.JoinWidget.cs:69
+msgid "Join"
+msgstr "Deltag"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:55
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:56
+msgid "_Smuxi"
+msgstr "_Smuxi"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:58
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:59
+msgid "_Server"
+msgstr "_Server"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:61
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:62
+msgid "_Chat"
+msgstr "_Snak"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:64
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:65
+msgid "_Engine"
+msgstr "_Motor"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:67
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:68
+msgid "_View"
+msgstr "_Vis"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:70
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:71
+msgid "_Help"
+msgstr "_Hjælp"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:73
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:75
+msgid "Connect"
+msgstr "Forbind"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:77
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:79
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:150
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:151
+msgid "Open Log"
+msgstr "Ã…bn log"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:87
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:88
+msgid "_Preferences"
+msgstr "_Præferencer"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:90
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:91
+msgid "_Quit"
+msgstr "_Afslut"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:93
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:94
+msgid "_Connect"
+msgstr "_Forbind"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:96
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:97
+msgid "_Add"
+msgstr "_Tilføj"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:99
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:100
+msgid "_Manage"
+msgstr "_HÃ¥ndter"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:102
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:103
+msgid "_Open / Join Chat"
+msgstr "_Ã…bn / deltag i samtale"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:105
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:106
+msgid "_Find Group Chat"
+msgstr "_Find gruppesnak"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:108
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:109
+msgid "C_lear All Activity"
+msgstr "_Ryd al aktivitet"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:111
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:112
+msgid "_Next Chat"
+msgstr "_Næste snak"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:114
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:115
+msgid "_Previous Chat"
+msgstr "_Forrige snak"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:117
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:118
+msgid "_Close"
+msgstr "_Luk"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:120
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:121
+msgid "_Use Local Engine"
+msgstr "_Brug lokal motor"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:123
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:124
+msgid "_Add Remote Engine"
+msgstr "_Tilføj ekstern motor"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:126
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:127
+msgid "Switch Remote Engine"
+msgstr "Skift ekstern motor"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:129
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:130
+msgid "_Caret Mode"
+msgstr "_Markørtilstand"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:132
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:133
+msgid "_Browse Mode"
+msgstr "_Navigeringstilstand"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:138
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:139
+msgid "Show _Statusbar"
+msgstr "Vis _statuslinje"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:141
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:142
+msgid "Show _Join Bar"
+msgstr "Vis _deltagelseslinje"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:144
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:145
+msgid "_Fullscreen"
+msgstr "_Fuldskærm"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:147
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:148
+msgid "_About"
+msgstr "_Om"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:153
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:155
+msgid "Find Group Chat"
+msgstr "Find gruppesamtale"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:157
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:158
+msgid "_Website"
+msgstr "_Hjemmeside"
+
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs:19
-msgid "Smuxi - Quick Connect"
-msgstr "Smuxi - hurtig tilslutning"
+msgid "Smuxi - Connect"
+msgstr "Smuxi - forbind"
 
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:206
 msgid "Smuxi - Preferences"
@@ -983,10 +1058,7 @@ 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\">Aktiverer brugen af SSH til forbindelsen. Dette har en "
-"mindre ydelsespåvirkning, men er mere sikker og krævet med brug af NAT- "
-"eller portbaserede brandmure (firewalls)</span>"
+msgstr "<span size=\"small\">Aktiverer brugen af SSH til forbindelsen. Dette har en 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:135
 msgid "SSH _Host:"
@@ -1004,8 +1076,7 @@ msgstr "_Port:"
 
 #: ../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>"
+msgstr "<span size=\"small\">DNS- eller IP-adresse og port på Smuxiserveren</span>"
 
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:199
 msgid "_Smuxi Host:"
@@ -1019,9 +1090,7 @@ msgstr "_SSH-brugernavn: (valgfri)"
 msgid ""
 "<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>"
+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:95
 msgid "_SSH Password: (optional)"
@@ -1032,10 +1101,7 @@ 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\">Adgangskode vil blive brugt til at logge ind på SSH-"
-"serveren. Adgangskoden er valgfri hvis SSH-nøglegodkendelse anvendes (se "
-"nedenfor).</span>"
+msgstr "<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)"
@@ -1050,9 +1116,7 @@ msgstr "Vælg en fil"
 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>"
+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
@@ -1063,9 +1127,7 @@ msgstr "_Brugernavn:"
 msgid ""
 "<span size=\"small\">Username which will be used to log into the Smuxi "
 "server</span>"
-msgstr ""
-"<span size=\"small\">Brugernavn som vil blive brugt til at logge ind til "
-"Smuxiserveren</span>"
+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:224
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:87
@@ -1090,11 +1152,7 @@ msgid ""
 "You need to enter some information before you can use the engine.\n"
 "\n"
 "Click \"Forward\" to begin."
-msgstr ""
-"Velkommen til konfigurationsassistenten til Smuximotoren.\n"
-"Det er nødvendigt at indtaste nogle informationer før du kan bruge motoren.\n"
-"\n"
-"Klik »Fremad« for at begynde."
+msgstr "Velkommen til konfigurationsassistenten til Smuximotoren.\nDet er nødvendigt at indtaste nogle informationer før du kan bruge motoren.\n\nKlik »Fremad« for at begynde."
 
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:36
 msgid "_Engine Name:"
@@ -1116,15 +1174,13 @@ msgstr "Brug som ny standardmotor"
 msgid ""
 "<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>"
+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:20
 msgid "Smuxi - Open Chat"
 msgstr "Smuxi - åben snak"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:63
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:61
 msgid "_Type:"
 msgstr "_Type:"
 
@@ -1155,5 +1211,3 @@ msgstr "Kommandoer _ved tilslutning:"
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:265
 msgid "_Ignore Commands"
 msgstr "_Ignorer kommandoer"
-
-
diff --git a/po-Frontend-GNOME/de.po b/po-Frontend-GNOME/de.po
index d9e7937..2529040 100644
--- a/po-Frontend-GNOME/de.po
+++ b/po-Frontend-GNOME/de.po
@@ -3,211 +3,194 @@
 # This file is distributed under the same license as the PACKAGE package.
 # 
 # Translators:
-# Bianca Mix <heavydemon at freenet.de>, 2011.
+# Bianca Mix <heavydemon at freenet.de>, 2011-2013.
 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: 2011-12-30 22:54+0000\n"
+"POT-Creation-Date: 2013-04-14 10:19+0200\n"
+"PO-Revision-Date: 2013-04-14 19:41+0000\n"
 "Last-Translator: Bianca Mix <heavydemon at freenet.de>\n"
-"Language-Team: German (http://www.transifex.net/projects/p/smuxi/team/de/)\n"
+"Language-Team: German (http://www.transifex.com/projects/p/smuxi/language/de/)\n"
 "MIME-Version: 1.0\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"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:1
-msgid "<b> Chat </b>"
-msgstr "<b> Chat </b>"
+msgid "Smuxi Preferences"
+msgstr "Smuxi Einstellungen"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:2
-msgid "<b> Color </b>"
-msgstr "<b> Farbe </b>"
+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:3
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1172
-msgid "<b> Entry Field </b>"
-msgstr "<b> Eingabefeld </b>"
+msgid "Nickname(s):"
+msgstr "Nickname(n):"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:4
-msgid "<b> Font </b>"
-msgstr "<b> Schrift </b>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:315
+msgid "Username:"
+msgstr "Benutzername:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:5
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1502
-msgid "<b> Highlighting </b>"
-msgstr "<b> Highlighting </b>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:338
+msgid "Realname:"
+msgstr "Wirklicher Name:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:6
-msgid "<b> Notification Area Icon </b>"
-msgstr "<b> Symbol im Benachrichtigungsfeld </b>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:359
+msgid "Encoding:"
+msgstr "Kodierung:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:7
-msgid "<b> Person List Position </b>"
-msgstr "<b> Position der Personenliste </b>"
+msgid "<b>General</b>"
+msgstr "Allgemein"
 
 #: ../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> Farbe der Reiter </b>"
+msgid "Type:"
+msgstr "Typ:"
 
 #: ../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> Position der Reiter </b>"
+msgid "Host:"
+msgstr "Host:"
 
 #: ../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> Position des Themas </b>"
+msgid "Password:"
+msgstr "Passwort:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:11
-msgid "<b>Advanced</b>"
-msgstr "Erweitert"
+msgid "Port:"
+msgstr "Port:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:12
-msgid "<b>General</b>"
-msgstr "Allgemein"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:170
+msgid "Show Password"
+msgstr "Passwort anzeigen"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:13
-msgid "<b>Global Commands</b>"
-msgstr "übergreifende Kommandos"
+msgid "<b>Network Proxy</b>"
+msgstr "Netzwerk Proxy"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:14
-msgid "<b>Message Buffer</b>"
-msgstr "Nachrichtenpuffer"
+#: ../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:15
-msgid "<b>Messaging Menu</b>"
-msgstr "Messaging-Menü"
+#: ../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:16
-msgid "<b>Network Proxy</b>"
-msgstr "Netzwerk Proxy"
+msgid "<b>Global Commands</b>"
+msgstr "übergreifende Kommandos"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:17
-msgid "<b>Notification Popups</b>"
-msgstr "<b>Beachrichtigungs-Pop-ups</b>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:471
+msgid "C_onnection"
+msgstr "_Verbindung"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:18
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:961
-msgid "Activity"
-msgstr "Aktivität"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:526
+msgid "Timestamp Format:"
+msgstr "Zeitstempel-Format:"
 
 #: ../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:20
-msgid "Background"
-msgstr "Hintergrund"
-
-#: ../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: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: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:24
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:546
 msgid "Buffer Lines:"
 msgstr "Puffer-Zeilen:"
 
-#: ../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:26
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1112
-msgid "Command Character:"
-msgstr "Befehlszeichen:"
-
-#: ../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:28
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1092
-msgid "Completion Character:"
-msgstr "Vervollständigungzeichen:"
+#: ../glade/smuxi-frontend-gnome.glade.h:20
+#: ../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:29
-msgid "Enable"
-msgstr "Aktivieren"
+#: ../glade/smuxi-frontend-gnome.glade.h:21
+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 = Sekunden\nmm = Minuten\nhh = Stunden (1 - 12)\nHH = Stunden (0 - 23)\ntt = AM/PM\n\ndd = Tag\nMM = Monat\nyy/yyyy = Jahr"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:30
-msgid "Enabled"
-msgstr "Aktiviert"
+msgid "Persistency Type:"
+msgstr "Persistenz-Typ"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:31
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:359
-msgid "Encoding:"
-msgstr "Kodierung:"
+msgid "Volatile Buffer Lines:"
+msgstr "Zeilen Volatilitäts-Puffer"
 
 #: ../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:"
+msgid "Persistent Buffer Lines:"
+msgstr "Zeilen Persistenz-Puffer"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:33
-msgid "Foreground"
-msgstr "Vordergrund"
+msgid "<b>Message Buffer</b>"
+msgstr "Nachrichtenpuffer"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:34
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:725
-msgid "General"
-msgstr "Allgemein"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:628
+msgid "Strip Colors"
+msgstr "Farben entfernen"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:35
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:981
-msgid "Highlight"
-msgstr "Highlight"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:667
+msgid "Strip Formattings"
+msgstr "Formatierungen entfernen"
 
 #: ../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:"
+#: ../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:37
-msgid "Host:"
-msgstr "Host:"
+msgid "Show Advanced Settings"
+msgstr "Zeige erweiterte Einstellungen"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:38
-msgid "Hostname:"
-msgstr "Hostname:"
+msgid "<b>Advanced</b>"
+msgstr "Erweitert"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:39
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1181
-msgid "Input"
-msgstr "Eingabe"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:725
+msgid "General"
+msgstr "Allgemein"
 
+#. Container child vbox6.Gtk.Box+BoxChild
+#. Container child vbox11.Gtk.Box+BoxChild
 #: ../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"
+#: ../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"
 
 #. Container child vbox6.Gtk.Box+BoxChild
-#. Container child vbox12.Gtk.Box+BoxChild
+#. Container child vbox11.Gtk.Box+BoxChild
 #: ../glade/smuxi-frontend-gnome.glade.h:41
+#: ../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"
+
+#. Container child vbox6.Gtk.Box+BoxChild
+#. Container child vbox12.Gtk.Box+BoxChild
+#: ../glade/smuxi-frontend-gnome.glade.h:42
 #: ../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
@@ -215,263 +198,273 @@ msgstr "Beitreten/Verlassen/Mode"
 msgid "Left"
 msgstr "Links"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:42
-msgid "Log Filtered Messages"
-msgstr "Protokollierung gefilterter Nachrichten"
-
+#. Container child vbox6.Gtk.Box+BoxChild
+#. Container child vbox12.Gtk.Box+BoxChild
 #: ../glade/smuxi-frontend-gnome.glade.h:43
-msgid "Network:"
-msgstr "Netzwerk:"
-
-#: ../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:45
-msgid "Nickname(s):"
-msgstr "Nickname(n):"
-
-#: ../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"
+#: ../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"
 
 #. 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
+#: ../glade/smuxi-frontend-gnome.glade.h:44
 #: ../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:45
+#: ../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:46
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:981
+msgid "Highlight"
+msgstr "Highlight"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:47
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:961
+msgid "Activity"
+msgstr "Aktivität"
+
 #: ../glade/smuxi-frontend-gnome.glade.h:48
-msgid "Notification"
-msgstr "Benachrichtigung"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:953
+msgid "No Activity"
+msgstr "Keine Aktivität"
 
 #: ../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:"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:971
+msgid "Join/Part/Mode"
+msgstr "Beitreten/Verlassen/Mode"
 
 #: ../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:"
+#: ../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:51
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1514
-msgid "Output"
-msgstr "Ausgabe"
+msgid "Automatically switch to newly opened person chats"
+msgstr "Automatisches Wechseln zu neu geöffneten Personen-Gesprächsfenstern"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:52
-msgid "Override"
-msgstr "Ãœbersteuern"
+msgid "Automatically switch to newly opened group chats"
+msgstr "Automatisches Wechseln zu neu geöffneten Gruppen-Gesprächsfenstern"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:53
-msgid "Password:"
-msgstr "Passwort:"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1022
+msgid "Tabs"
+msgstr "Reiter"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:54
-msgid "Persistency Type:"
-msgstr "Persistenz-Typ"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1092
+msgid "Completion Character:"
+msgstr "Vervollständigungzeichen:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:55
-msgid "Persistent Buffer Lines:"
-msgstr "Zeilen Persistenz-Puffer"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1112
+msgid "Command Character:"
+msgstr "Befehlszeichen:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:56
-msgid "Port:"
-msgstr "Port:"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1135
+msgid "Command History Size:"
+msgstr "Befehlsprotokollgröße:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:57
-msgid "Protocol:"
-msgstr "Protokoll:"
+#: ../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:58
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:338
-msgid "Realname:"
-msgstr "Wirklicher Name:"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1172
+msgid "<b> Entry Field </b>"
+msgstr "<b> Eingabefeld </b>"
 
-#. 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 "Rechts"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1181
+msgid "Input"
+msgstr "Eingabe"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:60
-msgid "Show Advanced Settings"
-msgstr "Zeige erweiterte Einstellungen"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1202
+msgid "Nick Colors"
+msgstr "Nick-Farben"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:61
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:170
-msgid "Show Password"
-msgstr "Passwort anzeigen"
+msgid "<b> Person List Position </b>"
+msgstr "<b> Position der Personenliste </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:62
-msgid "Show Smuxi in the messaging menu"
-msgstr "Zeige Smuxi im Messaging-Menü"
+msgid "Override"
+msgstr "Ãœbersteuern"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:63
-msgid "Show always"
-msgstr "Immer anzeigen"
+msgid "<b> Font </b>"
+msgstr "<b> Schrift </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:64
-msgid "Show notification popups"
-msgstr "Zeige Benachrichtigungs-Pop-ups"
+#: ../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:65
-msgid "Show when window is closed"
-msgstr "Anzeigen, wenn Fenster geschlossen ist"
+msgid "Foreground"
+msgstr "Vordergrund"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:66
-msgid "Show when window is minimized"
-msgstr "Zeigen, wenn Fenster minimiert ist"
+msgid "Background"
+msgstr "Hintergrund"
 
 #: ../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:68
-msgid "Smuxi Preferences"
-msgstr "Smuxi Einstellungen"
+msgid "<b> Color </b>"
+msgstr "<b> Farbe </b>"
 
+#. This is a setting for character based line wrapping vs word based when
+#. showing messages
 #: ../glade/smuxi-frontend-gnome.glade.h:69
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:628
-msgid "Strip Colors"
-msgstr "Farben entfernen"
+msgid "_Wrap Mode:"
+msgstr "_Umbruch-Modus"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:70
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:667
-msgid "Strip Formattings"
-msgstr "Formatierungen entfernen"
+msgid "<b> Chat </b>"
+msgstr "<b> Chat </b>"
 
 #: ../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"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1466
+msgid "Highlight words:"
+msgstr "Highlight-Wörter:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:72
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1022
-msgid "Tabs"
-msgstr "Reiter"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1490
+msgid "Beep on highlight"
+msgstr "Bei Highlight piepsen"
 
 #: ../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."
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1502
+msgid "<b> Highlighting </b>"
+msgstr "<b> Highlighting </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:74
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:526
-msgid "Timestamp Format:"
-msgstr "Zeitstempel-Format:"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1514
+msgid "Output"
+msgstr "Ausgabe"
 
-#. 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 "Oben"
+msgid "Enable"
+msgstr "Aktivieren"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:76
+msgid "Show always"
+msgstr "Immer anzeigen"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:77
+msgid "Show when window is minimized"
+msgstr "Zeigen, wenn Fenster minimiert ist"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:78
+msgid "Show when window is closed"
+msgstr "Anzeigen, wenn Fenster geschlossen ist"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:79
+msgid "<b> Notification Area Icon </b>"
+msgstr "<b> Symbol im Benachrichtigungsfeld </b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:80
+msgid "Show Smuxi in the messaging menu"
+msgstr "Zeige Smuxi im Messaging-Menü"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:81
+msgid "<b>Messaging Menu</b>"
+msgstr "Messaging-Menü"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:76
-msgid "Type:"
-msgstr "Typ:"
+#: ../glade/smuxi-frontend-gnome.glade.h:82
+msgid "Show notification popups"
+msgstr "Zeige Benachrichtigungs-Pop-ups"
 
-#: ../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:83
+msgid "<b>Notification Popups</b>"
+msgstr "<b>Beachrichtigungs-Pop-ups</b>"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:78
-msgid "Volatile Buffer Lines:"
-msgstr "Zeilen Volatilitäts-Puffer"
+#: ../glade/smuxi-frontend-gnome.glade.h:84
+msgid "Notification"
+msgstr "Benachrichtigung"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:79
+#: ../glade/smuxi-frontend-gnome.glade.h:85
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1523
+msgid "_Interface"
+msgstr "_Anzeige"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:86
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1589
+msgid "_Servers"
+msgstr "_Server"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:87
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1681
 msgid "_Filters"
 msgstr "_Filter"
 
-#: ../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:88
+msgid "Enabled"
+msgstr "Aktiviert"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:81
+#: ../glade/smuxi-frontend-gnome.glade.h:89
+msgid "Log Filtered Messages"
+msgstr "Protokollierung gefilterter Nachrichten"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:90
 msgid "_Logging"
 msgstr "_Geprächsprotokollierung"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:82
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1589
-msgid "_Servers"
-msgstr "_Server"
+#: ../glade/smuxi-frontend-gnome.glade.h:91
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerDialog.cs:16
+msgid "Smuxi - Server"
+msgstr "Smuxi - Server"
 
-#. 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 "_Umbruch-Modus"
+#: ../glade/smuxi-frontend-gnome.glade.h:92
+#: ../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: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 = Sekunden\n"
-"mm = Minuten\n"
-"hh = Stunden (1 - 12)\n"
-"HH = Stunden (0 - 23)\n"
-"tt = AM/PM\n"
-"\n"
-"dd = Tag\n"
-"MM = Monat\n"
-"yy/yyyy = Jahr"
+#: ../glade/smuxi-frontend-gnome.glade.h:93
+msgid "Protocol:"
+msgstr "Protokoll:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:94
+msgid "Network:"
+msgstr "Netzwerk:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:95
+msgid "Hostname:"
+msgstr "Hostname:"
 
 #: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:1
-msgid "Chat with other people on IRC"
-msgstr "Kommuniziere mit anderen Leuten im IRC"
+msgid "Smuxi"
+msgstr "Smuxi"
 
 #: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:2
 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:60
-msgid "translator-credits"
-msgstr ""
-"Mirco Bauer <meebey at meebey.net>\n"
-"Bianca Mix <heavydemon at freenet.de>"
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:4
+msgid "Chat with other people on IRC"
+msgstr "Kommuniziere mit anderen Leuten im IRC"
 
 #: ../src/Frontend-GNOME/AboutDialog.cs:65
+msgid "translator-credits"
+msgstr "Mirco Bauer <meebey at meebey.net>\nBianca Mix <heavydemon at freenet.de>"
+
+#: ../src/Frontend-GNOME/AboutDialog.cs:72
 msgid "Smuxi Website"
 msgstr "Smuxi Webseite"
 
@@ -481,8 +474,7 @@ msgstr "Ups, ich habe es wieder getan..."
 
 #: ../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:63
 msgid "Here is the stacktrace, please report this bug!"
@@ -492,239 +484,134 @@ msgstr "Hier ist der Stack-Trace, bitte berichten Sie diesen Fehler!"
 msgid "_Report Bug"
 msgstr "_Fehler berichten"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:61
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:66
+msgid "Engine not found."
+msgstr "Engine nicht gefunden."
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:81
 msgid "Engine Manager"
 msgstr "Engine-Manager"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:80
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:100
 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:86
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:106
 msgid "Engine:"
 msgstr "Engine:"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:97
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:117
 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
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:141
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:201
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:383
 msgid "Local Engine"
 msgstr "Lokale Engine"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:173
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:193
 msgid "Please select an engine!"
 msgstr "Bitte wählen Sie eine Engine aus!"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:194
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:219
 #, 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:221
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:246
 msgid "An error occurred while connecting to the engine!"
 msgstr "Ein Fehler ist beim Verbinden zur Engine aufgetreten!"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:222
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:247
 #, csharp-format
 msgid "Engine URL: {0}"
 msgstr "Engine URL: {0}"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:225
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:250
 #, csharp-format
 msgid "Error: {0}"
 msgstr "Fehler: {0}"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:295
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:320
 #, 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:443
+#: ../src/Frontend-GNOME/Entry.cs:474
 #, 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:547
+#: ../src/Frontend-GNOME/Entry.cs:587
 msgid "Frontend Commands"
 msgstr "Frontend Befehle"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:252
-msgid "_File"
-msgstr "_Datei"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:276
-msgid "_Server"
-msgstr "_Server"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:280
-msgid "_Quick Connect"
-msgstr "_Schnelles Verbinden"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:291
-msgid "_Manage"
-msgstr "_Verwalten"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:298
-msgid "_Chat"
-msgstr "_Chat"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:302
-msgid "Open / Join Chat"
-msgstr "Chat öffnen / beitreten"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:308
-msgid "_Find Group Chat"
-msgstr "_Finde Gruppen-Chat"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:314
-msgid "C_lear All Activity"
-msgstr "Alle Aktivitäten _löschen"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:321
-msgid "_Next Chat"
-msgstr "_Nächster Chat"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:335
-msgid "_Previous Chat"
-msgstr "_Vorheriger Chat"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:389
-msgid "Open Log"
-msgstr "Mitschnitt Öffnen"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:407
-msgid "_Engine"
-msgstr "_Engine"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:411
-msgid "_Use Local Engine"
-msgstr "_Verwende lokale Engine"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:417
-msgid "_Add Remote Engine"
-msgstr "_Füge entfernte Engine hinzu"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:422
-msgid "_Switch Remote Engine"
-msgstr "_Entfernte Engine wechseln"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:429
-msgid "_View"
-msgstr "_Anzeige"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:433
-msgid "_Caret Mode"
-msgstr "_Caret-Modus"
-
-#: ../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: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:828
-#, csharp-format
-msgid "Unknown ChatType: {0}"
-msgstr "Unbekannter Chat-Typ: {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 ""
-"Das Wechseln zur lokalen Engine wird Sie von der jetzigen Engine trennen!\n"
-"Möchten Sie fortfahren?"
-
-#: ../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 ""
-"Das Wechseln zur entfernten Engine wird Sie von der jetzigen Engine trennen!\n"
-"Möchten Sie fortfahren?"
-
 #: ../src/Frontend-GNOME/NotImplementedMessageDialog.cs:40
 msgid "Sorry, not implemented yet!"
 msgstr "Tut mir leid, das ist noch nicht implementiert!"
 
 #. fill ListStore
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:179
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:185
 msgid "Character"
 msgstr "Zeichen"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:180
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:186
 msgid "Word"
 msgstr "Wort"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:197
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:203
 msgid "Volatile"
 msgstr "Volatil"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:199
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:205
 msgid "Persistent"
 msgstr "Persistent"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:222
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:228
 msgid "No Proxy"
 msgstr "Kein Proxy"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:224
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:307
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:230
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:318
 msgid "System Default"
 msgstr "System-Standard"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:238
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:244
 #: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:140
 msgid "Connection"
 msgstr "Verbindung"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:242
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:248
 msgid "Interface"
 msgstr "Anzeige"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:246
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:252
 msgid "Servers"
 msgstr "Server"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:253
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:259
 msgid "Filters"
 msgstr "Filter"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:257
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:263
 msgid "Logging"
 msgstr "Geprächsprotokollierung"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:642
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:666
 msgid "Nicknames(s) field must not be empty."
 msgstr "Das Nickname(n)-Feld darf nicht leer sein."
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:823
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:857
 #, csharp-format
 msgid "Invalid highlight regex: '{0}'. Reason: {1}"
 msgstr "Ungültiger Highlight regex: '{0}'. Ursache: {1}"
 
 #: ../src/Frontend-GNOME/FindGroupChatDialog.cs:81
 #: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:106
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:271
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:265
 msgid "Name"
 msgstr "Name"
 
@@ -736,78 +623,70 @@ msgstr "Thema"
 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 ""
-"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?"
+msgstr "Vom Suchen nach Gruppen-Chats ohne einen Filter wird abgeraten. Es könnte eine Weile dauern, oder es funktioniert gar nicht.\nMöchten Sie fortfahren?"
 
 #: ../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:325
+#: ../src/Frontend-GNOME/Frontend.cs:400
 msgid "Disconnected from engine."
 msgstr "Von der Engine getrennt."
 
-#: ../src/Frontend-GNOME/Frontend.cs:368
+#: ../src/Frontend-GNOME/Frontend.cs:442
 #, csharp-format
 msgid "Reconnecting to engine... (attempt {0})"
 msgstr "Wiederverbinden zur Engine... (Versuch {0})"
 
-#: ../src/Frontend-GNOME/Frontend.cs:465
+#: ../src/Frontend-GNOME/Frontend.cs:540
 #, csharp-format
 msgid "Cause: {0}"
 msgstr "Grund: {0}"
 
-#: ../src/Frontend-GNOME/Frontend.cs:583
+#: ../src/Frontend-GNOME/Frontend.cs:666
 msgid ""
 "The frontend has lost the connection to the server.\n"
 "Do you want to reconnect now?"
-msgstr ""
-"Der Server hat die Verbindung zum Frontend verloren.\n"
-"Möchten Sie diese nun erneut aufbauen?"
+msgstr "Der Server hat die Verbindung zum Frontend verloren.\nMöchten Sie diese nun erneut aufbauen?"
 
-#: ../src/Frontend-GNOME/Frontend.cs:602
+#: ../src/Frontend-GNOME/Frontend.cs:685
 msgid ""
 "Reconnecting to the server has failed.\n"
 "Do you want to try again?"
-msgstr ""
-"Erneutes Verbindung zum Server ist fehlgeschlagen.\n"
-"Möchten Sie es nochmals versuchen?"
+msgstr "Erneutes Verbindung zum Server ist fehlgeschlagen.\nMöchten Sie es nochmals versuchen?"
 
-#: ../src/Frontend-GNOME/Frontend.cs:705
+#: ../src/Frontend-GNOME/Frontend.cs:974
 msgid ""
 "The server has lost the connection to the frontend.\n"
 "Do you want to reconnect now?"
-msgstr ""
-"Der Server hat die Verbindung zum Frontend verloren.\n"
-"Möchten Sie diese nun erneut aufbauen?"
+msgstr "Der Server hat die Verbindung zum Frontend verloren.\nMöchten Sie diese nun erneut aufbauen?"
 
-#: ../src/Frontend-GNOME/NotifyManager.cs:267
+#: ../src/Frontend-GNOME/NotifyManager.cs:336
 msgid "Show"
 msgstr "Zeige"
 
-#: ../src/Frontend-GNOME/QuickConnectDialog.cs:62
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:238
+#: ../src/Frontend-GNOME/QuickConnectDialog.cs:58
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:233
 #: ../src/Frontend-GNOME/Preferences/ServerListView.cs:70
 msgid "Protocol"
 msgstr "Protokoll"
 
-#: ../src/Frontend-GNOME/QuickConnectDialog.cs:63
+#: ../src/Frontend-GNOME/QuickConnectDialog.cs:59
 #: ../src/Frontend-GNOME/Preferences/ServerListView.cs:71
 msgid "Hostname"
 msgstr "Hostname"
 
-#: ../src/Frontend-GNOME/QuickConnectDialog.cs:166
+#: ../src/Frontend-GNOME/QuickConnectDialog.cs:162
 msgid "Unable to load server: "
 msgstr "Laden des Servers nicht möglich:"
 
 #: ../src/Frontend-GNOME/ChatTypeWidget.cs:54
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:244
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:239
 msgid "Person / Private"
 msgstr "Person / Privat"
 
 #: ../src/Frontend-GNOME/ChatTypeWidget.cs:55
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:245
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:240
 msgid "Group / Public"
 msgstr "Gruppe / Öffentlich"
 
@@ -838,87 +717,118 @@ msgstr "Vielen Dank"
 #: ../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."
+msgstr "Es existiert bereits eine Engine mit diesem Namen! Bitte geben Sie einen anderen an."
+
+#: ../src/Frontend-GNOME/Views/JoinWidget.cs:87
+msgid "Enter which chat to join"
+msgstr "Geben Sie den zu betretenden Chat ein"
+
+#: ../src/Frontend-GNOME/Views/MenuWidget.cs:140
+msgid "About Smuxi"
+msgstr "Ãœber Smuxi"
+
+#. TODO: add cmd+, accelerator
+#: ../src/Frontend-GNOME/Views/MenuWidget.cs:144
+msgid "Preferences"
+msgstr "Einstellungen"
+
+#: ../src/Frontend-GNOME/Views/MenuWidget.cs:238
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:227
+msgid "Unable to add server: "
+msgstr "Fehler beim Hinzufügen des Servers:"
+
+#: ../src/Frontend-GNOME/Views/MenuWidget.cs:359
+msgid ""
+"Switching to local engine will disconnect you from the current engine!\n"
+"Are you sure you want to do this?"
+msgstr "Das Wechseln zur lokalen Engine wird Sie von der jetzigen Engine trennen!\nMöchten Sie fortfahren?"
 
-#: ../src/Frontend-GNOME/Views/MessageTextView.cs:204
+#: ../src/Frontend-GNOME/Views/MenuWidget.cs:403
+msgid ""
+"Switching the remote engine will disconnect you from the current engine!\n"
+"Are you sure you want to do this?"
+msgstr "Das Wechseln zur entfernten Engine wird Sie von der jetzigen Engine trennen!\nMöchten Sie fortfahren?"
+
+#: ../src/Frontend-GNOME/Views/MessageTextView.cs:273
 #, csharp-format
 msgid "Day changed from {0} to {1}"
 msgstr "Tag wechselte vom {0} zum {1}"
 
-#: ../src/Frontend-GNOME/Views/MessageTextView.cs:210
+#: ../src/Frontend-GNOME/Views/MessageTextView.cs:277
 #, csharp-format
 msgid "Day changed to {0}"
 msgstr "Tageswechsel: {0}"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:123
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:133
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:120
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:130
 #, csharp-format
 msgid "Invalid filter regex: '{0}'. Reason: {1}"
 msgstr "Üngültiger Filter regex: '{0}'. Ursache: {1}"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:200
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:197
 msgid "Are you sure you want to delete the selected filter?"
 msgstr "Möchten Sie den ausgewählten Filter wirklich löschen?"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:246
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:241
 msgid "Protocol / Server"
 msgstr "Protokoll / Server"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:253
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:248
 msgid "Chat Type"
 msgstr "Gesprächstyp"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:287
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:281
 msgid "Normal"
 msgstr "Normal"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:288
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:282
 msgid "Event"
 msgstr "Ereignis"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:295
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:289
 msgid "Type"
 msgstr "Typ"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:321
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:314
 msgid "Pattern"
 msgstr "Muster"
 
-#: ../src/Frontend-GNOME/Views/Chats/ChatView.cs:506
+#: ../src/Frontend-GNOME/Views/Chats/ChatView.cs:538
 msgid "Low Bandwidth Mode is active: no messages synced."
-msgstr ""
-"Geringe-Bandbreite-Modus ist aktiviert: Keine Nachrichten synchronisiert."
+msgstr "Geringe-Bandbreite-Modus ist aktiviert: Keine Nachrichten synchronisiert."
+
+#: ../src/Frontend-GNOME/Views/Chats/ChatView.cs:764
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:135
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:136
+msgid "Show _Menubar"
+msgstr "Zeige Menüleiste"
 
-#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:245
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:275
 #, 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:279
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:309
 msgid "done."
 msgstr "abgeschlossen."
 
-#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:290
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:320
 msgid "Person"
 msgstr "Person"
 
-#: ../src/Frontend-GNOME/Views/Chats/ProtocolChatView.cs:69
+#: ../src/Frontend-GNOME/Views/Chats/ProtocolChatView.cs:146
 msgid ""
 "Closing the protocol chat will also close all open chats connected to it!\n"
 "Are you sure you want to do this?"
-msgstr ""
-"Das Schließen des Protokoll-Chats wird alle dazugehörigen Chats ebenfalls schließen!\n"
-"Möchten Sie fortfahren?"
+msgstr "Das Schließen des Protokoll-Chats wird alle dazugehörigen Chats ebenfalls schließen!\nMöchten Sie fortfahren?"
 
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:187
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:189
 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:243
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:277
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:245
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:279
 msgid "Unable to edit server: "
 msgstr "Bearbeiten des Servers nicht möglich:"
 
@@ -951,13 +861,169 @@ msgid "Smuxi - Find Group Chat"
 msgstr "Smuxi - Finde Gruppen-Chat"
 
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:47
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:73
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:71
 msgid "_Name:"
 msgstr "_Name:"
 
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.JoinWidget.cs:69
+msgid "Join"
+msgstr "Betreten"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:55
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:56
+msgid "_Smuxi"
+msgstr "_Smuxi"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:58
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:59
+msgid "_Server"
+msgstr "_Server"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:61
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:62
+msgid "_Chat"
+msgstr "_Chat"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:64
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:65
+msgid "_Engine"
+msgstr "_Engine"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:67
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:68
+msgid "_View"
+msgstr "_Anzeige"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:70
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:71
+msgid "_Help"
+msgstr "_Hilfe"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:73
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:75
+msgid "Connect"
+msgstr "Verbinden"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:77
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:79
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:150
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:151
+msgid "Open Log"
+msgstr "Mitschnitt Öffnen"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:87
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:88
+msgid "_Preferences"
+msgstr "_Einstellungen"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:90
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:91
+msgid "_Quit"
+msgstr "_Beenden"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:93
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:94
+msgid "_Connect"
+msgstr "_Verbinden"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:96
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:97
+msgid "_Add"
+msgstr "_Hinzufügen"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:99
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:100
+msgid "_Manage"
+msgstr "_Verwalten"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:102
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:103
+msgid "_Open / Join Chat"
+msgstr "Chat _Öffnen / Betreten"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:105
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:106
+msgid "_Find Group Chat"
+msgstr "_Finde Gruppen-Chat"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:108
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:109
+msgid "C_lear All Activity"
+msgstr "Alle Aktivitäten _löschen"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:111
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:112
+msgid "_Next Chat"
+msgstr "_Nächster Chat"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:114
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:115
+msgid "_Previous Chat"
+msgstr "_Vorheriger Chat"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:117
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:118
+msgid "_Close"
+msgstr "_Schließen"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:120
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:121
+msgid "_Use Local Engine"
+msgstr "_Verwende lokale Engine"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:123
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:124
+msgid "_Add Remote Engine"
+msgstr "_Füge entfernte Engine hinzu"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:126
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:127
+msgid "Switch Remote Engine"
+msgstr "Entfernte Engine wechseln"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:129
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:130
+msgid "_Caret Mode"
+msgstr "_Caret-Modus"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:132
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:133
+msgid "_Browse Mode"
+msgstr "_Durchstöber-Modus"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:138
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:139
+msgid "Show _Statusbar"
+msgstr "Zeige _Statusanzeige"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:141
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:142
+msgid "Show _Join Bar"
+msgstr "Zeige _Beitrittsmenü"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:144
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:145
+msgid "_Fullscreen"
+msgstr "_Vollbild"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:147
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:148
+msgid "_About"
+msgstr "_Ãœber"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:153
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:155
+msgid "Find Group Chat"
+msgstr "Finde Gruppen-Chat"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:157
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:158
+msgid "_Website"
+msgstr "_Webseite"
+
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs:19
-msgid "Smuxi - Quick Connect"
-msgstr "Smuxi - Schnelles Verbinden"
+msgid "Smuxi - Connect"
+msgstr "Smuxi - Verbinden"
 
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:206
 msgid "Smuxi - Preferences"
@@ -992,10 +1058,7 @@ 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>"
+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:135
 msgid "SSH _Host:"
@@ -1027,9 +1090,7 @@ msgstr "_SSH-Benutzer: (optional)"
 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>"
+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:95
 msgid "_SSH Password: (optional)"
@@ -1040,9 +1101,7 @@ 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). "
+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)"
@@ -1057,9 +1116,7 @@ msgstr "Datei auswählen"
 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"
+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
@@ -1070,9 +1127,7 @@ msgstr "_Benutzer:"
 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>"
+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:224
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:87
@@ -1097,11 +1152,7 @@ msgid ""
 "You need to enter some information before you can use the engine.\n"
 "\n"
 "Click \"Forward\" to begin."
-msgstr ""
-"Willkommen beim Engine-Konfigurations-Assistenten von Smuxi.\n"
-"Sie müssen ein paar Informationen eingeben, bevor Sie diese Engine nutzen können.\n"
-"\n"
-"Klicken Sie auf \"Weiter\" um anzufangen."
+msgstr "Willkommen beim Engine-Konfigurations-Assistenten von Smuxi.\nSie müssen ein paar Informationen eingeben, bevor Sie diese Engine nutzen können.\n\nKlicken Sie auf \"Weiter\" um anzufangen."
 
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:36
 msgid "_Engine Name:"
@@ -1123,15 +1174,13 @@ msgstr "Als neue Standard-Engine verwenden"
 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>"
+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:20
 msgid "Smuxi - Open Chat"
 msgstr "Smuxi - Chat Öffnen"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:63
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:61
 msgid "_Type:"
 msgstr "_Typ:"
 
@@ -1162,5 +1211,3 @@ msgstr "Befehle beim Verbinden:"
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:265
 msgid "_Ignore Commands"
 msgstr "Befehle ignorieren:"
-
-
diff --git a/po-Frontend-GNOME/fi.po b/po-Frontend-GNOME/fi.po
new file mode 100644
index 0000000..83a47d6
--- /dev/null
+++ b/po-Frontend-GNOME/fi.po
@@ -0,0 +1,1213 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+# Kalle Kaitala <cobrian at cobrian.net>, 2013
+msgid ""
+msgstr ""
+"Project-Id-Version: Smuxi - IRC client\n"
+"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
+"POT-Creation-Date: 2013-04-14 10:19+0200\n"
+"PO-Revision-Date: 2013-05-01 14:48+0000\n"
+"Last-Translator: Kalle Kaitala <cobrian at cobrian.net>\n"
+"Language-Team: Finnish (http://www.transifex.com/projects/p/smuxi/language/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"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:1
+msgid "Smuxi Preferences"
+msgstr "Smuxi-asetukset"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:2
+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:3
+msgid "Nickname(s):"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:4
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:315
+msgid "Username:"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:5
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:338
+msgid "Realname:"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:6
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:359
+msgid "Encoding:"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:7
+msgid "<b>General</b>"
+msgstr "<b>Yleiset</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:8
+msgid "Type:"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:9
+msgid "Host:"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:10
+msgid "Password:"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:11
+msgid "Port:"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:12
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:170
+msgid "Show Password"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:13
+msgid "<b>Network Proxy</b>"
+msgstr "<b>Verkon välityspalvelin</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:14
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:381
+msgid "On Connect Commands:"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:15
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:427
+msgid "On Startup Commands:"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:16
+msgid "<b>Global Commands</b>"
+msgstr "<b>Globaalit komennot</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:17
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:471
+msgid "C_onnection"
+msgstr "Y_hteys"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:18
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:526
+msgid "Timestamp Format:"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:19
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:546
+msgid "Buffer Lines:"
+msgstr "Puskuririvit:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:20
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:569
+msgid "Engine Buffer Lines:"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:21
+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 ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:30
+msgid "Persistency Type:"
+msgstr "Pysyvyyden tyyppi:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:31
+msgid "Volatile Buffer Lines:"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:32
+msgid "Persistent Buffer Lines:"
+msgstr "Pysyvät puskuririvit:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:33
+msgid "<b>Message Buffer</b>"
+msgstr "<b>Viestipuskuri</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:34
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:628
+msgid "Strip Colors"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:35
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:667
+msgid "Strip Formattings"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:36
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:707
+msgid "Strip UTF-8"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:37
+msgid "Show Advanced Settings"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:38
+msgid "<b>Advanced</b>"
+msgstr "<b>Edistyneet</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:39
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:725
+msgid "General"
+msgstr ""
+
+#. Container child vbox6.Gtk.Box+BoxChild
+#. Container child vbox11.Gtk.Box+BoxChild
+#: ../glade/smuxi-frontend-gnome.glade.h:40
+#: ../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 ""
+
+#. Container child vbox6.Gtk.Box+BoxChild
+#. Container child vbox11.Gtk.Box+BoxChild
+#: ../glade/smuxi-frontend-gnome.glade.h:41
+#: ../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 "Pohjalla"
+
+#. Container child vbox6.Gtk.Box+BoxChild
+#. Container child vbox12.Gtk.Box+BoxChild
+#: ../glade/smuxi-frontend-gnome.glade.h:42
+#: ../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 ""
+
+#. Container child vbox6.Gtk.Box+BoxChild
+#. Container child vbox12.Gtk.Box+BoxChild
+#: ../glade/smuxi-frontend-gnome.glade.h:43
+#: ../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 ""
+
+#. Container child vbox6.Gtk.Box+BoxChild
+#. Container child vbox11.Gtk.Box+BoxChild
+#. Container child vbox12.Gtk.Box+BoxChild
+#: ../glade/smuxi-frontend-gnome.glade.h:44
+#: ../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:45
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:910
+msgid "<b> Tabs Position </b>"
+msgstr "<b> Välilehtien sijainti </b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:46
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:981
+msgid "Highlight"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:47
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:961
+msgid "Activity"
+msgstr "Aktiviteetti"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:48
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:953
+msgid "No Activity"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:49
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:971
+msgid "Join/Part/Mode"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:50
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1009
+msgid "<b> Tab Colors </b>"
+msgstr "<b> Välilehtien värit </b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:51
+msgid "Automatically switch to newly opened person chats"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:52
+msgid "Automatically switch to newly opened group chats"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:53
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1022
+msgid "Tabs"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:54
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1092
+msgid "Completion Character:"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:55
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1112
+msgid "Command Character:"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:56
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1135
+msgid "Command History Size:"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:57
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1160
+msgid "Bash-Style Completion"
+msgstr "Bash-tyylinen täyttäminen"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:58
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1172
+msgid "<b> Entry Field </b>"
+msgstr "<b> Syöttökenttä </b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:59
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1181
+msgid "Input"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:60
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1202
+msgid "Nick Colors"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:61
+msgid "<b> Person List Position </b>"
+msgstr "<b> Henkilölistan sijainti </b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:62
+msgid "Override"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:63
+msgid "<b> Font </b>"
+msgstr "<b> Fontti </b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:64
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1315
+msgid "<b> Topic Position </b>"
+msgstr "<b> Aihekentän sijainti </b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:65
+msgid "Foreground"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:66
+msgid "Background"
+msgstr "Tausta"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:67
+msgid "<b> Color </b>"
+msgstr "<b> Väri </b>"
+
+#. This is a setting for character based line wrapping vs word based when
+#. showing messages
+#: ../glade/smuxi-frontend-gnome.glade.h:69
+msgid "_Wrap Mode:"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:70
+msgid "<b> Chat </b>"
+msgstr "<b> Chat </b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:71
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1466
+msgid "Highlight words:"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:72
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1490
+msgid "Beep on highlight"
+msgstr "Piippaus korostuksen yhteydessä"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:73
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1502
+msgid "<b> Highlighting </b>"
+msgstr "<b> Korostaminen </b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:74
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1514
+msgid "Output"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:75
+msgid "Enable"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:76
+msgid "Show always"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:77
+msgid "Show when window is minimized"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:78
+msgid "Show when window is closed"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:79
+msgid "<b> Notification Area Icon </b>"
+msgstr "<b> Huomioalueen ikoni </b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:80
+msgid "Show Smuxi in the messaging menu"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:81
+msgid "<b>Messaging Menu</b>"
+msgstr "<b>Viestivalikko</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:82
+msgid "Show notification popups"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:83
+msgid "<b>Notification Popups</b>"
+msgstr "<b>Ilmoitusten ponnahdusikkunat</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:84
+msgid "Notification"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:85
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1523
+msgid "_Interface"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:86
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1589
+msgid "_Servers"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:87
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1681
+msgid "_Filters"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:88
+msgid "Enabled"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:89
+msgid "Log Filtered Messages"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:90
+msgid "_Logging"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:91
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerDialog.cs:16
+msgid "Smuxi - Server"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:92
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:209
+msgid "Automatically connect to server at startup"
+msgstr "Yhdistä palvelimeen automaattisesti käynnistyksen yhteydessä"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:93
+msgid "Protocol:"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:94
+msgid "Network:"
+msgstr ""
+
+#: ../glade/smuxi-frontend-gnome.glade.h:95
+msgid "Hostname:"
+msgstr ""
+
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:1
+msgid "Smuxi"
+msgstr ""
+
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:2
+msgid "IRC Chat"
+msgstr ""
+
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:3
+msgid "Smuxi IRC Client"
+msgstr ""
+
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:4
+msgid "Chat with other people on IRC"
+msgstr ""
+
+#: ../src/Frontend-GNOME/AboutDialog.cs:65
+msgid "translator-credits"
+msgstr ""
+
+#: ../src/Frontend-GNOME/AboutDialog.cs:72
+msgid "Smuxi Website"
+msgstr ""
+
+#: ../src/Frontend-GNOME/CrashDialog.cs:46
+msgid "Oops, I did it again..."
+msgstr ""
+
+#: ../src/Frontend-GNOME/CrashDialog.cs:59
+msgid "Smuxi crashed because an unhandled exception was thrown!"
+msgstr ""
+
+#: ../src/Frontend-GNOME/CrashDialog.cs:63
+msgid "Here is the stacktrace, please report this bug!"
+msgstr ""
+
+#: ../src/Frontend-GNOME/CrashDialog.cs:83
+msgid "_Report Bug"
+msgstr ""
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:66
+msgid "Engine not found."
+msgstr ""
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:81
+msgid "Engine Manager"
+msgstr ""
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:100
+msgid "Select which Smuxi engine you want to connect to"
+msgstr ""
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:106
+msgid "Engine:"
+msgstr ""
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:117
+msgid "Use Low Bandwidth Mode"
+msgstr ""
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:141
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:201
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:383
+msgid "Local Engine"
+msgstr ""
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:193
+msgid "Please select an engine!"
+msgstr ""
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:219
+#, csharp-format
+msgid "Your frontend version ({0}) does not match the engine version ({1})!"
+msgstr ""
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:246
+msgid "An error occurred while connecting to the engine!"
+msgstr ""
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:247
+#, csharp-format
+msgid "Engine URL: {0}"
+msgstr ""
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:250
+#, csharp-format
+msgid "Error: {0}"
+msgstr ""
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:320
+#, csharp-format
+msgid "Are you sure you want to delete the engine \"{0}\"?"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Entry.cs:474
+#, csharp-format
+msgid "You are going to paste {0} lines. Do you want to continue?"
+msgstr ""
+
+#. TRANSLATOR: this line is used as a label / category for a
+#. list of commands below
+#: ../src/Frontend-GNOME/Entry.cs:587
+msgid "Frontend Commands"
+msgstr ""
+
+#: ../src/Frontend-GNOME/NotImplementedMessageDialog.cs:40
+msgid "Sorry, not implemented yet!"
+msgstr ""
+
+#. fill ListStore
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:185
+msgid "Character"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:186
+msgid "Word"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:203
+msgid "Volatile"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:205
+msgid "Persistent"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:228
+msgid "No Proxy"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:230
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:318
+msgid "System Default"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:244
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:140
+msgid "Connection"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:248
+msgid "Interface"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:252
+msgid "Servers"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:259
+msgid "Filters"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:263
+msgid "Logging"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:666
+msgid "Nicknames(s) field must not be empty."
+msgstr ""
+
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:857
+#, csharp-format
+msgid "Invalid highlight regex: '{0}'. Reason: {1}"
+msgstr ""
+
+#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:81
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:106
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:265
+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 ""
+
+#: ../src/Frontend-GNOME/FindGroupChatDialog.cs:156
+msgid "Error while fetching the list of group chats from the server."
+msgstr ""
+
+#: ../src/Frontend-GNOME/Frontend.cs:400
+msgid "Disconnected from engine."
+msgstr ""
+
+#: ../src/Frontend-GNOME/Frontend.cs:442
+#, csharp-format
+msgid "Reconnecting to engine... (attempt {0})"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Frontend.cs:540
+#, csharp-format
+msgid "Cause: {0}"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Frontend.cs:666
+msgid ""
+"The frontend has lost the connection to the server.\n"
+"Do you want to reconnect now?"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Frontend.cs:685
+msgid ""
+"Reconnecting to the server has failed.\n"
+"Do you want to try again?"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Frontend.cs:974
+msgid ""
+"The server has lost the connection to the frontend.\n"
+"Do you want to reconnect now?"
+msgstr ""
+
+#: ../src/Frontend-GNOME/NotifyManager.cs:336
+msgid "Show"
+msgstr ""
+
+#: ../src/Frontend-GNOME/QuickConnectDialog.cs:58
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:233
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:70
+msgid "Protocol"
+msgstr ""
+
+#: ../src/Frontend-GNOME/QuickConnectDialog.cs:59
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:71
+msgid "Hostname"
+msgstr ""
+
+#: ../src/Frontend-GNOME/QuickConnectDialog.cs:162
+msgid "Unable to load server: "
+msgstr ""
+
+#: ../src/Frontend-GNOME/ChatTypeWidget.cs:54
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:239
+msgid "Person / Private"
+msgstr ""
+
+#: ../src/Frontend-GNOME/ChatTypeWidget.cs:55
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:240
+msgid "Group / Public"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:71
+msgid "Engine Assistant - Smuxi"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:93
+msgid "Add Smuxi Engine"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:95
+msgid "Edit Smuxi Engine"
+msgstr ""
+
+#: ../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 ""
+
+#: ../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/JoinWidget.cs:87
+msgid "Enter which chat to join"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Views/MenuWidget.cs:140
+msgid "About Smuxi"
+msgstr ""
+
+#. TODO: add cmd+, accelerator
+#: ../src/Frontend-GNOME/Views/MenuWidget.cs:144
+msgid "Preferences"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Views/MenuWidget.cs:238
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:227
+msgid "Unable to add server: "
+msgstr ""
+
+#: ../src/Frontend-GNOME/Views/MenuWidget.cs:359
+msgid ""
+"Switching to local engine will disconnect you from the current engine!\n"
+"Are you sure you want to do this?"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Views/MenuWidget.cs:403
+msgid ""
+"Switching the remote engine will disconnect you from the current engine!\n"
+"Are you sure you want to do this?"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Views/MessageTextView.cs:273
+#, csharp-format
+msgid "Day changed from {0} to {1}"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Views/MessageTextView.cs:277
+#, csharp-format
+msgid "Day changed to {0}"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:120
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:130
+#, csharp-format
+msgid "Invalid filter regex: '{0}'. Reason: {1}"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:197
+msgid "Are you sure you want to delete the selected filter?"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:241
+msgid "Protocol / Server"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:248
+msgid "Chat Type"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:281
+msgid "Normal"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:282
+msgid "Event"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:289
+msgid "Type"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:314
+msgid "Pattern"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Views/Chats/ChatView.cs:538
+msgid "Low Bandwidth Mode is active: no messages synced."
+msgstr ""
+
+#: ../src/Frontend-GNOME/Views/Chats/ChatView.cs:764
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:135
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:136
+msgid "Show _Menubar"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:275
+#, csharp-format
+msgid "Retrieving user list for {0}..."
+msgstr ""
+
+#. TRANSLATOR: this string will be appended to the one above
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:309
+msgid "done."
+msgstr ""
+
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:320
+msgid "Person"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Views/Chats/ProtocolChatView.cs:146
+msgid ""
+"Closing the protocol chat will also close all open chats connected to it!\n"
+"Are you sure you want to do this?"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:189
+msgid "Are you sure you want to delete the selected server?"
+msgstr ""
+
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:245
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:279
+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 ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:73
+msgid "_Match Case"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:85
+msgid "Search _Backwards"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:97
+msgid "_Wrap Around"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ChatFindDialog.cs:110
+msgid "Use _Regular Expressions"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:23
+msgid "Smuxi - Find Group Chat"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:47
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:71
+msgid "_Name:"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.JoinWidget.cs:69
+msgid "Join"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:55
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:56
+msgid "_Smuxi"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:58
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:59
+msgid "_Server"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:61
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:62
+msgid "_Chat"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:64
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:65
+msgid "_Engine"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:67
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:68
+msgid "_View"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:70
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:71
+msgid "_Help"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:73
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:75
+msgid "Connect"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:77
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:79
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:150
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:151
+msgid "Open Log"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:87
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:88
+msgid "_Preferences"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:90
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:91
+msgid "_Quit"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:93
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:94
+msgid "_Connect"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:96
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:97
+msgid "_Add"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:99
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:100
+msgid "_Manage"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:102
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:103
+msgid "_Open / Join Chat"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:105
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:106
+msgid "_Find Group Chat"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:108
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:109
+msgid "C_lear All Activity"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:111
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:112
+msgid "_Next Chat"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:114
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:115
+msgid "_Previous Chat"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:117
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:118
+msgid "_Close"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:120
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:121
+msgid "_Use Local Engine"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:123
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:124
+msgid "_Add Remote Engine"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:126
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:127
+msgid "Switch Remote Engine"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:129
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:130
+msgid "_Caret Mode"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:132
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:133
+msgid "_Browse Mode"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:138
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:139
+msgid "Show _Statusbar"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:141
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:142
+msgid "Show _Join Bar"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:144
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:145
+msgid "_Fullscreen"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:147
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:148
+msgid "_About"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:153
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:155
+msgid "Find Group Chat"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:157
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:158
+msgid "_Website"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs:19
+msgid "Smuxi - Connect"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:206
+msgid "Smuxi - Preferences"
+msgstr ""
+
+#: ../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 ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1441
+msgid "<b> Channel </b>"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1652
+msgid "<b>Channel Filters</b>"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1669
+msgid "<b>User Filters</b>"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:42
+msgid "Use _SSH Tunnel"
+msgstr ""
+
+#: ../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 ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:135
+msgid "SSH _Host:"
+msgstr ""
+
+#: ../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 ""
+
+#: ../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 ""
+
+#: ../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 ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:199
+msgid "_Smuxi Host:"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:52
+msgid "_SSH Username: (optional)"
+msgstr ""
+
+#: ../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 ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:95
+msgid "_SSH Password: (optional)"
+msgstr ""
+
+#: ../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 ""
+
+#: ../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 ""
+
+#: ../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 ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:248
+msgid "<span size=\"small\">Password of the user</span>"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:268
+msgid "_Verify Password:"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantCredentialsWidget.cs:292
+msgid "<span size=\"small\">Repeat the password for verification</span>"
+msgstr ""
+
+#: ../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 ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:36
+msgid "_Engine Name:"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:59
+msgid "<span size=\"small\">Profile name of the new engine</span>"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:80
+msgid "_Default Engine:"
+msgstr ""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:91
+msgid "Use as new default engine"
+msgstr "Käytä uutena oletusmoottorina"
+
+#: ../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\">Jos valittu, nykyinen moottori on oletuksena käytössä seuraavalla Smuxin käynnistyskerralla</span>"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:20
+msgid "Smuxi - Open Chat"
+msgstr "Smuxi - Avaa keskustelu"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:61
+msgid "_Type:"
+msgstr "_Tyyppi:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:54
+msgid "_Hostname:"
+msgstr "_Isäntänimi:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:75
+msgid "_Network:"
+msgstr "_Verkko:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:198
+msgid "_Protocol:"
+msgstr "_Protokolla:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:222
+msgid "Use Encryption"
+msgstr "Käytä salausta"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:234
+msgid "Validate Server Certificate"
+msgstr "Vahvista palvelimen sertifikaatti"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:254
+msgid "_On Connect Commands:"
+msgstr "_Yhdistyksenaikaiset komennot:"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:265
+msgid "_Ignore Commands"
+msgstr "_Jätä komennot suorittamatta"
diff --git a/po-Frontend-GNOME/fr.po b/po-Frontend-GNOME/fr.po
index 80bfcb1..ea4038f 100644
--- a/po-Frontend-GNOME/fr.po
+++ b/po-Frontend-GNOME/fr.po
@@ -1,213 +1,209 @@
 # 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 - 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"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-04-10 21:42+0200\n"
+"PO-Revision-Date: 2013-04-10 22:38+0100\n"
 "Last-Translator: Clément Bourgeois <moonpyk at gmail.com>\n"
 "Language-Team: French (http://www.transifex.net/projects/p/smuxi/team/fr/)\n"
+"Language: 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"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:1
-msgid "<b> Chat </b>"
-msgstr "<b> Discussion </b>"
+msgid "Smuxi Preferences"
+msgstr "Préférences de Smuxi"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:2
-msgid "<b> Color </b>"
-msgstr "<b> Couleur </b>"
+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:3
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1172
-msgid "<b> Entry Field </b>"
-msgstr "<b> Champ d'entrée </b>"
+msgid "Nickname(s):"
+msgstr "Surnom(s) :"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:4
-msgid "<b> Font </b>"
-msgstr "<b> Police </b>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:315
+msgid "Username:"
+msgstr "Nom d'utilisateur :"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:5
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1502
-msgid "<b> Highlighting </b>"
-msgstr "<b> Surlignement </b>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:338
+msgid "Realname:"
+msgstr "Nom réel :"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:6
-msgid "<b> Notification Area Icon </b>"
-msgstr "<b> Icône de l'aire de notification </b>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:359
+msgid "Encoding:"
+msgstr "Encodage :"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:7
-msgid "<b> Person List Position </b>"
-msgstr "<b> Position de la liste des utilisateurs </b>"
+msgid "<b>General</b>"
+msgstr "<b>Général</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> Couleur des onglets </b>"
+msgid "Type:"
+msgstr "Type :"
 
 #: ../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> Position des onglets </b>"
+msgid "Host:"
+msgstr "Nom d'hôte :"
 
 #: ../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> Position du sujet </b>"
+msgid "Password:"
+msgstr "Mot de passe :"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:11
-msgid "<b>Advanced</b>"
-msgstr "<b>Avancé</b>"
+msgid "Port:"
+msgstr "Port :"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:12
-msgid "<b>General</b>"
-msgstr "<b>Général</b>"
+#: ../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:13
-msgid "<b>Global Commands</b>"
-msgstr "<b>Commandes globales</b>"
+msgid "<b>Network Proxy</b>"
+msgstr "<b>Proxy réseau</b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:14
-msgid "<b>Message Buffer</b>"
-msgstr "<b>Tampon de messages</b>"
+#: ../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:15
-msgid "<b>Messaging Menu</b>"
-msgstr "<b>Menu de messagerie</b>"
+#: ../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:16
-msgid "<b>Network Proxy</b>"
-msgstr "<b>Proxy réseau</b>"
+msgid "<b>Global Commands</b>"
+msgstr "<b>Commandes globales</b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:17
-msgid "<b>Notification Popups</b>"
-msgstr "<b>Popups de notification</b>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:471
+msgid "C_onnection"
+msgstr "C_onnexion"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:18
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:961
-msgid "Activity"
-msgstr "Activité"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:526
+msgid "Timestamp Format:"
+msgstr "Format temporel :"
 
 #: ../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:20
-msgid "Background"
-msgstr "Arrière plan"
-
-#: ../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: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: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: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:25
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:471
-msgid "C_onnection"
-msgstr "C_onnexion"
-
-#: ../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: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: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:20
+#: ../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:29
-msgid "Enable"
-msgstr "Activer"
+#: ../glade/smuxi-frontend-gnome.glade.h:21
+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 = secondes\n"
+"mm = minutes\n"
+"hh = heures (format 01 - 12)\n"
+"HH = heures (format 00 - 23)\n"
+"tt = AM/PM\n"
+"\n"
+"dd = jour\n"
+"MM = mois\n"
+"yy/yyyy = année"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:30
-msgid "Enabled"
-msgstr "Activé"
+msgid "Persistency Type:"
+msgstr "Type de persistance :"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:31
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:359
-msgid "Encoding:"
-msgstr "Encodage :"
+msgid "Volatile Buffer Lines:"
+msgstr "Lignes de tampon volatiles"
 
 #: ../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"
+msgid "Persistent Buffer Lines:"
+msgstr "Lignes de tampon sauvegardées :"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:33
-msgid "Foreground"
-msgstr "Texte"
+msgid "<b>Message Buffer</b>"
+msgstr "<b>Tampon de messages</b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:34
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:725
-msgid "General"
-msgstr "Général"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:628
+msgid "Strip Colors"
+msgstr "Ignorer les couleurs"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:35
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:981
-msgid "Highlight"
-msgstr "Surligner"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:667
+msgid "Strip Formattings"
+msgstr "Ignorer le formatage"
 
 #: ../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 :"
+#: ../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:37
-msgid "Host:"
-msgstr "Nom d'hôte :"
+msgid "Show Advanced Settings"
+msgstr "Afficher les reglages avancés"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:38
-msgid "Hostname:"
-msgstr "Nom d'hôte"
+msgid "<b>Advanced</b>"
+msgstr "<b>Avancé</b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:39
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1181
-msgid "Input"
-msgstr "Entrée"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:725
+msgid "General"
+msgstr "Général"
 
+#. Container child vbox6.Gtk.Box+BoxChild
+#. Container child vbox11.Gtk.Box+BoxChild
 #: ../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"
+#: ../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"
 
 #. Container child vbox6.Gtk.Box+BoxChild
-#. Container child vbox12.Gtk.Box+BoxChild
+#. Container child vbox11.Gtk.Box+BoxChild
 #: ../glade/smuxi-frontend-gnome.glade.h:41
+#: ../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"
+
+#. Container child vbox6.Gtk.Box+BoxChild
+#. Container child vbox12.Gtk.Box+BoxChild
+#: ../glade/smuxi-frontend-gnome.glade.h:42
 #: ../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
@@ -215,261 +211,272 @@ msgstr "Join/Part/Mode"
 msgid "Left"
 msgstr "Gauche"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:42
-msgid "Log Filtered Messages"
-msgstr "Journaliser les messages filtrés"
-
+#. Container child vbox6.Gtk.Box+BoxChild
+#. Container child vbox12.Gtk.Box+BoxChild
 #: ../glade/smuxi-frontend-gnome.glade.h:43
-msgid "Network:"
-msgstr "Réseau :"
-
-#: ../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:45
-msgid "Nickname(s):"
-msgstr "Surnom(s) :"
-
-#: ../glade/smuxi-frontend-gnome.glade.h:46
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:953
-msgid "No Activity"
-msgstr "Aucune activité"
+#: ../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"
 
 #. 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
+#: ../glade/smuxi-frontend-gnome.glade.h:44
 #: ../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:45
+#: ../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:46
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:981
+msgid "Highlight"
+msgstr "Surligner"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:47
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:961
+msgid "Activity"
+msgstr "Activité"
+
 #: ../glade/smuxi-frontend-gnome.glade.h:48
-msgid "Notification"
-msgstr "Notification"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:953
+msgid "No Activity"
+msgstr "Aucune activité"
 
 #: ../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 :"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:971
+msgid "Join/Part/Mode"
+msgstr "Join/Part/Mode"
 
 #: ../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 :"
+#: ../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:51
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1514
-msgid "Output"
-msgstr "Sortie"
+msgid "Automatically switch to newly opened person chats"
+msgstr "Ouvrir automatiquement les nouveaux chats de personne"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:52
-msgid "Override"
-msgstr "Ignorer"
+msgid "Automatically switch to newly opened group chats"
+msgstr "Ouvrir automatiquement les nouveaux chats de groupe"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:53
-msgid "Password:"
-msgstr "Mot de passe :"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1022
+msgid "Tabs"
+msgstr "Onglets"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:54
-msgid "Persistency Type:"
-msgstr "Type de persistance :"
+#: ../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:55
-msgid "Persistent Buffer Lines:"
-msgstr "Lignes de tampon sauvegardées :"
+#: ../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:56
-msgid "Port:"
-msgstr "Port :"
+#: ../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:57
-msgid "Protocol:"
-msgstr "Protocole :"
+#: ../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:58
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:338
-msgid "Realname:"
-msgstr "Nom réel :"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1172
+msgid "<b> Entry Field </b>"
+msgstr "<b> Champ d'entrée </b>"
 
-#. 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 "Droite"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1181
+msgid "Input"
+msgstr "Entrée"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:60
-msgid "Show Advanced Settings"
-msgstr "Afficher les reglages avancés"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1202
+msgid "Nick Colors"
+msgstr "Couleur du surnom"
 
 #: ../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"
+msgid "<b> Person List Position </b>"
+msgstr "<b> Position de la liste des utilisateurs </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:62
-msgid "Show Smuxi in the messaging menu"
-msgstr "Afficher Smuxi dans le menu messagerie"
+msgid "Override"
+msgstr "Ignorer"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:63
-msgid "Show always"
-msgstr "Toujours montrer"
+msgid "<b> Font </b>"
+msgstr "<b> Police </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:64
-msgid "Show notification popups"
-msgstr "Afficher les popups de notification"
+#: ../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:65
-msgid "Show when window is closed"
-msgstr "Montrer quand la fenêtre est fermée"
+msgid "Foreground"
+msgstr "Texte"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:66
-msgid "Show when window is minimized"
-msgstr "Montrer quand la fenêtre est minimisée"
+msgid "Background"
+msgstr "Arrière plan"
 
 #: ../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:68
-msgid "Smuxi Preferences"
-msgstr "Préférences de Smuxi"
+msgid "<b> Color </b>"
+msgstr "<b> Couleur </b>"
 
+#. This is a setting for character based line wrapping vs word based when showing messages
 #: ../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"
+msgid "_Wrap Mode:"
+msgstr "Mode _circulaire :"
 
 #: ../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"
+msgid "<b> Chat </b>"
+msgstr "<b> Discussion </b>"
 
 #: ../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"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1466
+msgid "Highlight words:"
+msgstr "Mots surlignés :"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:72
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1022
-msgid "Tabs"
-msgstr "Onglets"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1490
+msgid "Beep on highlight"
+msgstr "Émettre un son en cas de surlignage"
 
 #: ../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."
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1502
+msgid "<b> Highlighting </b>"
+msgstr "<b> Surlignement </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:74
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:526
-msgid "Timestamp Format:"
-msgstr "Format temporel :"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1514
+msgid "Output"
+msgstr "Sortie"
 
-#. 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 "Haut"
+msgid "Enable"
+msgstr "Activer"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:76
-msgid "Type:"
-msgstr "Type :"
+msgid "Show always"
+msgstr "Toujours montrer"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:77
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:315
-msgid "Username:"
-msgstr "Nom d'utilisateur :"
+msgid "Show when window is minimized"
+msgstr "Montrer quand la fenêtre est minimisée"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:78
-msgid "Volatile Buffer Lines:"
-msgstr "Lignes de tampon volatiles"
+msgid "Show when window is closed"
+msgstr "Montrer quand la fenêtre est fermée"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:79
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1681
-msgid "_Filters"
-msgstr "_Filtres"
+msgid "<b> Notification Area Icon </b>"
+msgstr "<b> Icône de l'aire de notification </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:80
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1523
-msgid "_Interface"
-msgstr "_Interface"
+msgid "Show Smuxi in the messaging menu"
+msgstr "Afficher Smuxi dans le menu messagerie"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:81
-msgid "_Logging"
-msgstr "_Journalisation"
+msgid "<b>Messaging Menu</b>"
+msgstr "<b>Menu de messagerie</b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:82
+msgid "Show notification popups"
+msgstr "Afficher les popups de notification"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:83
+msgid "<b>Notification Popups</b>"
+msgstr "<b>Popups de notification</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:84
+msgid "Notification"
+msgstr "Notification"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:85
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1523
+msgid "_Interface"
+msgstr "_Interface"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:86
 #: ../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:84
-msgid "_Wrap Mode:"
-msgstr "Mode _circulaire :"
+#: ../glade/smuxi-frontend-gnome.glade.h:87
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1681
+msgid "_Filters"
+msgstr "_Filtres"
 
-#: ../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 = secondes\n"
-"mm = minutes\n"
-"hh = heures (format 01 - 12)\n"
-"HH = heures (format 00 - 23)\n"
-"tt = AM/PM\n"
-"\n"
-"dd = jour\n"
-"MM = mois\n"
-"yy/yyyy = année"
+#: ../glade/smuxi-frontend-gnome.glade.h:88
+msgid "Enabled"
+msgstr "Activé"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:89
+msgid "Log Filtered Messages"
+msgstr "Journaliser les messages filtrés"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:90
+msgid "_Logging"
+msgstr "_Journalisation"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:91
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerDialog.cs:16
+msgid "Smuxi - Server"
+msgstr "Smuxi - Serveur"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:92
+#: ../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:93
+msgid "Protocol:"
+msgstr "Protocole :"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:94
+msgid "Network:"
+msgstr "Réseau :"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:95
+msgid "Hostname:"
+msgstr "Nom d'hôte"
 
 #: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:1
-msgid "Chat with other people on IRC"
-msgstr "Chatter sur IRC avec d'autres gens"
+msgid "Smuxi"
+msgstr "Smuxi"
 
 #: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:2
 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:60
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:4
+msgid "Chat with other people on IRC"
+msgstr "Chatter sur IRC avec d'autres gens"
+
+#: ../src/Frontend-GNOME/AboutDialog.cs:65
 msgid "translator-credits"
 msgstr "Clément Bourgeois <moonpyk at gmail.com>"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:65
+#: ../src/Frontend-GNOME/AboutDialog.cs:72
 msgid "Smuxi Website"
 msgstr "Site web de Smuxi"
 
@@ -489,241 +496,138 @@ msgstr "Voici la pile d'appels, envoyez le rapport de bug s'il-vous-plaît ! "
 msgid "_Report Bug"
 msgstr "_Rapporter un bogue"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:61
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:66
+msgid "Engine not found."
+msgstr "Moteur non trouvé."
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:81
 msgid "Engine Manager"
 msgstr "Gestionnaire de moteurs"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:80
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:100
 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:86
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:106
 msgid "Engine:"
 msgstr "Moteur :"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:97
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:117
 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
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:141
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:201
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:383
 msgid "Local Engine"
 msgstr "Moteur local"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:173
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:193
 msgid "Please select an engine!"
 msgstr "Sélectionnez un moteur s'il vous plaît !"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:194
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:219
 #, 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}) !"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:221
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:246
 msgid "An error occurred while connecting to the engine!"
 msgstr "Une erreur est survenue durant la connexion au moteur !"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:222
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:247
 #, csharp-format
 msgid "Engine URL: {0}"
 msgstr "URL du moteur : {0}"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:225
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:250
 #, csharp-format
 msgid "Error: {0}"
 msgstr "Erreur : {0}"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:295
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:320
 #, 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:443
+#: ../src/Frontend-GNOME/Entry.cs:474
 #, 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 ?"
+"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:547
+#: ../src/Frontend-GNOME/Entry.cs:587
 msgid "Frontend Commands"
 msgstr "Commandes Frontend"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:252
-msgid "_File"
-msgstr "_Fichier"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:276
-msgid "_Server"
-msgstr "_Serveur"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:280
-msgid "_Quick Connect"
-msgstr "_Connexion rapide"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:291
-msgid "_Manage"
-msgstr "_Gestion"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:298
-msgid "_Chat"
-msgstr "_Discussion"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:302
-msgid "Open / Join Chat"
-msgstr "Ouvrir / Rejoindre chat"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:308
-msgid "_Find Group Chat"
-msgstr "_Rechercher le groupe de discussion"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:314
-msgid "C_lear All Activity"
-msgstr "_Supprimer toute activité"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:321
-msgid "_Next Chat"
-msgstr "Discussion _suivante"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:335
-msgid "_Previous Chat"
-msgstr "Discussion _précédente"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:389
-msgid "Open Log"
-msgstr "Ouvrir le journal"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:407
-msgid "_Engine"
-msgstr "_Moteur"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:411
-msgid "_Use Local Engine"
-msgstr "_Utiliser le moteur local"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:417
-msgid "_Add Remote Engine"
-msgstr "_Ajouter un moteur distant"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:422
-msgid "_Switch Remote Engine"
-msgstr "_Changer de moteur distant"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:429
-msgid "_View"
-msgstr "_Vue"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:433
-msgid "_Caret Mode"
-msgstr "Mode _curseur"
-
-#: ../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:768
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:225
-msgid "Unable to add server: "
-msgstr "Impossible d'ajouter le serveur :"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:828
-#, csharp-format
-msgid "Unknown ChatType: {0}"
-msgstr "ChatType inconnu : {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 ""
-"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:1139
-msgid ""
-"Switching the remote engine will disconnect you from the current engine!\n"
-"Are you sure you want to do this?"
-msgstr ""
-"Changer de moteur pour un moteur distant va vous déconnecter du moteur actuel !\n"
-"Êtes vous sûr(e) de vouloir continuer ?"
-
 #: ../src/Frontend-GNOME/NotImplementedMessageDialog.cs:40
 msgid "Sorry, not implemented yet!"
 msgstr "Désolé, fonctionnalité pas encore implémentée !"
 
 #. fill ListStore
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:179
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:185
 msgid "Character"
 msgstr "Caractère"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:180
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:186
 msgid "Word"
 msgstr "Mot"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:197
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:203
 msgid "Volatile"
 msgstr "Volatile"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:199
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:205
 msgid "Persistent"
 msgstr "Persistant"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:222
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:228
 msgid "No Proxy"
 msgstr "Pas de proxy"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:224
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:307
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:230
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:318
 msgid "System Default"
 msgstr "Défaut du système"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:238
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:244
 #: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:140
 msgid "Connection"
 msgstr "Connexion"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:242
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:248
 msgid "Interface"
 msgstr "Interface"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:246
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:252
 msgid "Servers"
 msgstr "Serveurs"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:253
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:259
 msgid "Filters"
 msgstr "Filtres"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:257
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:263
 msgid "Logging"
 msgstr "Journalisation"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:642
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:666
 msgid "Nicknames(s) field must not be empty."
 msgstr "Le champ surnom(s) ne doit pas être vide."
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:823
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:857
 #, 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:81
 #: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:106
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:271
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:265
 msgid "Name"
 msgstr "Nom"
 
@@ -733,7 +637,8 @@ msgstr "Sujet"
 
 #: ../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 "Chercher des groupes de discussion"
 
@@ -743,21 +648,21 @@ msgstr ""
 "Erreur durant la récupération de la liste des groupes de discussion du "
 "serveur."
 
-#: ../src/Frontend-GNOME/Frontend.cs:325
+#: ../src/Frontend-GNOME/Frontend.cs:400
 msgid "Disconnected from engine."
 msgstr "Déconnecté du moteur."
 
-#: ../src/Frontend-GNOME/Frontend.cs:368
+#: ../src/Frontend-GNOME/Frontend.cs:442
 #, csharp-format
 msgid "Reconnecting to engine... (attempt {0})"
 msgstr "Reconnexion au moteur... (essai {0})"
 
-#: ../src/Frontend-GNOME/Frontend.cs:465
+#: ../src/Frontend-GNOME/Frontend.cs:540
 #, csharp-format
 msgid "Cause: {0}"
 msgstr "Cause : {0}"
 
-#: ../src/Frontend-GNOME/Frontend.cs:583
+#: ../src/Frontend-GNOME/Frontend.cs:666
 msgid ""
 "The frontend has lost the connection to the server.\n"
 "Do you want to reconnect now?"
@@ -765,7 +670,7 @@ msgstr ""
 "Le serveur a perdu la connexion a l'interface.\n"
 "Voulez-vous vous reconnecter maintenant ?"
 
-#: ../src/Frontend-GNOME/Frontend.cs:602
+#: ../src/Frontend-GNOME/Frontend.cs:685
 msgid ""
 "Reconnecting to the server has failed.\n"
 "Do you want to try again?"
@@ -773,7 +678,7 @@ msgstr ""
 "La reconnexion au serveur a échoué.\n"
 "Voulez-vous vous reconnecter maintenant ?"
 
-#: ../src/Frontend-GNOME/Frontend.cs:705
+#: ../src/Frontend-GNOME/Frontend.cs:974
 msgid ""
 "The server has lost the connection to the frontend.\n"
 "Do you want to reconnect now?"
@@ -781,32 +686,32 @@ msgstr ""
 "Le serveur a perdu la connexion à l'interface.\n"
 "Voulez-vous vous reconnecter maintenant ?"
 
-#: ../src/Frontend-GNOME/NotifyManager.cs:267
+#: ../src/Frontend-GNOME/NotifyManager.cs:336
 msgid "Show"
 msgstr "Afficher"
 
-#: ../src/Frontend-GNOME/QuickConnectDialog.cs:62
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:238
+#: ../src/Frontend-GNOME/QuickConnectDialog.cs:58
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:233
 #: ../src/Frontend-GNOME/Preferences/ServerListView.cs:70
 msgid "Protocol"
 msgstr "Protocole"
 
-#: ../src/Frontend-GNOME/QuickConnectDialog.cs:63
+#: ../src/Frontend-GNOME/QuickConnectDialog.cs:59
 #: ../src/Frontend-GNOME/Preferences/ServerListView.cs:71
 msgid "Hostname"
 msgstr "Nom d'hôte"
 
-#: ../src/Frontend-GNOME/QuickConnectDialog.cs:166
+#: ../src/Frontend-GNOME/QuickConnectDialog.cs:162
 msgid "Unable to load server: "
 msgstr "Impossible de charger le serveur :"
 
 #: ../src/Frontend-GNOME/ChatTypeWidget.cs:54
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:244
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:239
 msgid "Person / Private"
 msgstr "Personne / Privé"
 
 #: ../src/Frontend-GNOME/ChatTypeWidget.cs:55
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:245
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:240
 msgid "Group / Public"
 msgstr "Groupe / Public"
 
@@ -839,82 +744,125 @@ 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:204
+#: ../src/Frontend-GNOME/Views/JoinWidget.cs:87
+msgid "Enter which chat to join"
+msgstr "Entrez le nom du chat à rejoindre"
+
+#: ../src/Frontend-GNOME/Views/MenuWidget.cs:140
+msgid "About Smuxi"
+msgstr "À propos de Smuxi"
+
+#. TODO: add cmd+, accelerator
+#: ../src/Frontend-GNOME/Views/MenuWidget.cs:144
+msgid "Preferences"
+msgstr "Préférences"
+
+#: ../src/Frontend-GNOME/Views/MenuWidget.cs:238
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:227
+msgid "Unable to add server: "
+msgstr "Impossible d'ajouter le serveur :"
+
+#: ../src/Frontend-GNOME/Views/MenuWidget.cs:359
+msgid ""
+"Switching to local engine will disconnect you from the current engine!\n"
+"Are you sure you want to do this?"
+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/Views/MenuWidget.cs:403
+msgid ""
+"Switching the remote engine will disconnect you from the current engine!\n"
+"Are you sure you want to do this?"
+msgstr ""
+"Changer de moteur pour un moteur distant va vous déconnecter du moteur "
+"actuel !\n"
+"Êtes vous sûr(e) de vouloir continuer ?"
+
+#: ../src/Frontend-GNOME/Views/MessageTextView.cs:273
 #, csharp-format
 msgid "Day changed from {0} to {1}"
 msgstr "Jour changé de {0} à {1}"
 
-#: ../src/Frontend-GNOME/Views/MessageTextView.cs:210
+#: ../src/Frontend-GNOME/Views/MessageTextView.cs:277
 #, csharp-format
 msgid "Day changed to {0}"
 msgstr "Jour changé à {0}"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:123
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:133
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:120
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:130
 #, csharp-format
 msgid "Invalid filter regex: '{0}'. Reason: {1}"
 msgstr "Expression régulière de filtrage invalide '{0}'. Raison : {1} "
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:200
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:197
 msgid "Are you sure you want to delete the selected filter?"
 msgstr "Êtes vous sûr(e) de vouloir supprimer le filtre sélectionné ?"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:246
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:241
 msgid "Protocol / Server"
 msgstr "Protocole / Serveur"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:253
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:248
 msgid "Chat Type"
 msgstr "Type de chat"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:287
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:281
 msgid "Normal"
 msgstr "Normal"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:288
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:282
 msgid "Event"
 msgstr "Evenement"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:295
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:289
 msgid "Type"
 msgstr "Type :"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:321
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:314
 msgid "Pattern"
 msgstr "Motif"
 
-#: ../src/Frontend-GNOME/Views/Chats/ChatView.cs:506
+#: ../src/Frontend-GNOME/Views/Chats/ChatView.cs:538
 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
+#: ../src/Frontend-GNOME/Views/Chats/ChatView.cs:764
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:135
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:136
+msgid "Show _Menubar"
+msgstr "Afficher la barre de _menus"
+
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:275
 #, 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:279
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:309
 msgid "done."
 msgstr "terminé."
 
-#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:290
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:320
 msgid "Person"
 msgstr "Personne"
 
-#: ../src/Frontend-GNOME/Views/Chats/ProtocolChatView.cs:69
+#: ../src/Frontend-GNOME/Views/Chats/ProtocolChatView.cs:146
 msgid ""
 "Closing the protocol chat will also close all open chats connected to it!\n"
 "Are you sure you want to do this?"
 msgstr ""
-"Fermer la fenêtre de chat du protocole va aussi fermer toutes discussions connectées sur celui-ci !\n"
+"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:187
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:189
 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:243
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:277
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:245
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:279
 msgid "Unable to edit server: "
 msgstr "Impossible d'editer le serveur :"
 
@@ -947,13 +895,169 @@ msgid "Smuxi - Find Group Chat"
 msgstr "Smuxi - Trouver un groupe de discussion"
 
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:47
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:73
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:71
 msgid "_Name:"
 msgstr "_Nom :"
 
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.JoinWidget.cs:69
+msgid "Join"
+msgstr "Rejoindre"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:55
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:56
+msgid "_Smuxi"
+msgstr "_Smuxi"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:58
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:59
+msgid "_Server"
+msgstr "_Serveur"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:61
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:62
+msgid "_Chat"
+msgstr "_Discussion"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:64
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:65
+msgid "_Engine"
+msgstr "_Moteur"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:67
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:68
+msgid "_View"
+msgstr "_Vue"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:70
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:71
+msgid "_Help"
+msgstr "_Aide"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:73
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:75
+msgid "Connect"
+msgstr "Connexion"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:77
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:79
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:150
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:151
+msgid "Open Log"
+msgstr "Ouvrir le journal"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:87
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:88
+msgid "_Preferences"
+msgstr "_Préférences"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:90
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:91
+msgid "_Quit"
+msgstr "_Quitter"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:93
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:94
+msgid "_Connect"
+msgstr "Connexion"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:96
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:97
+msgid "_Add"
+msgstr "_Ajouter"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:99
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:100
+msgid "_Manage"
+msgstr "_Gestion"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:102
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:103
+msgid "_Open / Join Chat"
+msgstr "_Ouvrir / Rejoindre chat"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:105
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:106
+msgid "_Find Group Chat"
+msgstr "_Rechercher le groupe de discussion"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:108
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:109
+msgid "C_lear All Activity"
+msgstr "_Supprimer toute activité"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:111
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:112
+msgid "_Next Chat"
+msgstr "Discussion _suivante"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:114
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:115
+msgid "_Previous Chat"
+msgstr "Discussion _précédente"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:117
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:118
+msgid "_Close"
+msgstr "_Fermer"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:120
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:121
+msgid "_Use Local Engine"
+msgstr "_Utiliser le moteur local"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:123
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:124
+msgid "_Add Remote Engine"
+msgstr "_Ajouter un moteur distant"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:126
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:127
+msgid "Switch Remote Engine"
+msgstr "Changer de moteur distant"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:129
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:130
+msgid "_Caret Mode"
+msgstr "Mode _curseur"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:132
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:133
+msgid "_Browse Mode"
+msgstr "Mode _navigateur"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:138
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:139
+msgid "Show _Statusbar"
+msgstr "Afficher la barre de status"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:141
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:142
+msgid "Show _Join Bar"
+msgstr "Afficher la barre \"Rejoindre\""
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:144
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:145
+msgid "_Fullscreen"
+msgstr "_Plein écran"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:147
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:148
+msgid "_About"
+msgstr "_À propos"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:153
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:155
+msgid "Find Group Chat"
+msgstr "Rechercher le groupe de discussion"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:157
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:158
+msgid "_Website"
+msgstr "Site web de Smuxi"
+
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs:19
-msgid "Smuxi - Quick Connect"
-msgstr "Smuxi - Connexion rapide"
+msgid "Smuxi - Connect"
+msgstr "Smuxi - Connexion"
 
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:206
 msgid "Smuxi - Preferences"
@@ -999,7 +1103,8 @@ msgid "SSH _Host:"
 msgstr "SSH _Hôte:"
 
 #: ../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>"
+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
@@ -1009,7 +1114,8 @@ msgid "_Port:"
 msgstr "_Port"
 
 #: ../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>"
+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:199
@@ -1022,8 +1128,8 @@ msgstr "Nom d'utilisateur _SSH (optionnel) :"
 
 #: ../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\">Nom d'utilisateur qui sera utilisé pour "
 "l'enregistrement auprès du moteur Smuxi</span>"
@@ -1034,13 +1140,12 @@ msgstr "Mot de passe _SSH (optionnel) :"
 
 #: ../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>"
+"<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>"
+"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)"
@@ -1097,7 +1202,8 @@ msgid ""
 "Click \"Forward\" to begin."
 msgstr ""
 "Bienvenue sur l'assistant de configuration du moteur Smuxi.\n"
-"Vous devez entrer plusieurs informations avant de pouvoir utiliser le moteur.\n"
+"Vous devez entrer plusieurs informations avant de pouvoir utiliser le "
+"moteur.\n"
 "\n"
 "Cliquez sur \"Suivant\" pour commencer."
 
@@ -1107,7 +1213,8 @@ msgstr "Nom du _moteur :"
 
 #: ../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>"
+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:80
 msgid "_Default Engine:"
@@ -1119,17 +1226,17 @@ msgstr "Utiliser comme moteur par défaut"
 
 #: ../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\">Activé, cette fonctionnalité rend le moteur courant par"
-" défaut au prochain démarrage de Smuxi</span>"
+"<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:20
 msgid "Smuxi - Open Chat"
 msgstr "Smuxi - Ouvrir un chat"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:63
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:61
 msgid "_Type:"
 msgstr "_Type :"
 
@@ -1161,4 +1268,11 @@ msgstr "Commandes de _connexion :"
 msgid "_Ignore Commands"
 msgstr "_Ignorer les commandes"
 
+#~ msgid "_File"
+#~ msgstr "_Fichier"
+
+#~ msgid "_Quick Connect"
+#~ msgstr "_Connexion rapide"
 
+#~ msgid "Unknown ChatType: {0}"
+#~ msgstr "ChatType inconnu : {0}"
diff --git a/po-Frontend-GNOME/sv.po b/po-Frontend-GNOME/sv.po
index 62c5f84..1e0708c 100644
--- a/po-Frontend-GNOME/sv.po
+++ b/po-Frontend-GNOME/sv.po
@@ -3,211 +3,195 @@
 # This file is distributed under the same license as the PACKAGE package.
 # 
 # Translators:
-#   <flugsio at gmail.com>, 2011.
+# flugsio <flugsio at gmail.com>, 2013
+# flugsio <flugsio at gmail.com>, 2011, 2012
 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: 2011-12-31 10:33+0000\n"
+"POT-Creation-Date: 2013-04-14 10:19+0200\n"
+"PO-Revision-Date: 2013-04-17 04:20+0000\n"
 "Last-Translator: flugsio <flugsio at gmail.com>\n"
-"Language-Team: Swedish (http://www.transifex.net/projects/p/smuxi/team/sv/)\n"
+"Language-Team: Swedish (http://www.transifex.com/projects/p/smuxi/language/sv/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Language: sv\n"
-"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:1
-msgid "<b> Chat </b>"
-msgstr "<b> Chatt </b>"
+msgid "Smuxi Preferences"
+msgstr "Alternativ för Smuxi"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:2
-msgid "<b> Color </b>"
-msgstr "<b> Färg </b>"
+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:3
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1172
-msgid "<b> Entry Field </b>"
-msgstr "<b> Inmatningsfält </b>"
+msgid "Nickname(s):"
+msgstr "Smeknamn:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:4
-msgid "<b> Font </b>"
-msgstr "<b> Teckensnitt </b>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:315
+msgid "Username:"
+msgstr "Användarnamn:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:5
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1502
-msgid "<b> Highlighting </b>"
-msgstr "<b> Förstärkning </b>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:338
+msgid "Realname:"
+msgstr "Riktigt namn:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:6
-msgid "<b> Notification Area Icon </b>"
-msgstr "<b> Ikon i notifieringsområdet </b>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:359
+msgid "Encoding:"
+msgstr "Kodning:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:7
-msgid "<b> Person List Position </b>"
-msgstr "<b> Position för personlista </b>"
+msgid "<b>General</b>"
+msgstr "<b>Allmänt</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> Flikfärg </b>"
+msgid "Type:"
+msgstr "Typ:"
 
 #: ../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> Position för flikar </b>"
+msgid "Host:"
+msgstr "Värd:"
 
 #: ../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> Position för rubrik </b>"
+msgid "Password:"
+msgstr "Lösenord:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:11
-msgid "<b>Advanced</b>"
-msgstr "<b>Avancerat</b>"
+msgid "Port:"
+msgstr "Port:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:12
-msgid "<b>General</b>"
-msgstr "<b>Allmänt</b>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:170
+msgid "Show Password"
+msgstr "Visa lösenord"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:13
-msgid "<b>Global Commands</b>"
-msgstr "<b>Allmänna kommandon</b>"
+msgid "<b>Network Proxy</b>"
+msgstr "<b>Nätverksproxy</b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:14
-msgid "<b>Message Buffer</b>"
-msgstr "<b>Meddelande-buffer</b>"
+#: ../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:15
-msgid "<b>Messaging Menu</b>"
-msgstr "<b>Meddelandemenu</b>"
+#: ../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:16
-msgid "<b>Network Proxy</b>"
-msgstr "<b>Nätverksproxy</b>"
+msgid "<b>Global Commands</b>"
+msgstr "<b>Allmänna kommandon</b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:17
-msgid "<b>Notification Popups</b>"
-msgstr "<b>Notifieringsmeddelanden</b>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:471
+msgid "C_onnection"
+msgstr "_Anslutning"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:18
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:961
-msgid "Activity"
-msgstr "Aktivitet"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:526
+msgid "Timestamp Format:"
+msgstr "Format för tidsstämpel:"
 
 #: ../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:20
-msgid "Background"
-msgstr "Bakgrund"
-
-#: ../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: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: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:24
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:546
 msgid "Buffer Lines:"
 msgstr "Buffrade rader:"
 
-#: ../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:26
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1112
-msgid "Command Character:"
-msgstr "Kommandotecken:"
-
-#: ../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:28
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1092
-msgid "Completion Character:"
-msgstr "Kompletteringstecken:"
+#: ../glade/smuxi-frontend-gnome.glade.h:20
+#: ../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:29
-msgid "Enable"
-msgstr "Aktivera"
+#: ../glade/smuxi-frontend-gnome.glade.h:21
+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 = sekunder\nmm = minuter\nhh = timmar (01 - 12)\nHH = timmar (00 - 23)\ntt = AM/PM\n\ndd = dag\nMM = månad\nyy/yyyy = år"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:30
-msgid "Enabled"
-msgstr "Aktivera"
+msgid "Persistency Type:"
+msgstr "Typ av persistens:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:31
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:359
-msgid "Encoding:"
-msgstr "Kodning:"
+msgid "Volatile Buffer Lines:"
+msgstr "Flyktiga buffer-rader:"
 
 #: ../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"
+msgid "Persistent Buffer Lines:"
+msgstr "Beständiga buffer-rader:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:33
-msgid "Foreground"
-msgstr "Förgrund"
+msgid "<b>Message Buffer</b>"
+msgstr "<b>Meddelande-buffer</b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:34
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:725
-msgid "General"
-msgstr "Allmänt"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:628
+msgid "Strip Colors"
+msgstr "Kasta färger"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:35
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:981
-msgid "Highlight"
-msgstr "Förstärk"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:667
+msgid "Strip Formattings"
+msgstr "Kasta formateringar"
 
 #: ../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"
+#: ../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:37
-msgid "Host:"
-msgstr "Värd:"
+msgid "Show Advanced Settings"
+msgstr "Visa avancerade inställningar"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:38
-msgid "Hostname:"
-msgstr "Värdnamn:"
+msgid "<b>Advanced</b>"
+msgstr "<b>Avancerat</b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:39
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1181
-msgid "Input"
-msgstr "Indata"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:725
+msgid "General"
+msgstr "Allmänt"
 
+#. Container child vbox6.Gtk.Box+BoxChild
+#. Container child vbox11.Gtk.Box+BoxChild
 #: ../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"
+#: ../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"
 
 #. Container child vbox6.Gtk.Box+BoxChild
-#. Container child vbox12.Gtk.Box+BoxChild
+#. Container child vbox11.Gtk.Box+BoxChild
 #: ../glade/smuxi-frontend-gnome.glade.h:41
+#: ../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"
+
+#. Container child vbox6.Gtk.Box+BoxChild
+#. Container child vbox12.Gtk.Box+BoxChild
+#: ../glade/smuxi-frontend-gnome.glade.h:42
 #: ../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
@@ -215,260 +199,273 @@ msgstr "Anslut/Lämna/Användartillstånd"
 msgid "Left"
 msgstr "Vänster"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:42
-msgid "Log Filtered Messages"
-msgstr "Logga filtrerade meddelanden"
-
+#. Container child vbox6.Gtk.Box+BoxChild
+#. Container child vbox12.Gtk.Box+BoxChild
 #: ../glade/smuxi-frontend-gnome.glade.h:43
-msgid "Network:"
-msgstr "Nätverk"
-
-#: ../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:45
-msgid "Nickname(s):"
-msgstr "Smeknamn:"
-
-#: ../glade/smuxi-frontend-gnome.glade.h:46
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:953
-msgid "No Activity"
-msgstr "Ingen aktivitet"
+#: ../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"
 
 #. 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
+#: ../glade/smuxi-frontend-gnome.glade.h:44
 #: ../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:45
+#: ../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:46
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:981
+msgid "Highlight"
+msgstr "Förstärk"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:47
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:961
+msgid "Activity"
+msgstr "Aktivitet"
+
 #: ../glade/smuxi-frontend-gnome.glade.h:48
-msgid "Notification"
-msgstr "Notifiering"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:953
+msgid "No Activity"
+msgstr "Ingen aktivitet"
 
 #: ../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:"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:971
+msgid "Join/Part/Mode"
+msgstr "Anslut/Lämna/Användartillstånd"
 
 #: ../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:"
+#: ../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:51
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1514
-msgid "Output"
-msgstr "Utdata"
+msgid "Automatically switch to newly opened person chats"
+msgstr "Byt automatiskt till nyligen öppnade person-chattar"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:52
-msgid "Override"
-msgstr "ÅSidosätt"
+msgid "Automatically switch to newly opened group chats"
+msgstr "Byt automatiskt till nyligen öppnade grupp-chattar"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:53
-msgid "Password:"
-msgstr "Lösenord:"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1022
+msgid "Tabs"
+msgstr "Flikar"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:54
-msgid "Persistency Type:"
-msgstr "Typ av persistens:"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1092
+msgid "Completion Character:"
+msgstr "Kompletteringstecken:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:55
-msgid "Persistent Buffer Lines:"
-msgstr "Beständiga buffer-rader:"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1112
+msgid "Command Character:"
+msgstr "Kommandotecken:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:56
-msgid "Port:"
-msgstr "Port:"
+#: ../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:57
-msgid "Protocol:"
-msgstr "Protokoll:"
+#: ../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:58
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:338
-msgid "Realname:"
-msgstr "Riktigt namn:"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1172
+msgid "<b> Entry Field </b>"
+msgstr "<b> Inmatningsfält </b>"
 
-#. 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 "Höger"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1181
+msgid "Input"
+msgstr "Indata"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:60
-msgid "Show Advanced Settings"
-msgstr "Visa avancerade inställningar"
+#: ../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:61
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:170
-msgid "Show Password"
-msgstr "Visa lösenord"
+msgid "<b> Person List Position </b>"
+msgstr "<b> Position för personlista </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:62
-msgid "Show Smuxi in the messaging menu"
-msgstr "Visa Smuxi i meddelandemenyn"
+msgid "Override"
+msgstr "ÅSidosätt"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:63
-msgid "Show always"
-msgstr "Visa alltid"
+msgid "<b> Font </b>"
+msgstr "<b> Teckensnitt </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:64
-msgid "Show notification popups"
-msgstr "Visa notifieringsmeddelanden"
+#: ../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:65
-msgid "Show when window is closed"
-msgstr "Visa när fönster är stängt"
+msgid "Foreground"
+msgstr "Förgrund"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:66
-msgid "Show when window is minimized"
-msgstr "Visa när fönster är minimerat"
+msgid "Background"
+msgstr "Bakgrund"
 
 #: ../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:68
-msgid "Smuxi Preferences"
-msgstr "Alternativ för Smuxi"
+msgid "<b> Color </b>"
+msgstr "<b> Färg </b>"
 
+#. This is a setting for character based line wrapping vs word based when
+#. showing messages
 #: ../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"
+msgid "_Wrap Mode:"
+msgstr "_Läge för radbrytning:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:70
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:667
-msgid "Strip Formattings"
-msgstr "Kasta formateringar"
+msgid "<b> Chat </b>"
+msgstr "<b> Chatt </b>"
 
 #: ../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"
+#: ../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:72
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1022
-msgid "Tabs"
-msgstr "Flikar"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1490
+msgid "Beep on highlight"
+msgstr "Pip vid förstärkning"
 
 #: ../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__."
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1502
+msgid "<b> Highlighting </b>"
+msgstr "<b> Förstärkning </b>"
 
 #: ../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:"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1514
+msgid "Output"
+msgstr "Utdata"
 
-#. 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 "Topp"
+msgid "Enable"
+msgstr "Aktivera"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:76
+msgid "Show always"
+msgstr "Visa alltid"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:77
+msgid "Show when window is minimized"
+msgstr "Visa när fönster är minimerat"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:78
+msgid "Show when window is closed"
+msgstr "Visa när fönster är stängt"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:79
+msgid "<b> Notification Area Icon </b>"
+msgstr "<b> Ikon i notifieringsområdet </b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:80
+msgid "Show Smuxi in the messaging menu"
+msgstr "Visa Smuxi i meddelandemenyn"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:81
+msgid "<b>Messaging Menu</b>"
+msgstr "<b>Meddelandemenu</b>"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:76
-msgid "Type:"
-msgstr "Typ:"
+#: ../glade/smuxi-frontend-gnome.glade.h:82
+msgid "Show notification popups"
+msgstr "Visa notifieringsmeddelanden"
 
-#: ../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:83
+msgid "<b>Notification Popups</b>"
+msgstr "<b>Notifieringsmeddelanden</b>"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:78
-msgid "Volatile Buffer Lines:"
-msgstr "Flyktiga buffer-rader:"
+#: ../glade/smuxi-frontend-gnome.glade.h:84
+msgid "Notification"
+msgstr "Notifiering"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:79
+#: ../glade/smuxi-frontend-gnome.glade.h:85
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1523
+msgid "_Interface"
+msgstr "_Gränssnitt"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:86
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1589
+msgid "_Servers"
+msgstr "_Servrar"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:87
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1681
 msgid "_Filters"
 msgstr "_Filter"
 
-#: ../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:88
+msgid "Enabled"
+msgstr "Aktivera"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:81
+#: ../glade/smuxi-frontend-gnome.glade.h:89
+msgid "Log Filtered Messages"
+msgstr "Logga filtrerade meddelanden"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:90
 msgid "_Logging"
 msgstr "_Loggning"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:82
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1589
-msgid "_Servers"
-msgstr "_Servrar"
+#: ../glade/smuxi-frontend-gnome.glade.h:91
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerDialog.cs:16
+msgid "Smuxi - Server"
+msgstr "Smuxi - Server"
 
-#. 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:92
+#: ../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: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 = sekunder\n"
-"mm = minuter\n"
-"hh = timmar (01 - 12)\n"
-"HH = timmar (00 - 23)\n"
-"tt = AM/PM\n"
-"\n"
-"dd = dag\n"
-"MM = månad\n"
-"yy/yyyy = år"
+#: ../glade/smuxi-frontend-gnome.glade.h:93
+msgid "Protocol:"
+msgstr "Protokoll:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:94
+msgid "Network:"
+msgstr "Nätverk"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:95
+msgid "Hostname:"
+msgstr "Värdnamn:"
 
 #: ../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"
+msgid "Smuxi"
+msgstr "Smuxi"
 
 #: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:2
 msgid "IRC Chat"
 msgstr "IRC chatt"
 
 #: ../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:60
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:4
+msgid "Chat with other people on IRC"
+msgstr "Chatta med andra människor på IRC"
+
+#: ../src/Frontend-GNOME/AboutDialog.cs:65
 msgid "translator-credits"
 msgstr "Martin Bagge <brother at bsnet.se>"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:65
+#: ../src/Frontend-GNOME/AboutDialog.cs:72
 msgid "Smuxi Website"
 msgstr "Smuxis webbplats"
 
@@ -482,247 +479,140 @@ msgstr "Smuxi krashade på grund av ett ohanterat fel."
 
 #: ../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:83
 msgid "_Report Bug"
 msgstr "_Rapportera fel"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:61
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:66
+msgid "Engine not found."
+msgstr "Motor hittades ej."
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:81
 msgid "Engine Manager"
 msgstr "Motorhanterare"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:80
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:100
 msgid "Select which Smuxi engine you want to connect to"
 msgstr "Ange vilken Smuximotor du vill ansluta till"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:86
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:106
 msgid "Engine:"
 msgstr "Motor:"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:97
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:117
 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
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:141
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:201
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:383
 msgid "Local Engine"
 msgstr "Lokal motor:"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:173
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:193
 msgid "Please select an engine!"
 msgstr "Välj en motor!"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:194
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:219
 #, 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:221
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:246
 msgid "An error occurred while connecting to the engine!"
 msgstr "Ett fel uppstod vid anslutning till motorn!"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:222
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:247
 #, csharp-format
 msgid "Engine URL: {0}"
 msgstr "URL till motorn: {0}"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:225
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:250
 #, csharp-format
 msgid "Error: {0}"
 msgstr "Fel: {0}"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:295
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:320
 #, 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:443
+#: ../src/Frontend-GNOME/Entry.cs:474
 #, 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:547
+#: ../src/Frontend-GNOME/Entry.cs:587
 msgid "Frontend Commands"
 msgstr "Kommandon för framdelen"
 
-#: ../src/Frontend-GNOME/MainWindow.cs:252
-msgid "_File"
-msgstr "_Arkiv"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:276
-msgid "_Server"
-msgstr "_Server"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:280
-msgid "_Quick Connect"
-msgstr "Snabb _anslutning"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:291
-msgid "_Manage"
-msgstr "_Hantera"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:298
-msgid "_Chat"
-msgstr "_Chatt"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:302
-msgid "Open / Join Chat"
-msgstr "Öppna / Anslut till chatt"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:308
-msgid "_Find Group Chat"
-msgstr "_Hitta gruppchatt"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:314
-msgid "C_lear All Activity"
-msgstr "_Rensa all aktivitet"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:321
-msgid "_Next Chat"
-msgstr "_Nästa chatt"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:335
-msgid "_Previous Chat"
-msgstr "_Föregående chatt"
-
-#: ../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:411
-msgid "_Use Local Engine"
-msgstr "_Använd lokal motor"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:417
-msgid "_Add Remote Engine"
-msgstr "_Lägg till fjärrmotor"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:422
-msgid "_Switch Remote Engine"
-msgstr "_Byt fjärrmotor"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:429
-msgid "_View"
-msgstr "_Visa"
-
-#: ../src/Frontend-GNOME/MainWindow.cs:433
-msgid "_Caret Mode"
-msgstr "_Markörläge"
-
-#: ../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: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:828
-#, csharp-format
-msgid "Unknown ChatType: {0}"
-msgstr "Okänd chattyp: {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 ""
-"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:1139
-msgid ""
-"Switching the remote engine will disconnect you from the current engine!\n"
-"Are you sure you want to do this?"
-msgstr ""
-"Byte av fjärrmotor 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/NotImplementedMessageDialog.cs:40
 msgid "Sorry, not implemented yet!"
 msgstr "Ursäkta, detta är inte implementerat än!"
 
 #. fill ListStore
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:179
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:185
 msgid "Character"
 msgstr "Tecken"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:180
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:186
 msgid "Word"
 msgstr "Ord"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:197
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:203
 msgid "Volatile"
 msgstr "Flyktig"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:199
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:205
 msgid "Persistent"
 msgstr "Beständig"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:222
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:228
 msgid "No Proxy"
 msgstr "Ingen Proxy"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:224
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:307
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:230
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:318
 msgid "System Default"
 msgstr "Systemstandard"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:238
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:244
 #: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:140
 msgid "Connection"
 msgstr "Anslutning"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:242
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:248
 msgid "Interface"
 msgstr "Gränssnitt."
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:246
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:252
 msgid "Servers"
 msgstr "Servrar"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:253
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:259
 msgid "Filters"
 msgstr "Filter"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:257
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:263
 msgid "Logging"
 msgstr "Loggning"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:642
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:666
 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:823
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:857
 #, 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:81
 #: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:106
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:271
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:265
 msgid "Name"
 msgstr "Namn"
 
@@ -734,78 +624,70 @@ msgstr "Rubrik"
 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 ""
-"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?"
+msgstr "Sökning efter gruppchattar utan att använda filter är inte rekomenderat. Det kan ta lång tid eller inte fungera alls.\nVill du verkligen fortsätta?"
 
 #: ../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:325
+#: ../src/Frontend-GNOME/Frontend.cs:400
 msgid "Disconnected from engine."
 msgstr "Frånkopplad från motorn."
 
-#: ../src/Frontend-GNOME/Frontend.cs:368
+#: ../src/Frontend-GNOME/Frontend.cs:442
 #, csharp-format
 msgid "Reconnecting to engine... (attempt {0})"
 msgstr "Återkopplar till motorn... (försök {0})"
 
-#: ../src/Frontend-GNOME/Frontend.cs:465
+#: ../src/Frontend-GNOME/Frontend.cs:540
 #, csharp-format
 msgid "Cause: {0}"
 msgstr "Anledning: {0}"
 
-#: ../src/Frontend-GNOME/Frontend.cs:583
+#: ../src/Frontend-GNOME/Frontend.cs:666
 msgid ""
 "The frontend has lost the connection to the server.\n"
 "Do you want to reconnect now?"
-msgstr ""
-"Framdelen tappade anslutningen till server.\n"
-"Vill du återansluta?"
+msgstr "Framdelen tappade anslutningen till server.\nVill du återansluta?"
 
-#: ../src/Frontend-GNOME/Frontend.cs:602
+#: ../src/Frontend-GNOME/Frontend.cs:685
 msgid ""
 "Reconnecting to the server has failed.\n"
 "Do you want to try again?"
-msgstr ""
-"Återanslutningsförsöket fungerade inte.\n"
-"Vill du försöka igen?"
+msgstr "Återanslutningsförsöket fungerade inte.\nVill du försöka igen?"
 
-#: ../src/Frontend-GNOME/Frontend.cs:705
+#: ../src/Frontend-GNOME/Frontend.cs:974
 msgid ""
 "The server has lost the connection to the frontend.\n"
 "Do you want to reconnect now?"
-msgstr ""
-"Servern har tappat anslutningen till framdelen.\n"
-"Vill du återansluta?"
+msgstr "Servern har tappat anslutningen till framdelen.\nVill du återansluta?"
 
-#: ../src/Frontend-GNOME/NotifyManager.cs:267
+#: ../src/Frontend-GNOME/NotifyManager.cs:336
 msgid "Show"
 msgstr "Visa"
 
-#: ../src/Frontend-GNOME/QuickConnectDialog.cs:62
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:238
+#: ../src/Frontend-GNOME/QuickConnectDialog.cs:58
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:233
 #: ../src/Frontend-GNOME/Preferences/ServerListView.cs:70
 msgid "Protocol"
 msgstr "Protokoll"
 
-#: ../src/Frontend-GNOME/QuickConnectDialog.cs:63
+#: ../src/Frontend-GNOME/QuickConnectDialog.cs:59
 #: ../src/Frontend-GNOME/Preferences/ServerListView.cs:71
 msgid "Hostname"
 msgstr "Värdnamn"
 
-#: ../src/Frontend-GNOME/QuickConnectDialog.cs:166
+#: ../src/Frontend-GNOME/QuickConnectDialog.cs:162
 msgid "Unable to load server: "
 msgstr "Kan inte ladda server:"
 
 #: ../src/Frontend-GNOME/ChatTypeWidget.cs:54
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:244
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:239
 msgid "Person / Private"
 msgstr "Person / Privat"
 
 #: ../src/Frontend-GNOME/ChatTypeWidget.cs:55
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:245
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:240
 msgid "Group / Public"
 msgstr "Grupp / Publikt"
 
@@ -838,82 +720,116 @@ 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:204
+#: ../src/Frontend-GNOME/Views/JoinWidget.cs:87
+msgid "Enter which chat to join"
+msgstr "Ange vilken chat att ansluta till"
+
+#: ../src/Frontend-GNOME/Views/MenuWidget.cs:140
+msgid "About Smuxi"
+msgstr "Om Smuxi"
+
+#. TODO: add cmd+, accelerator
+#: ../src/Frontend-GNOME/Views/MenuWidget.cs:144
+msgid "Preferences"
+msgstr "Alternativ"
+
+#: ../src/Frontend-GNOME/Views/MenuWidget.cs:238
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:227
+msgid "Unable to add server: "
+msgstr "Kan inte lägga till server:"
+
+#: ../src/Frontend-GNOME/Views/MenuWidget.cs:359
+msgid ""
+"Switching to local engine will disconnect you from the current engine!\n"
+"Are you sure you want to do this?"
+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/Views/MenuWidget.cs:403
+msgid ""
+"Switching the remote engine will disconnect you from the current engine!\n"
+"Are you sure you want to do this?"
+msgstr "Byte av fjärrmotor 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/Views/MessageTextView.cs:273
 #, csharp-format
 msgid "Day changed from {0} to {1}"
 msgstr "Dag ändrades från {0} till {1}"
 
-#: ../src/Frontend-GNOME/Views/MessageTextView.cs:210
+#: ../src/Frontend-GNOME/Views/MessageTextView.cs:277
 #, csharp-format
 msgid "Day changed to {0}"
 msgstr "Dygnsskifte, {0}"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:123
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:133
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:120
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:130
 #, csharp-format
 msgid "Invalid filter regex: '{0}'. Reason: {1}"
 msgstr "Ogiltigt filtermänster: \"{0}\". Anledning: {1}"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:200
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:197
 msgid "Are you sure you want to delete the selected filter?"
 msgstr "Är du säker på att du vill radera det valda filtret?"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:246
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:241
 msgid "Protocol / Server"
 msgstr "Protokoll / Server"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:253
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:248
 msgid "Chat Type"
-msgstr "Chattyp"
+msgstr "Chatt-typ"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:287
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:281
 msgid "Normal"
 msgstr "Normal"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:288
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:282
 msgid "Event"
 msgstr "Händelse"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:295
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:289
 msgid "Type"
 msgstr "Typ"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:321
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:314
 msgid "Pattern"
 msgstr "Mönster"
 
-#: ../src/Frontend-GNOME/Views/Chats/ChatView.cs:506
+#: ../src/Frontend-GNOME/Views/Chats/ChatView.cs:538
 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
+#: ../src/Frontend-GNOME/Views/Chats/ChatView.cs:764
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:135
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:136
+msgid "Show _Menubar"
+msgstr "Visa Menu"
+
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:275
 #, 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:279
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:309
 msgid "done."
 msgstr "klar"
 
-#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:290
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:320
 msgid "Person"
 msgstr "Person"
 
-#: ../src/Frontend-GNOME/Views/Chats/ProtocolChatView.cs:69
+#: ../src/Frontend-GNOME/Views/Chats/ProtocolChatView.cs:146
 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ä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?"
+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:187
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:189
 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:243
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:277
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:245
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:279
 msgid "Unable to edit server: "
 msgstr "Kan inte redigera server:"
 
@@ -946,13 +862,169 @@ msgid "Smuxi - Find Group Chat"
 msgstr "Smuxi - Hitta gruppchatt"
 
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.FindGroupChatDialog.cs:47
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:73
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:71
 msgid "_Name:"
 msgstr "_Namn:"
 
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.JoinWidget.cs:69
+msgid "Join"
+msgstr "Anslut"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:55
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:56
+msgid "_Smuxi"
+msgstr "_Smuxi"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:58
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:59
+msgid "_Server"
+msgstr "_Server"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:61
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:62
+msgid "_Chat"
+msgstr "_Chatt"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:64
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:65
+msgid "_Engine"
+msgstr "_Motor"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:67
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:68
+msgid "_View"
+msgstr "_Visa"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:70
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:71
+msgid "_Help"
+msgstr "_Hjälp"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:73
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:75
+msgid "Connect"
+msgstr "Anslut"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:77
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:79
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:150
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:151
+msgid "Open Log"
+msgstr "Öppna logg"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:87
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:88
+msgid "_Preferences"
+msgstr "A_lternativ"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:90
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:91
+msgid "_Quit"
+msgstr "A_vsluta"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:93
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:94
+msgid "_Connect"
+msgstr "_Anslut"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:96
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:97
+msgid "_Add"
+msgstr "_Lägg till"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:99
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:100
+msgid "_Manage"
+msgstr "_Hantera"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:102
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:103
+msgid "_Open / Join Chat"
+msgstr "_Öppna / Anslut till chatt"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:105
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:106
+msgid "_Find Group Chat"
+msgstr "_Hitta gruppchatt"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:108
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:109
+msgid "C_lear All Activity"
+msgstr "_Rensa all aktivitet"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:111
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:112
+msgid "_Next Chat"
+msgstr "_Nästa chatt"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:114
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:115
+msgid "_Previous Chat"
+msgstr "_Föregående chatt"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:117
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:118
+msgid "_Close"
+msgstr "S_täng"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:120
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:121
+msgid "_Use Local Engine"
+msgstr "_Använd lokal motor"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:123
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:124
+msgid "_Add Remote Engine"
+msgstr "_Lägg till fjärrmotor"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:126
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:127
+msgid "Switch Remote Engine"
+msgstr "Byt fjärrmotor"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:129
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:130
+msgid "_Caret Mode"
+msgstr "_Markörläge"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:132
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:133
+msgid "_Browse Mode"
+msgstr "Visningsläge"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:138
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:139
+msgid "Show _Statusbar"
+msgstr "Visa _Statusbar"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:141
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:142
+msgid "Show _Join Bar"
+msgstr "Visa a_nslutningsbar"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:144
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:145
+msgid "_Fullscreen"
+msgstr "_Fullskärm"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:147
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:148
+msgid "_About"
+msgstr "_Om"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:153
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:155
+msgid "Find Group Chat"
+msgstr "Hitta grupp-chat"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:157
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:158
+msgid "_Website"
+msgstr "_Webbplats"
+
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs:19
-msgid "Smuxi - Quick Connect"
-msgstr "Smuxi - Snabbanslutning"
+msgid "Smuxi - Connect"
+msgstr "Smuxi - Anslut"
 
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:206
 msgid "Smuxi - Preferences"
@@ -987,10 +1059,7 @@ 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>"
+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:135
 msgid "SSH _Host:"
@@ -1008,8 +1077,7 @@ msgstr "_Port"
 
 #: ../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:199
 msgid "_Smuxi Host:"
@@ -1023,9 +1091,7 @@ msgstr "_SSH-avnändarnamn: (valbart)"
 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>"
+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:95
 msgid "_SSH Password: (optional)"
@@ -1036,10 +1102,7 @@ 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>"
+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)"
@@ -1054,9 +1117,7 @@ msgstr "Välj en fil"
 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>"
+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:181
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:188
@@ -1067,9 +1128,7 @@ msgstr "_Användarnamn:"
 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>"
+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:224
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:87
@@ -1094,11 +1153,7 @@ msgid ""
 "You need to enter some information before you can use the engine.\n"
 "\n"
 "Click \"Forward\" to begin."
-msgstr ""
-"Välkommen till inställningsdelen för Smuximotorn.\n"
-"Du behöver ange lite information innan du kan börja använda motorn.\n"
-"\n"
-"Klicka \"Nästa\" för att böja."
+msgstr "Välkommen till inställningsdelen för Smuximotorn.\nDu behöver ange lite information innan du kan börja använda motorn.\n\nKlicka \"Nästa\" för att böja."
 
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:36
 msgid "_Engine Name:"
@@ -1120,15 +1175,13 @@ msgstr "Använd som ny standardmotor"
 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>"
+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:20
 msgid "Smuxi - Open Chat"
-msgstr "Smuxi - Öppen hatt"
+msgstr "Smuxi - Öppen chatt"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:63
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:61
 msgid "_Type:"
 msgstr "_Typ:"
 
@@ -1159,5 +1212,3 @@ msgstr "_Kommando vid anslutning:"
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:265
 msgid "_Ignore Commands"
 msgstr "Kommando att _ignorera"
-
-
diff --git a/po-Frontend-GNOME/zh_CN.po b/po-Frontend-GNOME/zh_CN.po
index 7d44a33..c131b99 100644
--- a/po-Frontend-GNOME/zh_CN.po
+++ b/po-Frontend-GNOME/zh_CN.po
@@ -3,211 +3,194 @@
 # This file is distributed under the same license as the PACKAGE package.
 # 
 # Translators:
-# Dean Lee <xslidian at gmail.com>, 2012.
+# Dean Lee <xslidian at gmail.com>, 2012-2013.
 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: 2012-01-07 09:58+0000\n"
+"POT-Creation-Date: 2013-04-14 10:19+0200\n"
+"PO-Revision-Date: 2013-04-14 14:10+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"
+"Language-Team: Chinese (China) (http://www.transifex.com/projects/p/smuxi/language/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"
+"Plural-Forms: nplurals=1; plural=0;\n"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:1
-msgid "<b> Chat </b>"
-msgstr "<b> 聊天 </b>"
+msgid "Smuxi Preferences"
+msgstr "Smuxi 偏好设置"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:2
-msgid "<b> Color </b>"
-msgstr "<b> 颜色 </b>"
+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:3
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1172
-msgid "<b> Entry Field </b>"
-msgstr "<b> 预留字段 </b>"
+msgid "Nickname(s):"
+msgstr "昵称:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:4
-msgid "<b> Font </b>"
-msgstr "<b> 字体 </b>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:315
+msgid "Username:"
+msgstr "用户名:"
 
 #: ../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>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:338
+msgid "Realname:"
+msgstr "真名:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:6
-msgid "<b> Notification Area Icon </b>"
-msgstr "<b> 通知区域图标 </b>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:359
+msgid "Encoding:"
+msgstr "编码:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:7
-msgid "<b> Person List Position </b>"
-msgstr "<b> 成员列表位置 </b>"
+msgid "<b>General</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>"
+msgid "Type:"
+msgstr "类型:"
 
 #: ../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>"
+msgid "Host:"
+msgstr "主机:"
 
 #: ../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>"
+msgid "Password:"
+msgstr "密码:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:11
-msgid "<b>Advanced</b>"
-msgstr "<b>高级</b>"
+msgid "Port:"
+msgstr "端口:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:12
-msgid "<b>General</b>"
-msgstr "<b>全局</b>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:170
+msgid "Show Password"
+msgstr "显示密码"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:13
-msgid "<b>Global Commands</b>"
-msgstr "<b>全局命令</b>"
+msgid "<b>Network Proxy</b>"
+msgstr "<b>网络代理</b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:14
-msgid "<b>Message Buffer</b>"
-msgstr "<b>信息缓冲</b>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:381
+msgid "On Connect Commands:"
+msgstr "连接时命令:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:15
-msgid "<b>Messaging Menu</b>"
-msgstr "<b>消息菜单</b>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:427
+msgid "On Startup Commands:"
+msgstr "启动时命令:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:16
-msgid "<b>Network Proxy</b>"
-msgstr "<b>网络代理</b>"
+msgid "<b>Global Commands</b>"
+msgstr "<b>全局命令</b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:17
-msgid "<b>Notification Popups</b>"
-msgstr "<b>通知弹出</b>"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:471
+msgid "C_onnection"
+msgstr "连接(_O)"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:18
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:961
-msgid "Activity"
-msgstr "活动"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:526
+msgid "Timestamp Format:"
+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:20
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:569
+msgid "Engine Buffer Lines:"
+msgstr "引擎缓冲行数:"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:29
-msgid "Enable"
-msgstr "启用"
+#: ../glade/smuxi-frontend-gnome.glade.h:21
+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 = 秒数\nmm = 分数\nhh = 小时数 (01 - 12)\nHH = 小时数 (00 - 23)\ntt = AM/PM\n\ndd = day\nMM = month\nyy/yyyy = year"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:30
-msgid "Enabled"
-msgstr "启用"
+msgid "Persistency Type:"
+msgstr "持久类型:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:31
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:359
-msgid "Encoding:"
-msgstr "编码:"
+msgid "Volatile Buffer Lines:"
+msgstr "临时缓冲行数:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:32
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:569
-msgid "Engine Buffer Lines:"
-msgstr "引擎缓冲行数:"
+msgid "Persistent Buffer Lines:"
+msgstr "持久缓冲行数:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:33
-msgid "Foreground"
-msgstr "前景"
+msgid "<b>Message Buffer</b>"
+msgstr "<b>信息缓冲</b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:34
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:725
-msgid "General"
-msgstr "全局"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:628
+msgid "Strip Colors"
+msgstr "去除颜色"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:35
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:981
-msgid "Highlight"
-msgstr "高亮"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:667
+msgid "Strip Formattings"
+msgstr "去除格式"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:36
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1466
-msgid "Highlight words:"
-msgstr "高亮单词:"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:707
+msgid "Strip UTF-8"
+msgstr "去除 UTF-8"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:37
-msgid "Host:"
-msgstr "主机:"
+msgid "Show Advanced Settings"
+msgstr "显示高级设置"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:38
-msgid "Hostname:"
-msgstr "主机名:"
+msgid "<b>Advanced</b>"
+msgstr "<b>高级</b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:39
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1181
-msgid "Input"
-msgstr "输入"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:725
+msgid "General"
+msgstr "全局"
 
+#. Container child vbox6.Gtk.Box+BoxChild
+#. Container child vbox11.Gtk.Box+BoxChild
 #: ../glade/smuxi-frontend-gnome.glade.h:40
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:971
-msgid "Join/Part/Mode"
-msgstr "加入/离开/模式"
+#: ../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 "顶部"
 
 #. Container child vbox6.Gtk.Box+BoxChild
-#. Container child vbox12.Gtk.Box+BoxChild
+#. Container child vbox11.Gtk.Box+BoxChild
 #: ../glade/smuxi-frontend-gnome.glade.h:41
+#: ../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 "底部"
+
+#. Container child vbox6.Gtk.Box+BoxChild
+#. Container child vbox12.Gtk.Box+BoxChild
+#: ../glade/smuxi-frontend-gnome.glade.h:42
 #: ../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
@@ -215,257 +198,273 @@ msgstr "加入/离开/模式"
 msgid "Left"
 msgstr "左边"
 
-#: ../glade/smuxi-frontend-gnome.glade.h:42
-msgid "Log Filtered Messages"
-msgstr "记录经过滤的消息"
-
+#. Container child vbox6.Gtk.Box+BoxChild
+#. Container child vbox12.Gtk.Box+BoxChild
 #: ../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 "无活动"
+#: ../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 "右边"
 
 #. 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
+#: ../glade/smuxi-frontend-gnome.glade.h:44
 #: ../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:45
+#: ../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:46
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:981
+msgid "Highlight"
+msgstr "高亮"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:47
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:961
+msgid "Activity"
+msgstr "活动"
+
 #: ../glade/smuxi-frontend-gnome.glade.h:48
-msgid "Notification"
-msgstr "通知"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:953
+msgid "No Activity"
+msgstr "无活动"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:49
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:381
-msgid "On Connect Commands:"
-msgstr "连接时命令:"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:971
+msgid "Join/Part/Mode"
+msgstr "加入/离开/模式"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:50
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:427
-msgid "On Startup Commands:"
-msgstr "启动时命令:"
+#: ../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:51
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1514
-msgid "Output"
-msgstr "输出"
+msgid "Automatically switch to newly opened person chats"
+msgstr "自动切换到新打开的单人聊天"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:52
-msgid "Override"
-msgstr "覆盖"
+msgid "Automatically switch to newly opened group chats"
+msgstr "自动切换到新打开的群组聊天"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:53
-msgid "Password:"
-msgstr "密码:"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1022
+msgid "Tabs"
+msgstr "标签"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:54
-msgid "Persistency Type:"
-msgstr "持久类型:"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1092
+msgid "Completion Character:"
+msgstr "完成字符:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:55
-msgid "Persistent Buffer Lines:"
-msgstr "持久缓冲行数:"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1112
+msgid "Command Character:"
+msgstr "命令字符:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:56
-msgid "Port:"
-msgstr "端口:"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1135
+msgid "Command History Size:"
+msgstr "命令历史数:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:57
-msgid "Protocol:"
-msgstr "协议:"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1160
+msgid "Bash-Style Completion"
+msgstr "Bash 式完成"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:58
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:338
-msgid "Realname:"
-msgstr "真名:"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1172
+msgid "<b> Entry Field </b>"
+msgstr "<b> 预留字段 </b>"
 
-#. 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 "右边"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1181
+msgid "Input"
+msgstr "输入"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:60
-msgid "Show Advanced Settings"
-msgstr "显示高级设置"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1202
+msgid "Nick Colors"
+msgstr "昵称颜色"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:61
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:170
-msgid "Show Password"
-msgstr "显示密码"
+msgid "<b> Person List Position </b>"
+msgstr "<b> 成员列表位置 </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:62
-msgid "Show Smuxi in the messaging menu"
-msgstr "在消息菜单中显示 Smuxi"
+msgid "Override"
+msgstr "覆盖"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:63
-msgid "Show always"
-msgstr "总是显示"
+msgid "<b> Font </b>"
+msgstr "<b> 字体 </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:64
-msgid "Show notification popups"
-msgstr "显示通知弹出"
+#: ../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:65
-msgid "Show when window is closed"
-msgstr "当窗口关闭时显示"
+msgid "Foreground"
+msgstr "前景"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:66
-msgid "Show when window is minimized"
-msgstr "当窗口最小化时显示"
+msgid "Background"
+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 "Smuxi 偏好设置"
+msgid "<b> Color </b>"
+msgstr "<b> 颜色 </b>"
 
+#. This is a setting for character based line wrapping vs word based when
+#. showing messages
 #: ../glade/smuxi-frontend-gnome.glade.h:69
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:628
-msgid "Strip Colors"
-msgstr "去除颜色"
+msgid "_Wrap Mode:"
+msgstr "_自动换行模式:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:70
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:667
-msgid "Strip Formattings"
-msgstr "去除格式"
+msgid "<b> Chat </b>"
+msgstr "<b> 聊天 </b>"
 
 #: ../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"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1466
+msgid "Highlight words:"
+msgstr "高亮单词:"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:72
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1022
-msgid "Tabs"
-msgstr "标签"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1490
+msgid "Beep on highlight"
+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 "要使用的昵称。您可以指定多个昵称(用空格分隔)作为首个选项不可用时的候选项。默认使用 $昵称_ 和 $昵称__ 作为候选项。"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1502
+msgid "<b> Highlighting </b>"
+msgstr "<b> 高亮 </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:74
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:526
-msgid "Timestamp Format:"
-msgstr "时间戳格式:"
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1514
+msgid "Output"
+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 "顶部"
+msgid "Enable"
+msgstr "启用"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:76
-msgid "Type:"
-msgstr "类型:"
+msgid "Show always"
+msgstr "总是显示"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:77
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:315
-msgid "Username:"
-msgstr "用户名:"
+msgid "Show when window is minimized"
+msgstr "当窗口最小化时显示"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:78
-msgid "Volatile Buffer Lines:"
-msgstr "临时缓冲行数:"
+msgid "Show when window is closed"
+msgstr "当窗口关闭时显示"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:79
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1681
-msgid "_Filters"
-msgstr "过滤器(_F)"
+msgid "<b> Notification Area Icon </b>"
+msgstr "<b> 通知区域图标 </b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:80
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1523
-msgid "_Interface"
-msgstr "界面(_I)"
+msgid "Show Smuxi in the messaging menu"
+msgstr "在消息菜单中显示 Smuxi"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:81
-msgid "_Logging"
-msgstr "历史(_L)"
+msgid "<b>Messaging Menu</b>"
+msgstr "<b>消息菜单</b>"
 
 #: ../glade/smuxi-frontend-gnome.glade.h:82
+msgid "Show notification popups"
+msgstr "显示通知弹出"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:83
+msgid "<b>Notification Popups</b>"
+msgstr "<b>通知弹出</b>"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:84
+msgid "Notification"
+msgstr "通知"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:85
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1523
+msgid "_Interface"
+msgstr "界面(_I)"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:86
 #: ../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:87
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:1681
+msgid "_Filters"
+msgstr "过滤器(_F)"
 
-#: ../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"
+#: ../glade/smuxi-frontend-gnome.glade.h:88
+msgid "Enabled"
+msgstr "启用"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:89
+msgid "Log Filtered Messages"
+msgstr "记录经过滤的消息"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:90
+msgid "_Logging"
+msgstr "历史(_L)"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:91
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerDialog.cs:16
+msgid "Smuxi - Server"
+msgstr "Smuxi - 服务器"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:92
+#: ../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:93
+msgid "Protocol:"
+msgstr "协议:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:94
+msgid "Network:"
+msgstr "网络:"
+
+#: ../glade/smuxi-frontend-gnome.glade.h:95
+msgid "Hostname:"
+msgstr "主机名:"
 
 #: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:1
-msgid "Chat with other people on IRC"
-msgstr "和 IRC 上的其他人聊天"
+msgid "Smuxi"
+msgstr "Smuxi"
 
 #: ../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 "Smuxi"
-
-#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:4
 msgid "Smuxi IRC Client"
 msgstr "Smuxi IRC 客户端"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:60
+#: ../src/Frontend-GNOME/smuxi-frontend-gnome.desktop.in.h:4
+msgid "Chat with other people on IRC"
+msgstr "和 IRC 上的其他人聊天"
+
+#: ../src/Frontend-GNOME/AboutDialog.cs:65
 msgid "translator-credits"
 msgstr "Dean Lee <xslidian+smuxi at gmail.com>"
 
-#: ../src/Frontend-GNOME/AboutDialog.cs:65
+#: ../src/Frontend-GNOME/AboutDialog.cs:72
 msgid "Smuxi Website"
 msgstr "Smuxi 网站"
 
@@ -485,237 +484,134 @@ msgstr "这是 stacktrace,请报告错误!"
 msgid "_Report Bug"
 msgstr "报告错误(_R)"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:61
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:66
+msgid "Engine not found."
+msgstr "引擎未找到。"
+
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:81
 msgid "Engine Manager"
 msgstr "引擎管理器"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:80
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:100
 msgid "Select which Smuxi engine you want to connect to"
 msgstr "选择希望连接到的 Smuxi 引擎"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:86
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:106
 msgid "Engine:"
 msgstr "引擎:"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:97
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:117
 msgid "Use Low Bandwidth Mode"
 msgstr "使用低带宽模式"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:121
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:181
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:358
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:141
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:201
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:383
 msgid "Local Engine"
 msgstr "本地引擎"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:173
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:193
 msgid "Please select an engine!"
 msgstr "请选择一个引擎!"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:194
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:219
 #, csharp-format
 msgid "Your frontend version ({0}) does not match the engine version ({1})!"
 msgstr "您的前端版本 ({0}) 与引擎版本 ({1}) 不匹配!"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:221
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:246
 msgid "An error occurred while connecting to the engine!"
 msgstr "连接到引擎时出现了一个错误!"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:222
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:247
 #, csharp-format
 msgid "Engine URL: {0}"
 msgstr "引擎 URL: {0}"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:225
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:250
 #, csharp-format
 msgid "Error: {0}"
 msgstr "错误: {0}"
 
-#: ../src/Frontend-GNOME/EngineManagerDialog.cs:295
+#: ../src/Frontend-GNOME/EngineManagerDialog.cs:320
 #, csharp-format
 msgid "Are you sure you want to delete the engine \"{0}\"?"
 msgstr "您确实要删除引擎 \"{0}\" 吗?"
 
-#: ../src/Frontend-GNOME/Entry.cs:443
+#: ../src/Frontend-GNOME/Entry.cs:474
 #, 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
+#: ../src/Frontend-GNOME/Entry.cs:587
 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
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:185
 msgid "Character"
 msgstr "字符"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:180
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:186
 msgid "Word"
 msgstr "单词"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:197
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:203
 msgid "Volatile"
 msgstr "临时"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:199
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:205
 msgid "Persistent"
 msgstr "持久"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:222
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:228
 msgid "No Proxy"
 msgstr "无代理"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:224
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:307
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:230
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:318
 msgid "System Default"
 msgstr "系统默认"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:238
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:244
 #: ../src/Frontend-GNOME/Views/Assistants/Engine/EngineAssistant.cs:140
 msgid "Connection"
 msgstr "连接"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:242
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:248
 msgid "Interface"
 msgstr "界面"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:246
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:252
 msgid "Servers"
 msgstr "服务器"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:253
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:259
 msgid "Filters"
 msgstr "过滤器"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:257
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:263
 msgid "Logging"
 msgstr "历史"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:642
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:666
 msgid "Nicknames(s) field must not be empty."
 msgstr "昵称字段不能为空。"
 
-#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:823
+#: ../src/Frontend-GNOME/Preferences/PreferencesDialog.cs:857
 #, 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
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:265
 msgid "Name"
 msgstr "名称"
 
@@ -727,78 +623,70 @@ msgstr "主题"
 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"
-"您是否打算继续?"
+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
+#: ../src/Frontend-GNOME/Frontend.cs:400
 msgid "Disconnected from engine."
 msgstr "从引擎断开连接。"
 
-#: ../src/Frontend-GNOME/Frontend.cs:368
+#: ../src/Frontend-GNOME/Frontend.cs:442
 #, csharp-format
 msgid "Reconnecting to engine... (attempt {0})"
 msgstr "正在重新连接到引擎... (第 {0} 次尝试)"
 
-#: ../src/Frontend-GNOME/Frontend.cs:465
+#: ../src/Frontend-GNOME/Frontend.cs:540
 #, csharp-format
 msgid "Cause: {0}"
 msgstr "原因: {0}"
 
-#: ../src/Frontend-GNOME/Frontend.cs:583
+#: ../src/Frontend-GNOME/Frontend.cs:666
 msgid ""
 "The frontend has lost the connection to the server.\n"
 "Do you want to reconnect now?"
-msgstr ""
-"前端与服务器之间的连接已丢失。\n"
-"是否希望现在重新连接?"
+msgstr "前端与服务器之间的连接已丢失。\n是否希望现在重新连接?"
 
-#: ../src/Frontend-GNOME/Frontend.cs:602
+#: ../src/Frontend-GNOME/Frontend.cs:685
 msgid ""
 "Reconnecting to the server has failed.\n"
 "Do you want to try again?"
-msgstr ""
-"重新连接到服务器失败。\n"
-"是否重试?"
+msgstr "重新连接到服务器失败。\n是否重试?"
 
-#: ../src/Frontend-GNOME/Frontend.cs:705
+#: ../src/Frontend-GNOME/Frontend.cs:974
 msgid ""
 "The server has lost the connection to the frontend.\n"
 "Do you want to reconnect now?"
-msgstr ""
-"服务器与前端之间的连接已丢失。\n"
-"是否希望现在重新连接?"
+msgstr "服务器与前端之间的连接已丢失。\n是否希望现在重新连接?"
 
-#: ../src/Frontend-GNOME/NotifyManager.cs:267
+#: ../src/Frontend-GNOME/NotifyManager.cs:336
 msgid "Show"
 msgstr "显示"
 
-#: ../src/Frontend-GNOME/QuickConnectDialog.cs:62
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:238
+#: ../src/Frontend-GNOME/QuickConnectDialog.cs:58
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:233
 #: ../src/Frontend-GNOME/Preferences/ServerListView.cs:70
 msgid "Protocol"
 msgstr "协议"
 
-#: ../src/Frontend-GNOME/QuickConnectDialog.cs:63
+#: ../src/Frontend-GNOME/QuickConnectDialog.cs:59
 #: ../src/Frontend-GNOME/Preferences/ServerListView.cs:71
 msgid "Hostname"
 msgstr "主机名"
 
-#: ../src/Frontend-GNOME/QuickConnectDialog.cs:166
+#: ../src/Frontend-GNOME/QuickConnectDialog.cs:162
 msgid "Unable to load server: "
 msgstr "无法加载服务器: "
 
 #: ../src/Frontend-GNOME/ChatTypeWidget.cs:54
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:244
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:239
 msgid "Person / Private"
 msgstr "成员 / 私聊"
 
 #: ../src/Frontend-GNOME/ChatTypeWidget.cs:55
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:245
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:240
 msgid "Group / Public"
 msgstr "群组 / 公开"
 
@@ -831,82 +719,116 @@ msgid ""
 "An engine with this name already exists! Please specify a different one."
 msgstr "已存在同名引擎! 请另外指定一个。"
 
-#: ../src/Frontend-GNOME/Views/MessageTextView.cs:204
+#: ../src/Frontend-GNOME/Views/JoinWidget.cs:87
+msgid "Enter which chat to join"
+msgstr "输入要加入的聊天"
+
+#: ../src/Frontend-GNOME/Views/MenuWidget.cs:140
+msgid "About Smuxi"
+msgstr "关于 Smuxi"
+
+#. TODO: add cmd+, accelerator
+#: ../src/Frontend-GNOME/Views/MenuWidget.cs:144
+msgid "Preferences"
+msgstr "偏好设置"
+
+#: ../src/Frontend-GNOME/Views/MenuWidget.cs:238
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:227
+msgid "Unable to add server: "
+msgstr "无法添加服务器: "
+
+#: ../src/Frontend-GNOME/Views/MenuWidget.cs:359
+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/Views/MenuWidget.cs:403
+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/Views/MessageTextView.cs:273
 #, csharp-format
 msgid "Day changed from {0} to {1}"
 msgstr "天数由 {0} 变为 {1}"
 
-#: ../src/Frontend-GNOME/Views/MessageTextView.cs:210
+#: ../src/Frontend-GNOME/Views/MessageTextView.cs:277
 #, csharp-format
 msgid "Day changed to {0}"
 msgstr "日期已改为 {0}"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:123
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:133
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:120
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:130
 #, csharp-format
 msgid "Invalid filter regex: '{0}'. Reason: {1}"
 msgstr "无效的过滤器正则表达式: '{0}'。原因: {1}"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:200
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:197
 msgid "Are you sure you want to delete the selected filter?"
 msgstr "您确实要删除选中的过滤器?"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:246
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:241
 msgid "Protocol / Server"
 msgstr "协议 / 服务器"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:253
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:248
 msgid "Chat Type"
 msgstr "聊天类型"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:287
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:281
 msgid "Normal"
 msgstr "普通"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:288
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:282
 msgid "Event"
 msgstr "事件"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:295
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:289
 msgid "Type"
 msgstr "类型"
 
-#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:321
+#: ../src/Frontend-GNOME/Views/FilterListWidget.cs:314
 msgid "Pattern"
 msgstr "匹配"
 
-#: ../src/Frontend-GNOME/Views/Chats/ChatView.cs:506
+#: ../src/Frontend-GNOME/Views/Chats/ChatView.cs:538
 msgid "Low Bandwidth Mode is active: no messages synced."
 msgstr "低带宽模式未启用: 未同步任何信息。"
 
-#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:245
+#: ../src/Frontend-GNOME/Views/Chats/ChatView.cs:764
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:135
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:136
+msgid "Show _Menubar"
+msgstr "显示菜单栏(_M)"
+
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:275
 #, 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
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:309
 msgid "done."
 msgstr "完成。"
 
-#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:290
+#: ../src/Frontend-GNOME/Views/Chats/GroupChatView.cs:320
 msgid "Person"
 msgstr "成员"
 
-#: ../src/Frontend-GNOME/Views/Chats/ProtocolChatView.cs:69
+#: ../src/Frontend-GNOME/Views/Chats/ProtocolChatView.cs:146
 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"
-"您确实希望这么做吗?"
+msgstr "关闭该协议将同时关闭所有连接到它的开放聊天!\n您确实希望这么做吗?"
 
-#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:187
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:189
 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
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:245
+#: ../src/Frontend-GNOME/Preferences/ServerListView.cs:279
 msgid "Unable to edit server: "
 msgstr "无法编辑服务器: "
 
@@ -939,13 +861,169 @@ 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
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:71
 msgid "_Name:"
 msgstr "名称(_N):"
 
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.JoinWidget.cs:69
+msgid "Join"
+msgstr "加入"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:55
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:56
+msgid "_Smuxi"
+msgstr "_Smuxi"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:58
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:59
+msgid "_Server"
+msgstr "服务器(_S)"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:61
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:62
+msgid "_Chat"
+msgstr "聊天(_C)"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:64
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:65
+msgid "_Engine"
+msgstr "引擎(_E)"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:67
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:68
+msgid "_View"
+msgstr "视图(_V)"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:70
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:71
+msgid "_Help"
+msgstr "帮助(_H)"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:73
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:75
+msgid "Connect"
+msgstr "连接"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:77
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:79
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:150
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:151
+msgid "Open Log"
+msgstr "打开聊天历史"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:87
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:88
+msgid "_Preferences"
+msgstr "偏好设置(_P)"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:90
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:91
+msgid "_Quit"
+msgstr "退出(_Q)"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:93
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:94
+msgid "_Connect"
+msgstr "连接(_C)"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:96
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:97
+msgid "_Add"
+msgstr "添加(_A)"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:99
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:100
+msgid "_Manage"
+msgstr "管理(_M)"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:102
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:103
+msgid "_Open / Join Chat"
+msgstr "打开(_O) / 加入聊天"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:105
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:106
+msgid "_Find Group Chat"
+msgstr "查找群组聊天(_F)"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:108
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:109
+msgid "C_lear All Activity"
+msgstr "清除所有活动(_L)"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:111
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:112
+msgid "_Next Chat"
+msgstr "下一个聊天(_N)"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:114
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:115
+msgid "_Previous Chat"
+msgstr "上一个聊天(_P)"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:117
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:118
+msgid "_Close"
+msgstr "关闭(_C)"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:120
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:121
+msgid "_Use Local Engine"
+msgstr "使用本地引擎(_U)"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:123
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:124
+msgid "_Add Remote Engine"
+msgstr "添加远程引擎(_A)"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:126
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:127
+msgid "Switch Remote Engine"
+msgstr "切换远程引擎"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:129
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:130
+msgid "_Caret Mode"
+msgstr "插入模式(_C)"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:132
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:133
+msgid "_Browse Mode"
+msgstr "浏览模式(_B)"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:138
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:139
+msgid "Show _Statusbar"
+msgstr "显示状态栏(_S)"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:141
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:142
+msgid "Show _Join Bar"
+msgstr "显示加入栏(_J)"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:144
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:145
+msgid "_Fullscreen"
+msgstr "全屏(_F)"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:147
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:148
+msgid "_About"
+msgstr "关于(_A)"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:153
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:155
+msgid "Find Group Chat"
+msgstr "查找群组聊天"
+
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:157
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs:158
+msgid "_Website"
+msgstr "网站(_W)"
+
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs:19
-msgid "Smuxi - Quick Connect"
-msgstr "Smuxi - 快速连接"
+msgid "Smuxi - Connect"
+msgstr "Smuxi - 连接"
 
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs:206
 msgid "Smuxi - Preferences"
@@ -980,8 +1058,7 @@ 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>"
+msgstr "<span size=\"small\">为连接启用 SSH。这对性能有一定影响,但更安全,且使用 NAT 或者基于端口的防火墙时必需</span>"
 
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantConnectionWidget.cs:135
 msgid "SSH _Host:"
@@ -1075,11 +1152,7 @@ msgid ""
 "You need to enter some information before you can use the engine.\n"
 "\n"
 "Click \"Forward\" to begin."
-msgstr ""
-"欢迎使用 Smuxi 引擎配置助手。\n"
-"在您能够使用引擎之前,需要输入一些信息。\n"
-"\n"
-"点击“前进”开始。"
+msgstr "欢迎使用 Smuxi 引擎配置助手。\n在您能够使用引擎之前,需要输入一些信息。\n\n点击“前进”开始。"
 
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs:36
 msgid "_Engine Name:"
@@ -1107,7 +1180,7 @@ msgstr "<span size=\"small\">如果启用,Smuxi 下次启动时当前引擎将
 msgid "Smuxi - Open Chat"
 msgstr "Smuxi - 开放聊天"
 
-#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:63
+#: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs:61
 msgid "_Type:"
 msgstr "_类型:"
 
@@ -1138,5 +1211,3 @@ msgstr "连接时命令(_O):"
 #: ../src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs:265
 msgid "_Ignore Commands"
 msgstr "忽略命令(_I)"
-
-
diff --git a/po-Frontend/POTFILES.skip b/po-Frontend/POTFILES.skip
index 74a7646..b7e421f 100644
--- a/po-Frontend/POTFILES.skip
+++ b/po-Frontend/POTFILES.skip
@@ -6,6 +6,7 @@ src/Frontend-STFL/
 src/Frontend-SWF/
 src/Frontend-WPF/
 src/Engine/
+src/Engine-Campfire/
 src/Engine-IRC/
 src/Engine-MSNP/
 src/Engine-OSCAR/
diff --git a/po-Frontend/da.po b/po-Frontend/da.po
index 880840c..f1f543a 100644
--- a/po-Frontend/da.po
+++ b/po-Frontend/da.po
@@ -3,26 +3,31 @@
 # This file is distributed under the same license as the PACKAGE package.
 # 
 # Translators:
-# Joe Hansen <joedalton2 at yahoo.dk>, 2011.
+# Joe Hansen <joedalton2 at yahoo.dk>, 2011,2013.
 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: 2011-12-29 20:06+0000\n"
+"POT-Creation-Date: 2013-04-14 10:18+0200\n"
+"PO-Revision-Date: 2013-04-16 06:17+0000\n"
 "Last-Translator: Joe Hansen <joedalton2 at yahoo.dk>\n"
-"Language-Team: Danish (http://www.transifex.net/projects/p/smuxi/team/da/)\n"
+"Language-Team: Danish (http://www.transifex.com/projects/p/smuxi/language/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"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: ../src/Frontend/CommandManager.cs:143
+#: ../src/Frontend/CommandManager.cs:255
 #, csharp-format
 msgid "Unknown Command: {0}"
 msgstr "Ukendt kommando: {0}"
 
+#: ../src/Frontend/CommandManager.cs:264
+#, csharp-format
+msgid "Not enough parameters for {0} command"
+msgstr "Ikke nok parametre for kommandoen {0}"
+
 #: ../src/Frontend/EngineManager.cs:122
 msgid "Engine must not be empty."
 msgstr "Motor må ikke være tom."
@@ -31,41 +36,35 @@ msgstr "Motor må ikke være tom."
 msgid "Engine does not exist."
 msgstr "Motor findes ikke."
 
-#: ../src/Frontend/EngineManager.cs:318
+#: ../src/Frontend/EngineManager.cs:317
 #, csharp-format
 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:327
+#: ../src/Frontend/EngineManager.cs:326
 msgid ""
 "Registration with engine failed!  The username and/or password were wrong - "
 "please verify them."
-msgstr ""
-"Registrering med motor mislykkedes! Brugernavnet og/eller adgangskoden var "
-"forkert - bekræft dem venligst."
+msgstr "Registrering med motor mislykkedes! Brugernavnet og/eller adgangskoden var forkert - bekræft dem venligst."
 
-#: ../src/Frontend/SshTunnelManager.cs:145
+#: ../src/Frontend/SshTunnelManager.cs:144
 msgid "SSH client application was not found: "
 msgstr "SSH-klientprogram blev ikke fundet: "
 
-#: ../src/Frontend/SshTunnelManager.cs:148
+#: ../src/Frontend/SshTunnelManager.cs:147
 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)"
+msgstr "SSH-klient skal enten være OpenSSH (ssh) eller Plink (plink.exe, ikke putty.exe)"
 
-#: ../src/Frontend/SshTunnelManager.cs:185
+#: ../src/Frontend/SshTunnelManager.cs:184
 #, 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?"
+msgstr "Den lokale SSH-videresendelsesport {0} er allerede i brug. Er der en gammel SSH-tunnel, der stadig er aktiv?"
 
-#: ../src/Frontend/SshTunnelManager.cs:209
+#: ../src/Frontend/SshTunnelManager.cs:208
 #, csharp-format
 msgid ""
 "SSH tunnel setup failed (exit code: {0})\n"
@@ -77,28 +76,19 @@ msgid ""
 "{3}\n"
 "Program Output:\n"
 "{4}\n"
-msgstr ""
-"Kunne ikke opsætte SSH-tunnel (afbrydelseskode: {0})\n"
-"\n"
-"SSH-program: {1}\n"
-"SSH-parametre: {2}\n"
-"\n"
-"Programfejl:\n"
-"{3}\n"
-"Programuddata:\n"
-"{4}\n"
+msgstr "Kunne ikke opsætte SSH-tunnel (afbrydelseskode: {0})\n\nSSH-program: {1}\nSSH-parametre: {2}\n\nProgramfejl:\n{3}\nProgramuddata:\n{4}\n"
 
-#: ../src/Frontend/SshTunnelManager.cs:330
-#: ../src/Frontend/SshTunnelManager.cs:476
+#: ../src/Frontend/SshTunnelManager.cs:329
+#: ../src/Frontend/SshTunnelManager.cs:475
 msgid "SSH keyfile not found."
 msgstr "SSH-nøglefil blev ikke fundet."
 
-#: ../src/Frontend/SshTunnelManager.cs:336
-#: ../src/Frontend/SshTunnelManager.cs:482
+#: ../src/Frontend/SshTunnelManager.cs:335
+#: ../src/Frontend/SshTunnelManager.cs:481
 msgid "SSH keyfile could not be read."
 msgstr "SSH-nøglefil kunne ikke læses."
 
-#: ../src/Frontend/SshTunnelManager.cs:424
+#: ../src/Frontend/SshTunnelManager.cs:423
 #, csharp-format
 msgid ""
 "OpenSSH version number not found (exit code: {0})\n"
@@ -109,21 +99,13 @@ msgid ""
 "{2}\n"
 "Program Output:\n"
 "{3}\n"
-msgstr ""
-"Versionnummer for OpenSSH blev ikke fundet (afbrydelseskode: {0})\n"
-"\n"
-"SSH-program: {1}\n"
-"\n"
-"Programfejl:\n"
-"{2}\n"
-"Programuddata:\n"
-"{3}\n"
+msgstr "Versionnummer for OpenSSH blev ikke fundet (afbrydelseskode: {0})\n\nSSH-program: {1}\n\nProgramfejl:\n{2}\nProgramuddata:\n{3}\n"
 
-#: ../src/Frontend/SshTunnelManager.cs:467
+#: ../src/Frontend/SshTunnelManager.cs:466
 msgid "PuTTY / Plink requires a username to be set."
 msgstr "PuTTY / Plink kræver at et brugernavn er angivet."
 
-#: ../src/Frontend/SshTunnelManager.cs:555
+#: ../src/Frontend/SshTunnelManager.cs:554
 #, csharp-format
 msgid ""
 "Plink version number not found (exit code: {0})\n"
@@ -134,14 +116,4 @@ msgid ""
 "{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"
-
-
+msgstr "Plink-versionsnummer blev ikke fundet (afslutningskode: {0})\n\nSSH-program: {1}\n\nProgramfejl:\n{2}\nProgramuddata:\n{3}\n"
diff --git a/po-Frontend/de.po b/po-Frontend/de.po
index a8de363..0d44a3c 100644
--- a/po-Frontend/de.po
+++ b/po-Frontend/de.po
@@ -3,26 +3,31 @@
 # This file is distributed under the same license as the PACKAGE package.
 # 
 # Translators:
-# Bianca Mix <heavydemon at freenet.de>, 2011.
+# Bianca Mix <heavydemon at freenet.de>, 2011,2013.
 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: 2011-12-30 23:04+0000\n"
+"POT-Creation-Date: 2013-04-14 10:18+0200\n"
+"PO-Revision-Date: 2013-04-14 19:28+0000\n"
 "Last-Translator: Bianca Mix <heavydemon at freenet.de>\n"
-"Language-Team: German (http://www.transifex.net/projects/p/smuxi/team/de/)\n"
+"Language-Team: German (http://www.transifex.com/projects/p/smuxi/language/de/)\n"
 "MIME-Version: 1.0\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"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: ../src/Frontend/CommandManager.cs:143
+#: ../src/Frontend/CommandManager.cs:255
 #, csharp-format
 msgid "Unknown Command: {0}"
 msgstr "Unbekannter Befehl: {0}"
 
+#: ../src/Frontend/CommandManager.cs:264
+#, csharp-format
+msgid "Not enough parameters for {0} command"
+msgstr "Nicht genügend Parameter für Kommando {0}"
+
 #: ../src/Frontend/EngineManager.cs:122
 msgid "Engine must not be empty."
 msgstr "Engine darf nicht leer sein."
@@ -31,43 +36,35 @@ msgstr "Engine darf nicht leer sein."
 msgid "Engine does not exist."
 msgstr "Engine existiert nicht."
 
-#: ../src/Frontend/EngineManager.cs:318
+#: ../src/Frontend/EngineManager.cs:317
 #, csharp-format
 msgid ""
 "Unknown channel ({0}) - only the following channel types are supported:"
-msgstr ""
-"Unbekannter Channel ({0}) - nur die folgenden Channel-Typen werden "
-"unterstützt:"
+msgstr "Unbekannter Channel ({0}) - nur die folgenden Channel-Typen werden unterstützt:"
 
-#: ../src/Frontend/EngineManager.cs:327
+#: ../src/Frontend/EngineManager.cs:326
 msgid ""
 "Registration with engine failed!  The username and/or password were wrong - "
 "please verify them."
-msgstr ""
-"Registierung gegenüber der Engine ist fehlgeschlagen. Benutzer und/oder "
-"Passwort ist falsch, bitte überprüfen Sie Ihre Eingabe."
+msgstr "Registierung gegenüber der Engine ist fehlgeschlagen. Benutzer und/oder Passwort ist falsch, bitte überprüfen Sie Ihre Eingabe."
 
-#: ../src/Frontend/SshTunnelManager.cs:145
+#: ../src/Frontend/SshTunnelManager.cs:144
 msgid "SSH client application was not found: "
 msgstr "SSH-Client-Programm wurde nicht gefunden: "
 
-#: ../src/Frontend/SshTunnelManager.cs:148
+#: ../src/Frontend/SshTunnelManager.cs:147
 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"
+msgstr "SSH-Client muss entweder OpenSSH (ssh) oder Plink (plink.exe, nicht putty.exe) sein"
 
-#: ../src/Frontend/SshTunnelManager.cs:185
+#: ../src/Frontend/SshTunnelManager.cs:184
 #, csharp-format
 msgid ""
 "The local SSH forwarding port {0} is already in use. Is there an old SSH "
 "tunnel still active?"
-msgstr ""
-"Der lokale SSH Weiterleitungs-Port {0} wird bereits verwendet. Ist noch ein "
-"alter SSH Tunnel aktiv?"
+msgstr "Der lokale SSH Weiterleitungs-Port {0} wird bereits verwendet. Ist noch ein alter SSH Tunnel aktiv?"
 
-#: ../src/Frontend/SshTunnelManager.cs:209
+#: ../src/Frontend/SshTunnelManager.cs:208
 #, csharp-format
 msgid ""
 "SSH tunnel setup failed (exit code: {0})\n"
@@ -79,28 +76,19 @@ msgid ""
 "{3}\n"
 "Program Output:\n"
 "{4}\n"
-msgstr ""
-"Aufbau des SSH-Tunnels ist fehlgeschlagen (Exit-Code: {0})\n"
-"\n"
-"SSH-Programm: {1}\n"
-"SSH-Parameter: {2}\n"
-"\n"
-"Programm-Fehler:\n"
-"{3}\n"
-"Programm-Ausgabe:\n"
-"{4}\n"
+msgstr "Aufbau des SSH-Tunnels ist fehlgeschlagen (Exit-Code: {0})\n\nSSH-Programm: {1}\nSSH-Parameter: {2}\n\nProgramm-Fehler:\n{3}\nProgramm-Ausgabe:\n{4}\n"
 
-#: ../src/Frontend/SshTunnelManager.cs:330
-#: ../src/Frontend/SshTunnelManager.cs:476
+#: ../src/Frontend/SshTunnelManager.cs:329
+#: ../src/Frontend/SshTunnelManager.cs:475
 msgid "SSH keyfile not found."
 msgstr "SSH Schlüssel-Datei nicht gefunden."
 
-#: ../src/Frontend/SshTunnelManager.cs:336
-#: ../src/Frontend/SshTunnelManager.cs:482
+#: ../src/Frontend/SshTunnelManager.cs:335
+#: ../src/Frontend/SshTunnelManager.cs:481
 msgid "SSH keyfile could not be read."
 msgstr "SSH Schlüssel-Datei konnte nicht gelesen werden."
 
-#: ../src/Frontend/SshTunnelManager.cs:424
+#: ../src/Frontend/SshTunnelManager.cs:423
 #, csharp-format
 msgid ""
 "OpenSSH version number not found (exit code: {0})\n"
@@ -111,21 +99,13 @@ msgid ""
 "{2}\n"
 "Program Output:\n"
 "{3}\n"
-msgstr ""
-"OpenSSH-Version konnte nicht ermittelt werden (Exit-Code: {0})\n"
-"\n"
-"SSH-Programm: {1}\n"
-"\n"
-"Programm-Fehler:\n"
-"{2}\n"
-"Programm-Ausgabe:\n"
-"{3}\n"
+msgstr "OpenSSH-Version konnte nicht ermittelt werden (Exit-Code: {0})\n\nSSH-Programm: {1}\n\nProgramm-Fehler:\n{2}\nProgramm-Ausgabe:\n{3}\n"
 
-#: ../src/Frontend/SshTunnelManager.cs:467
+#: ../src/Frontend/SshTunnelManager.cs:466
 msgid "PuTTY / Plink requires a username to be set."
 msgstr "PuTTY / Plink fordert einen gesetzten Benutzernamen."
 
-#: ../src/Frontend/SshTunnelManager.cs:555
+#: ../src/Frontend/SshTunnelManager.cs:554
 #, csharp-format
 msgid ""
 "Plink version number not found (exit code: {0})\n"
@@ -136,14 +116,4 @@ msgid ""
 "{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"
-
-
+msgstr "Plink Versionsnummer nicht gefunden (Rückgabewert: {0})\n\nSSH Programm: {1}\n\nProgramm Fehler:\n{2}\nProgramm Ausgabe:\n{3}\n"
diff --git a/po-Frontend/fr.po b/po-Frontend/fr.po
index 4c0ef91..261d79e 100644
--- a/po-Frontend/fr.po
+++ b/po-Frontend/fr.po
@@ -1,28 +1,33 @@
 # 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 - 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"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-04-10 21:41+0200\n"
+"PO-Revision-Date: 2013-04-10 22:38+0100\n"
 "Last-Translator: Clément Bourgeois <moonpyk at gmail.com>\n"
 "Language-Team: French (http://www.transifex.net/projects/p/smuxi/team/fr/)\n"
+"Language: 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:143
+#: ../src/Frontend/CommandManager.cs:255
 #, csharp-format
 msgid "Unknown Command: {0}"
 msgstr "Commande inconnue : {0}"
 
+#: ../src/Frontend/CommandManager.cs:264
+#, csharp-format
+msgid "Not enough parameters for {0} command"
+msgstr "Pas assez de paramètres pour la commande {0}"
+
 #: ../src/Frontend/EngineManager.cs:122
 msgid "Engine must not be empty."
 msgstr "Le moteur ne doit pas être vide."
@@ -31,14 +36,13 @@ msgstr "Le moteur ne doit pas être vide."
 msgid "Engine does not exist."
 msgstr "Le moteur n'existe pas."
 
-#: ../src/Frontend/EngineManager.cs:318
+#: ../src/Frontend/EngineManager.cs:317
 #, 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:327
+#: ../src/Frontend/EngineManager.cs:326
 msgid ""
 "Registration with engine failed!  The username and/or password were wrong - "
 "please verify them."
@@ -46,18 +50,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:145
+#: ../src/Frontend/SshTunnelManager.cs:144
 msgid "SSH client application was not found: "
 msgstr "L'application SSH client n'a pas été trouvée :"
 
-#: ../src/Frontend/SshTunnelManager.cs:148
+#: ../src/Frontend/SshTunnelManager.cs:147
 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:185
+#: ../src/Frontend/SshTunnelManager.cs:184
 #, csharp-format
 msgid ""
 "The local SSH forwarding port {0} is already in use. Is there an old SSH "
@@ -66,7 +70,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:209
+#: ../src/Frontend/SshTunnelManager.cs:208
 #, csharp-format
 msgid ""
 "SSH tunnel setup failed (exit code: {0})\n"
@@ -89,17 +93,17 @@ msgstr ""
 "Sortie du programme :\n"
 "{4}\n"
 
-#: ../src/Frontend/SshTunnelManager.cs:330
-#: ../src/Frontend/SshTunnelManager.cs:476
+#: ../src/Frontend/SshTunnelManager.cs:329
+#: ../src/Frontend/SshTunnelManager.cs:475
 msgid "SSH keyfile not found."
 msgstr "Fichier de clé SSH introuvable"
 
-#: ../src/Frontend/SshTunnelManager.cs:336
-#: ../src/Frontend/SshTunnelManager.cs:482
+#: ../src/Frontend/SshTunnelManager.cs:335
+#: ../src/Frontend/SshTunnelManager.cs:481
 msgid "SSH keyfile could not be read."
 msgstr "Impossible de lire le fichier de clé SSH."
 
-#: ../src/Frontend/SshTunnelManager.cs:424
+#: ../src/Frontend/SshTunnelManager.cs:423
 #, csharp-format
 msgid ""
 "OpenSSH version number not found (exit code: {0})\n"
@@ -120,11 +124,11 @@ msgstr ""
 "Sortie du programme:\n"
 "{3}\n"
 
-#: ../src/Frontend/SshTunnelManager.cs:467
+#: ../src/Frontend/SshTunnelManager.cs:466
 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
+#: ../src/Frontend/SshTunnelManager.cs:554
 #, csharp-format
 msgid ""
 "Plink version number not found (exit code: {0})\n"
@@ -144,5 +148,3 @@ msgstr ""
 "{2}\n"
 "Sortie du programme : \n"
 "{3}\n"
-
-
diff --git a/po-Frontend/sv.po b/po-Frontend/sv.po
index e715ea2..07a13c1 100644
--- a/po-Frontend/sv.po
+++ b/po-Frontend/sv.po
@@ -3,26 +3,32 @@
 # This file is distributed under the same license as the PACKAGE package.
 # 
 # Translators:
-#   <flugsio at gmail.com>, 2011.
+# flugsio <flugsio at gmail.com>, 2013
+# flugsio <flugsio 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:21+0100\n"
-"PO-Revision-Date: 2011-12-31 10:56+0000\n"
+"POT-Creation-Date: 2013-04-14 10:18+0200\n"
+"PO-Revision-Date: 2013-04-17 04:21+0000\n"
 "Last-Translator: flugsio <flugsio at gmail.com>\n"
-"Language-Team: Swedish (http://www.transifex.net/projects/p/smuxi/team/sv/)\n"
+"Language-Team: Swedish (http://www.transifex.com/projects/p/smuxi/language/sv/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Language: sv\n"
-"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: ../src/Frontend/CommandManager.cs:143
+#: ../src/Frontend/CommandManager.cs:255
 #, csharp-format
 msgid "Unknown Command: {0}"
 msgstr "Okänt kommando: {0}"
 
+#: ../src/Frontend/CommandManager.cs:264
+#, csharp-format
+msgid "Not enough parameters for {0} command"
+msgstr "Inte tillräckligt med parametrar för kommandot {0}"
+
 #: ../src/Frontend/EngineManager.cs:122
 msgid "Engine must not be empty."
 msgstr "Motor får inte lämnas tom."
@@ -31,41 +37,35 @@ msgstr "Motor får inte lämnas tom."
 msgid "Engine does not exist."
 msgstr "Vald motor finns inte."
 
-#: ../src/Frontend/EngineManager.cs:318
+#: ../src/Frontend/EngineManager.cs:317
 #, csharp-format
 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:327
+#: ../src/Frontend/EngineManager.cs:326
 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."
+msgstr "Kunde inte ansluta till motorn! Användarnamnet och/eller lösenordet var fel - kontrollera dessa."
 
-#: ../src/Frontend/SshTunnelManager.cs:145
+#: ../src/Frontend/SshTunnelManager.cs:144
 msgid "SSH client application was not found: "
 msgstr "SSH-klient-applikationen kunde inte hittas:"
 
-#: ../src/Frontend/SshTunnelManager.cs:148
+#: ../src/Frontend/SshTunnelManager.cs:147
 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)"
+msgstr "SSH-klienten måste vara antingen OpenSSH (ssh) eller Plink (plink.exe, inte putty.exe)"
 
-#: ../src/Frontend/SshTunnelManager.cs:185
+#: ../src/Frontend/SshTunnelManager.cs:184
 #, 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?"
+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:209
+#: ../src/Frontend/SshTunnelManager.cs:208
 #, csharp-format
 msgid ""
 "SSH tunnel setup failed (exit code: {0})\n"
@@ -77,28 +77,19 @@ msgid ""
 "{3}\n"
 "Program Output:\n"
 "{4}\n"
-msgstr ""
-"Fel vid upprättande av SSH-tunnel (felkod: {0})\n"
-"\n"
-"SSH-applikation: {1}\n"
-"SSH-parameterar: {2}\n"
-"\n"
-"Applikationsfel:\n"
-"{3}\n"
-"Utdata från applikation:\n"
-"{4}\n"
+msgstr "Fel vid upprättande av SSH-tunnel (felkod: {0})\n\nSSH-applikation: {1}\nSSH-parameterar: {2}\n\nApplikationsfel:\n{3}\nUtdata från applikation:\n{4}\n"
 
-#: ../src/Frontend/SshTunnelManager.cs:330
-#: ../src/Frontend/SshTunnelManager.cs:476
+#: ../src/Frontend/SshTunnelManager.cs:329
+#: ../src/Frontend/SshTunnelManager.cs:475
 msgid "SSH keyfile not found."
 msgstr "SSH-nyckelfil hittades inte."
 
-#: ../src/Frontend/SshTunnelManager.cs:336
-#: ../src/Frontend/SshTunnelManager.cs:482
+#: ../src/Frontend/SshTunnelManager.cs:335
+#: ../src/Frontend/SshTunnelManager.cs:481
 msgid "SSH keyfile could not be read."
 msgstr "SSH-nyckelfilen kunde inte läsas."
 
-#: ../src/Frontend/SshTunnelManager.cs:424
+#: ../src/Frontend/SshTunnelManager.cs:423
 #, csharp-format
 msgid ""
 "OpenSSH version number not found (exit code: {0})\n"
@@ -109,21 +100,13 @@ msgid ""
 "{2}\n"
 "Program Output:\n"
 "{3}\n"
-msgstr ""
-"Versionsnummer för OpenSSH kunde inte hittas (felkod: {0})\n"
-"\n"
-"SSH-applikation: {1}\n"
-"\n"
-"Applikationsfel:\n"
-"{2}\n"
-"Utdata från applikation:\n"
-"{3}\n"
+msgstr "Versionsnummer för OpenSSH kunde inte hittas (felkod: {0})\n\nSSH-applikation: {1}\n\nApplikationsfel:\n{2}\nUtdata från applikation:\n{3}\n"
 
-#: ../src/Frontend/SshTunnelManager.cs:467
+#: ../src/Frontend/SshTunnelManager.cs:466
 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
+#: ../src/Frontend/SshTunnelManager.cs:554
 #, csharp-format
 msgid ""
 "Plink version number not found (exit code: {0})\n"
@@ -134,14 +117,4 @@ msgid ""
 "{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"
-
-
+msgstr "Plink versions-nummer hittades inte (avslutningskod: {0})\n\nSSH program: {1}\n\nProgramfel:\n{2}\nProgramutdata:\n{3}\n"
diff --git a/po-Frontend/zh_CN.po b/po-Frontend/zh_CN.po
index 1b9d0c2..f281ad2 100644
--- a/po-Frontend/zh_CN.po
+++ b/po-Frontend/zh_CN.po
@@ -3,26 +3,31 @@
 # This file is distributed under the same license as the PACKAGE package.
 # 
 # Translators:
-# Dean Lee <xslidian at gmail.com>, 2012.
+# Dean Lee <xslidian at gmail.com>, 2012-2013.
 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: 2012-01-07 10:01+0000\n"
+"POT-Creation-Date: 2013-04-14 10:18+0200\n"
+"PO-Revision-Date: 2013-04-14 14:00+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"
+"Language-Team: Chinese (China) (http://www.transifex.com/projects/p/smuxi/language/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"
+"Plural-Forms: nplurals=1; plural=0;\n"
 
-#: ../src/Frontend/CommandManager.cs:143
+#: ../src/Frontend/CommandManager.cs:255
 #, csharp-format
 msgid "Unknown Command: {0}"
 msgstr "未知命令: {0}"
 
+#: ../src/Frontend/CommandManager.cs:264
+#, csharp-format
+msgid "Not enough parameters for {0} command"
+msgstr "{0} 命令参数不足"
+
 #: ../src/Frontend/EngineManager.cs:122
 msgid "Engine must not be empty."
 msgstr "引擎不能为空。"
@@ -31,35 +36,35 @@ msgstr "引擎不能为空。"
 msgid "Engine does not exist."
 msgstr "引擎不存在。"
 
-#: ../src/Frontend/EngineManager.cs:318
+#: ../src/Frontend/EngineManager.cs:317
 #, csharp-format
 msgid ""
 "Unknown channel ({0}) - only the following channel types are supported:"
 msgstr "未知频道 ({0}) - 仅支持下列频道类型:"
 
-#: ../src/Frontend/EngineManager.cs:327
+#: ../src/Frontend/EngineManager.cs:326
 msgid ""
 "Registration with engine failed!  The username and/or password were wrong - "
 "please verify them."
 msgstr "引擎注册失败!  用户名和/或密码错误 - 请验证。"
 
-#: ../src/Frontend/SshTunnelManager.cs:145
+#: ../src/Frontend/SshTunnelManager.cs:144
 msgid "SSH client application was not found: "
 msgstr "未找到 SSH 客户端应用程序: "
 
-#: ../src/Frontend/SshTunnelManager.cs:148
+#: ../src/Frontend/SshTunnelManager.cs:147
 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
+#: ../src/Frontend/SshTunnelManager.cs:184
 #, 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
+#: ../src/Frontend/SshTunnelManager.cs:208
 #, csharp-format
 msgid ""
 "SSH tunnel setup failed (exit code: {0})\n"
@@ -71,28 +76,19 @@ msgid ""
 "{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"
+msgstr "SSH 隧道安装失败 (退出代码: {0})\n\nSSH 程序: {1}\nSSH 参数: {2}\n\n程序错误:\n{3}\n程序输出:\n{4}\n"
 
-#: ../src/Frontend/SshTunnelManager.cs:330
-#: ../src/Frontend/SshTunnelManager.cs:476
+#: ../src/Frontend/SshTunnelManager.cs:329
+#: ../src/Frontend/SshTunnelManager.cs:475
 msgid "SSH keyfile not found."
 msgstr "未找到 SSH 密钥文件。"
 
-#: ../src/Frontend/SshTunnelManager.cs:336
-#: ../src/Frontend/SshTunnelManager.cs:482
+#: ../src/Frontend/SshTunnelManager.cs:335
+#: ../src/Frontend/SshTunnelManager.cs:481
 msgid "SSH keyfile could not be read."
 msgstr "无法读取 SSH 密钥文件。"
 
-#: ../src/Frontend/SshTunnelManager.cs:424
+#: ../src/Frontend/SshTunnelManager.cs:423
 #, csharp-format
 msgid ""
 "OpenSSH version number not found (exit code: {0})\n"
@@ -103,21 +99,13 @@ msgid ""
 "{2}\n"
 "Program Output:\n"
 "{3}\n"
-msgstr ""
-"未发现 OpenSSH 版本号 (退出代码: {0})\n"
-"\n"
-"SSH 程序: {1}\n"
-"\n"
-"程序错误:\n"
-"{2}\n"
-"程序输出:\n"
-"{3}\n"
+msgstr "未发现 OpenSSH 版本号 (退出代码: {0})\n\nSSH 程序: {1}\n\n程序错误:\n{2}\n程序输出:\n{3}\n"
 
-#: ../src/Frontend/SshTunnelManager.cs:467
+#: ../src/Frontend/SshTunnelManager.cs:466
 msgid "PuTTY / Plink requires a username to be set."
 msgstr "PuTTY / Plink 需要设置用户名。"
 
-#: ../src/Frontend/SshTunnelManager.cs:555
+#: ../src/Frontend/SshTunnelManager.cs:554
 #, csharp-format
 msgid ""
 "Plink version number not found (exit code: {0})\n"
@@ -128,14 +116,4 @@ msgid ""
 "{2}\n"
 "Program Output:\n"
 "{3}\n"
-msgstr ""
-"Plink 版本号未找到 (退出代码: {0})\n"
-"\n"
-"SSH 程序: {1}\n"
-"\n"
-"程序错误:\n"
-"{2}\n"
-"程序输出:\n"
-"{3}\n"
-
-
+msgstr "Plink 版本号未找到 (退出代码: {0})\n\nSSH 程序: {1}\n\n程序错误:\n{2}\n程序输出:\n{3}\n"
diff --git a/po-Server/POTFILES.skip b/po-Server/POTFILES.skip
index 47eecc2..66cc22d 100644
--- a/po-Server/POTFILES.skip
+++ b/po-Server/POTFILES.skip
@@ -1,6 +1,7 @@
 glade/
 src/Common/
 src/Engine/
+src/Engine-Campfire/
 src/Engine-IRC/
 src/Engine-MSNP/
 src/Engine-OSCAR/
diff --git a/po-Server/fr.po b/po-Server/fr.po
index 6fd8ea5..adb8215 100644
--- a/po-Server/fr.po
+++ b/po-Server/fr.po
@@ -1,21 +1,21 @@
 # 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 - IRC client\n"
-"Report-Msgid-Bugs-To: http://www.smuxi.org/issues\n"
-"POT-Creation-Date: 2011-12-29 09:21+0100\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-04-10 21:39+0200\n"
 "PO-Revision-Date: 2011-12-30 23:04+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"
+"Language: 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/Server/Main.cs:71
@@ -41,8 +41,7 @@ msgstr "Utilisateur à créer, modifier ou supprimer"
 #: ../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:125
 msgid "Enable debug output"
@@ -79,8 +78,8 @@ msgstr "Erreur de ligne de commande : {0}"
 
 #: ../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."
@@ -104,8 +103,8 @@ msgstr "Le mot de passe ne peut pas être vide."
 #: ../src/Server/Main.cs:283
 #, csharp-format
 msgid ""
-"Invalid optimization value passed to --optimize-message-buffer, valid values"
-" are: {0}"
+"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}"
@@ -123,7 +122,8 @@ msgstr "L'utilisateur \"{0}\" a été modifié avec succès."
 #: ../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:328
 msgid "Users:"
@@ -138,5 +138,3 @@ msgstr "Optimisation des tampons de messages {0} réalisée avec succès."
 #, csharp-format
 msgid "Failed to optimize message buffers: {0}"
 msgstr "Impossible d'optimiser les tampon de messages : {0}"
-
-
diff --git a/src/AssemblyVersion.cs b/src/AssemblyVersion.cs
index b6ca745..18ee3ea 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.10.2")]
+[assembly: AssemblyVersion("0.8.11")]
 
diff --git a/src/Common/Crc32.cs b/src/Common/Crc32.cs
index 93c3e13..a1c2f2d 100644
--- a/src/Common/Crc32.cs
+++ b/src/Common/Crc32.cs
@@ -107,7 +107,7 @@ namespace Smuxi.Common
         }
         public uint CrcValue {
             get {
-                return (uint)((HashValue[0] << 24) | (HashValue[1] << 16) | (HashValue[2] << 8) | HashValue[3]);
+                return (uint)(((uint)HashValue[0] << 24) | (HashValue[1] << 16) | (HashValue[2] << 8) | HashValue[3]);
             }
         }
         public override int HashSize {
diff --git a/src/Common/Defines.cs b/src/Common/Defines.cs
index 80dbfa0..edd727d 100644
--- a/src/Common/Defines.cs
+++ b/src/Common/Defines.cs
@@ -26,11 +26,11 @@ namespace Smuxi.Common
 {
     public static class Defines
     {
-        public const string GitBranch   = "stable";
-        public const string GitCommitHash = "eacbbd5";
+        public const string GitBranch   = "";
+        public const string GitCommitHash = "";
 
         private static readonly string f_InstallPrefix = "/usr/local";
-        private static readonly string f_DistVersion = "stable/eacbbd5";
+        private static readonly string f_DistVersion = "dist-osx";
         private static readonly string f_TwitterApiKey = "60QV2qQx9cS7y1BJDbgAA|2VgD6qQKddsF5HYQ0TrRgs3tFTnCwDONBmRlTmG658";
 
         public static string InstallPrefix {
diff --git a/src/Common/Makefile.am b/src/Common/Makefile.am
index c073d02..359adfb 100644
--- a/src/Common/Makefile.am
+++ b/src/Common/Makefile.am
@@ -58,6 +58,7 @@ FILES = \
 	LibraryCatalog.cs \
 	NDesk.Options.cs \
 	Defines.cs \
+	SpecialFolderPatternConverter.cs \
 	TaskQueue.cs \
 	ThreadPoolQueue.cs \
 	Platform.cs \
diff --git a/src/Common/Makefile.in b/src/Common/Makefile.in
index 4cd9beb..1b8862a 100644
--- a/src/Common/Makefile.in
+++ b/src/Common/Makefile.in
@@ -58,8 +58,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
@@ -150,9 +153,8 @@ 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_CAMPFIRE = @GETTEXT_PACKAGE_ENGINE_CAMPFIRE@
 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@
@@ -164,6 +166,9 @@ 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@
+GIO_SHARP_CFLAGS = @GIO_SHARP_CFLAGS@
+GIO_SHARP_FILES = @GIO_SHARP_FILES@
+GIO_SHARP_LIBS = @GIO_SHARP_LIBS@
 GLADE_SHARP_20_CFLAGS = @GLADE_SHARP_20_CFLAGS@
 GLADE_SHARP_20_LIBS = @GLADE_SHARP_20_LIBS@
 GLIB_SHARP_20_CFLAGS = @GLIB_SHARP_20_CFLAGS@
@@ -210,6 +215,11 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
+MESSAGINGMENU_SHARP_CFLAGS = @MESSAGINGMENU_SHARP_CFLAGS@
+MESSAGINGMENU_SHARP_FILES = @MESSAGINGMENU_SHARP_FILES@
+MESSAGINGMENU_SHARP_LIBS = @MESSAGINGMENU_SHARP_LIBS@
+MESSAGING_MENU_CFLAGS = @MESSAGING_MENU_CFLAGS@
+MESSAGING_MENU_LIBS = @MESSAGING_MENU_LIBS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
 MONO_MODULE_CFLAGS = @MONO_MODULE_CFLAGS@
@@ -217,8 +227,6 @@ 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@
@@ -231,8 +239,6 @@ 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@
@@ -368,6 +374,7 @@ FILES = \
 	LibraryCatalog.cs \
 	NDesk.Options.cs \
 	Defines.cs \
+	SpecialFolderPatternConverter.cs \
 	TaskQueue.cs \
 	ThreadPoolQueue.cs \
 	Platform.cs \
diff --git a/src/Common/Platform.cs b/src/Common/Platform.cs
index 6053c85..9574652 100644
--- a/src/Common/Platform.cs
+++ b/src/Common/Platform.cs
@@ -44,6 +44,7 @@ namespace Smuxi.Common
                 string os = null;
                 // GNU/Linux
                 // GNU/kFreeBSD
+                // Cygwin
                 var info = new ProcessStartInfo("uname", "-o");
                 info.UseShellExecute = false;
                 info.RedirectStandardOutput = true;
@@ -51,6 +52,11 @@ namespace Smuxi.Common
                 process.WaitForExit();
                 if (process.ExitCode == 0) {
                     os = process.StandardOutput.ReadLine();
+                    // HACK: if Cygwin was installed on Windows and is in PATH
+                    // we should not trust uname and ask the runtime instead
+                    if (os == "Cygwin") {
+                        return Environment.OSVersion.Platform.ToString();
+                    }
                 }
 
                 if (String.IsNullOrEmpty(os)) {
diff --git a/src/Common/SpecialFolderPatternConverter.cs b/src/Common/SpecialFolderPatternConverter.cs
new file mode 100644
index 0000000..733b271
--- /dev/null
+++ b/src/Common/SpecialFolderPatternConverter.cs
@@ -0,0 +1,38 @@
+// Smuxi - Smart MUltipleXed Irc
+//
+// Copyright (c) 2012 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;
+
+#if LOG4NET
+namespace Smuxi.Common
+{
+    public class SpecialFolderPatternConverter : log4net.Util.PatternConverter
+    {
+        protected override void Convert(TextWriter writer, object state)
+        {
+            var specialFolder = (Environment.SpecialFolder) Enum.Parse(
+                typeof(Environment.SpecialFolder), Option, true
+            );
+            writer.Write(Environment.GetFolderPath(specialFolder));
+        }
+    }
+}
+#endif
\ No newline at end of file
diff --git a/src/Engine-Campfire/AssemblyInfo.cs b/src/Engine-Campfire/AssemblyInfo.cs
new file mode 100644
index 0000000..a526cc6
--- /dev/null
+++ b/src/Engine-Campfire/AssemblyInfo.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Smuxi - Campfire support for engine")]
+[assembly: AssemblyCopyright("2012 © Carlos Martín Nieto <cmn at dwim.me>")]
+
+[assembly: AssemblyDelaySign(false)]
+[assembly: AssemblyKeyFile("")]
+
+[assembly: CLSCompliant(true)]
+[assembly: ComVisible(false)]
diff --git a/src/Engine-Campfire/Makefile.am b/src/Engine-Campfire/Makefile.am
new file mode 100644
index 0000000..1398aa1
--- /dev/null
+++ b/src/Engine-Campfire/Makefile.am
@@ -0,0 +1,40 @@
+TARGET_DIR = $(top_builddir)/bin/$(PROFILE)
+ASSEMBLY_NAME = smuxi-engine-campfire
+ASSEMBLY_FILENAME = $(ASSEMBLY_NAME).dll
+ASSEMBLY_TARGET = $(TARGET_DIR)/$(ASSEMBLY_FILENAME)
+
+SOURCES = \
+	$(top_srcdir)/src/AssemblyVersion.cs \
+	AssemblyInfo.cs \
+	Protocols/Campfire/CampfireProtocolManager.cs \
+	Protocols/Campfire/CampfirePersonModel.cs \
+	Protocols/Campfire/CampfireEventStream.cs \
+	Protocols/Campfire/DTO.cs
+
+REFERENCES = \
+	System \
+	System.Web \
+	Mono.Posix \
+	$(LOG4NET_LIBS)
+
+DLL_REFERENCES = \
+	$(TARGET_DIR)/smuxi-common.dll \
+	$(TARGET_DIR)/smuxi-engine.dll \
+	$(TARGET_DIR)/ServiceStack.Common.dll \
+	$(TARGET_DIR)/ServiceStack.Interfaces.dll \
+	$(TARGET_DIR)/ServiceStack.Text.dll
+
+SOURCES_BUILD = $(addprefix $(srcdir)/, $(SOURCES))
+
+# automake magic variables
+EXTRA_DIST = $(SOURCES_BUILD)
+CLEANFILES = $(ASSEMBLY_TARGET) $(ASSEMBLY_TARGET).mdb
+
+pkgapp_DATA = $(ASSEMBLY_TARGET) $(ASSEMBLY_TARGET).mdb
+
+include $(top_srcdir)/Makefile.include
+
+all: $(ASSEMBLY_TARGET)
+
+$(ASSEMBLY_TARGET) $(ASSEMBLY_TARGET).mdb: $(SOURCES) $(DLL_REFERENCES)
+	$(CSC) $(CSC_FLAGS) $(build_references_ref) -target:library -out:$@ $(SOURCES_BUILD)
diff --git a/src/Engine-Campfire/Makefile.in b/src/Engine-Campfire/Makefile.in
new file mode 100644
index 0000000..9e28d8a
--- /dev/null
+++ b/src/Engine-Campfire/Makefile.in
@@ -0,0 +1,835 @@
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@
+am__make_dryrun = \
+  { \
+    am__dry=no; \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        echo 'am--echo: ; @echo "AM"  OK' | $(MAKE) -f - 2>/dev/null \
+          | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+      *) \
+        for am__flg in $$MAKEFLAGS; do \
+          case $$am__flg in \
+            *=*|--*) ;; \
+            *n*) am__dry=yes; break;; \
+          esac; \
+        done;; \
+    esac; \
+    test $$am__dry = yes; \
+  }
+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@
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+	$(top_srcdir)/Makefile.include
+subdir = src/Engine-Campfire
+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 =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgappdir)" \
+	"$(DESTDIR)$(linuxdesktopapplicationsdir)" \
+	"$(DESTDIR)$(linuxpkgconfigdir)" "$(DESTDIR)$(pkgappdir)" \
+	"$(DESTDIR)$(programfilesdir)" \
+	"$(DESTDIR)$(programfilesiconsdir)"
+SCRIPTS = $(bin_SCRIPTS) $(pkgapp_SCRIPTS)
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+DATA = $(linuxdesktopapplications_DATA) $(linuxpkgconfig_DATA) \
+	$(pkgapp_DATA) $(programfiles_DATA) $(programfilesicons_DATA)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+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_CAMPFIRE = @GETTEXT_PACKAGE_ENGINE_CAMPFIRE@
+GETTEXT_PACKAGE_ENGINE_IRC = @GETTEXT_PACKAGE_ENGINE_IRC@
+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@
+GIO_SHARP_CFLAGS = @GIO_SHARP_CFLAGS@
+GIO_SHARP_FILES = @GIO_SHARP_FILES@
+GIO_SHARP_LIBS = @GIO_SHARP_LIBS@
+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@
+GTKSPELL_CFLAGS = @GTKSPELL_CFLAGS@
+GTKSPELL_LIBS = @GTKSPELL_LIBS@
+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@
+INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
+INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
+INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
+INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
+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@
+MESSAGINGMENU_SHARP_CFLAGS = @MESSAGINGMENU_SHARP_CFLAGS@
+MESSAGINGMENU_SHARP_FILES = @MESSAGINGMENU_SHARP_FILES@
+MESSAGINGMENU_SHARP_LIBS = @MESSAGINGMENU_SHARP_LIBS@
+MESSAGING_MENU_CFLAGS = @MESSAGING_MENU_CFLAGS@
+MESSAGING_MENU_LIBS = @MESSAGING_MENU_LIBS@
+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@
+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@
+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@
+intltool__v_merge_options_ = @intltool__v_merge_options_@
+intltool__v_merge_options_0 = @intltool__v_merge_options_0@
+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@
+TARGET_DIR = $(top_builddir)/bin/$(PROFILE)
+ASSEMBLY_NAME = smuxi-engine-campfire
+ASSEMBLY_FILENAME = $(ASSEMBLY_NAME).dll
+ASSEMBLY_TARGET = $(TARGET_DIR)/$(ASSEMBLY_FILENAME)
+SOURCES = \
+	$(top_srcdir)/src/AssemblyVersion.cs \
+	AssemblyInfo.cs \
+	Protocols/Campfire/CampfireProtocolManager.cs \
+	Protocols/Campfire/CampfirePersonModel.cs \
+	Protocols/Campfire/CampfireEventStream.cs \
+	Protocols/Campfire/DTO.cs
+
+REFERENCES = \
+	System \
+	System.Web \
+	Mono.Posix \
+	$(LOG4NET_LIBS)
+
+DLL_REFERENCES = \
+	$(TARGET_DIR)/smuxi-common.dll \
+	$(TARGET_DIR)/smuxi-engine.dll \
+	$(TARGET_DIR)/ServiceStack.Common.dll \
+	$(TARGET_DIR)/ServiceStack.Interfaces.dll \
+	$(TARGET_DIR)/ServiceStack.Text.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)
+pkgapp_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)/%')
+comma__ = ,
+get_resource_name = $(firstword $(subst $(comma__), ,$1))
+get_culture = $(lastword $(subst ., ,$(basename $1)))
+is_cultured_resource = $(and $(word 3,$(subst ., ,$1)), $(filter $(VALID_CULTURES),$(lastword $(subst ., ,$(basename $1)))))
+build_resx_list = $(foreach res, $(RESOURCES), $(if $(filter %.resx, $(call get_resource_name,$(res))),$(res),))
+build_non_culture_resx_list = $(foreach res, $(build_resx_list),$(if $(call is_cultured_resource,$(call get_resource_name,$(res))),,$(res)))
+build_non_culture_others_list = $(foreach res, $(filter-out $(build_resx_list),$(RESOURCES)),$(if $(call is_cultured_resource,$(call get_resource_name,$(res))),,$(res)))
+build_others_list = $(build_non_culture_others_list)
+build_xamlg_list = $(filter %.xaml.g.cs, $(FILES))
+
+# resgen all .resx resources
+build_resx_files = $(foreach res, $(build_resx_list), $(call get_resource_name,$(res)))
+build_resx_resources = $(build_resx_files:.resx=.resources)
+
+# embed resources for the main assembly
+build_resx_resources_hack = $(subst .resx,.resources, $(build_non_culture_resx_list))
+build_resx_resources_embed = $(build_resx_resources_hack:%='-resource:%')
+build_others_files = $(foreach res, $(build_others_list),$(call get_resource_name,$(res)))
+build_others_resources = $(build_others_files)
+build_others_resources_embed = $(build_others_list:%='-resource:$(srcdir)/%')
+build_resources = $(build_resx_resources) $(build_others_resources)
+build_resources_embed = $(build_resx_resources_embed) $(build_others_resources_embed)
+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)
+pkgappdir = $(pkglibdir)
+pkgapp_SCRIPTS = $(ASSEMBLY)
+bin_SCRIPTS = $(BINARIES)
+programfilesdir = @libdir@/@PACKAGE@
+programfiles_DATA = $(PROGRAMFILES)
+programfilesiconsdir = @libdir@/@PACKAGE@/icons
+programfilesicons_DATA = $(PROGRAMFILES_ICONS)
+linuxpkgconfigdir = @libdir@/pkgconfig
+linuxpkgconfig_DATA = $(LINUX_PKGCONFIG)
+linuxdesktopapplicationsdir = @prefix@/share/applications
+linuxdesktopapplications_DATA = $(LINUX_DESKTOPAPPLICATIONS)
+
+# generating satellite assemblies
+culture_resources = $(foreach res, $(RESOURCES), $(if $(call is_cultured_resource,$(call get_resource_name, $(res))),$(res)))
+cultures = $(sort $(foreach res, $(culture_resources), $(call get_culture,$(call get_resource_name,$(res)))))
+culture_resource_dependencies = $(BUILD_DIR)/$1/$(SATELLITE_ASSEMBLY_NAME): $(subst .resx,.resources,$2)
+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)))
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/Makefile.include $(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/Engine-Campfire/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign src/Engine-Campfire/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_srcdir)/Makefile.include:
+
+$(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):
+install-binSCRIPTS: $(bin_SCRIPTS)
+	@$(NORMAL_INSTALL)
+	@list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
+	done | \
+	sed -e 'p;s,.*/,,;n' \
+	    -e 'h;s|.*|.|' \
+	    -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
+	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
+	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+	    if ($$2 == $$4) { files[d] = files[d] " " $$1; \
+	      if (++n[d] == $(am__install_max)) { \
+		print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
+	    else { print "f", d "/" $$4, $$1 } } \
+	  END { for (d in files) print "f", d, files[d] }' | \
+	while read type dir files; do \
+	     if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+	     test -z "$$files" || { \
+	       echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+	       $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+	     } \
+	; done
+
+uninstall-binSCRIPTS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \
+	files=`for p in $$list; do echo "$$p"; done | \
+	       sed -e 's,.*/,,;$(transform)'`; \
+	dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir)
+install-pkgappSCRIPTS: $(pkgapp_SCRIPTS)
+	@$(NORMAL_INSTALL)
+	@list='$(pkgapp_SCRIPTS)'; test -n "$(pkgappdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(pkgappdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(pkgappdir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
+	done | \
+	sed -e 'p;s,.*/,,;n' \
+	    -e 'h;s|.*|.|' \
+	    -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
+	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
+	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+	    if ($$2 == $$4) { files[d] = files[d] " " $$1; \
+	      if (++n[d] == $(am__install_max)) { \
+		print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
+	    else { print "f", d "/" $$4, $$1 } } \
+	  END { for (d in files) print "f", d, files[d] }' | \
+	while read type dir files; do \
+	     if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+	     test -z "$$files" || { \
+	       echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(pkgappdir)$$dir'"; \
+	       $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(pkgappdir)$$dir" || exit $$?; \
+	     } \
+	; done
+
+uninstall-pkgappSCRIPTS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(pkgapp_SCRIPTS)'; test -n "$(pkgappdir)" || exit 0; \
+	files=`for p in $$list; do echo "$$p"; done | \
+	       sed -e 's,.*/,,;$(transform)'`; \
+	dir='$(DESTDIR)$(pkgappdir)'; $(am__uninstall_files_from_dir)
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-linuxdesktopapplicationsDATA: $(linuxdesktopapplications_DATA)
+	@$(NORMAL_INSTALL)
+	@list='$(linuxdesktopapplications_DATA)'; test -n "$(linuxdesktopapplicationsdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(linuxdesktopapplicationsdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(linuxdesktopapplicationsdir)" || exit 1; \
+	fi; \
+	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)$(linuxdesktopapplicationsdir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(linuxdesktopapplicationsdir)" || exit $$?; \
+	done
+
+uninstall-linuxdesktopapplicationsDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(linuxdesktopapplications_DATA)'; test -n "$(linuxdesktopapplicationsdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(linuxdesktopapplicationsdir)'; $(am__uninstall_files_from_dir)
+install-linuxpkgconfigDATA: $(linuxpkgconfig_DATA)
+	@$(NORMAL_INSTALL)
+	@list='$(linuxpkgconfig_DATA)'; test -n "$(linuxpkgconfigdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(linuxpkgconfigdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(linuxpkgconfigdir)" || exit 1; \
+	fi; \
+	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)$(linuxpkgconfigdir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(linuxpkgconfigdir)" || exit $$?; \
+	done
+
+uninstall-linuxpkgconfigDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(linuxpkgconfig_DATA)'; test -n "$(linuxpkgconfigdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(linuxpkgconfigdir)'; $(am__uninstall_files_from_dir)
+install-pkgappDATA: $(pkgapp_DATA)
+	@$(NORMAL_INSTALL)
+	@list='$(pkgapp_DATA)'; test -n "$(pkgappdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(pkgappdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(pkgappdir)" || exit 1; \
+	fi; \
+	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)$(pkgappdir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgappdir)" || exit $$?; \
+	done
+
+uninstall-pkgappDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(pkgapp_DATA)'; test -n "$(pkgappdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(pkgappdir)'; $(am__uninstall_files_from_dir)
+install-programfilesDATA: $(programfiles_DATA)
+	@$(NORMAL_INSTALL)
+	@list='$(programfiles_DATA)'; test -n "$(programfilesdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(programfilesdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(programfilesdir)" || exit 1; \
+	fi; \
+	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)$(programfilesdir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(programfilesdir)" || exit $$?; \
+	done
+
+uninstall-programfilesDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(programfiles_DATA)'; test -n "$(programfilesdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(programfilesdir)'; $(am__uninstall_files_from_dir)
+install-programfilesiconsDATA: $(programfilesicons_DATA)
+	@$(NORMAL_INSTALL)
+	@list='$(programfilesicons_DATA)'; test -n "$(programfilesiconsdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(programfilesiconsdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(programfilesiconsdir)" || exit 1; \
+	fi; \
+	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)$(programfilesiconsdir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(programfilesiconsdir)" || exit $$?; \
+	done
+
+uninstall-programfilesiconsDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(programfilesicons_DATA)'; test -n "$(programfilesiconsdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(programfilesiconsdir)'; $(am__uninstall_files_from_dir)
+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 $(SCRIPTS) $(DATA)
+installdirs:
+	for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgappdir)" "$(DESTDIR)$(linuxdesktopapplicationsdir)" "$(DESTDIR)$(linuxpkgconfigdir)" "$(DESTDIR)$(pkgappdir)" "$(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-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+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)
+	-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+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-linuxdesktopapplicationsDATA \
+	install-linuxpkgconfigDATA install-pkgappDATA \
+	install-pkgappSCRIPTS install-programfilesDATA \
+	install-programfilesiconsDATA
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-binSCRIPTS
+
+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: uninstall-binSCRIPTS \
+	uninstall-linuxdesktopapplicationsDATA \
+	uninstall-linuxpkgconfigDATA uninstall-pkgappDATA \
+	uninstall-pkgappSCRIPTS uninstall-programfilesDATA \
+	uninstall-programfilesiconsDATA
+
+.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-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-pkgappDATA install-pkgappSCRIPTS \
+	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-pkgappDATA \
+	uninstall-pkgappSCRIPTS uninstall-programfilesDATA \
+	uninstall-programfilesiconsDATA
+
+
+# macros
+
+# $(call emit-deploy-target,deploy-variable-name)
+define emit-deploy-target
+$($1): $($1_SOURCE)
+	mkdir -p $$(dir $($1))
+	cp '$$<' '$$@'
+endef
+
+# $(call emit-deploy-wrapper,wrapper-variable-name,wrapper-sourcefile,x)
+# assumes that for a wrapper foo.pc its source template is foo.pc.in
+# if $3 is non-empty then wrapper is marked exec
+define emit-deploy-wrapper
+$($1): $2 
+	mkdir -p '$$(@D)'
+	cp '$$<' '$$@'
+	$(if $3,chmod +x '$$@')
+
+endef
+
+$(eval $(foreach res, $(culture_resources), $(eval $(call culture_resource_dependencies,$(call get_culture,$(call get_resource_name,$(res))),$(call get_resource_name,$(res))))))
+$(eval $(foreach res, $(culture_resources), $(eval $(call culture_resource_commandlines,$(call get_culture,$(call get_resource_name,$(res))),$(res)))))
+
+$(build_satellite_assembly_list): $(BUILD_DIR)/%/$(SATELLITE_ASSEMBLY_NAME):
+	mkdir -p '$(@D)'
+	$(AL) -out:'$@' -culture:$* -t:lib $(cmd_line_satellite_$*)
+
+all: $(ASSEMBLY_TARGET)
+
+$(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.
+.NOEXPORT:
diff --git a/src/Engine-Campfire/Protocols/Campfire/CampfireEventStream.cs b/src/Engine-Campfire/Protocols/Campfire/CampfireEventStream.cs
new file mode 100644
index 0000000..cd6e7e5
--- /dev/null
+++ b/src/Engine-Campfire/Protocols/Campfire/CampfireEventStream.cs
@@ -0,0 +1,163 @@
+// Smuxi - Smart MUltipleXed Irc
+//
+// Copyright (c) 2012 Carlos Martín Nieto <cmn at dwim.me>
+//
+// 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.IO;
+using System.Text;
+using System.Threading;
+using ServiceStack.Text;
+using ServiceStack.ServiceClient.Web;
+using Smuxi.Common;
+using Smuxi.Engine.Campfire;
+
+namespace Smuxi.Engine
+{
+    internal class MessageReceivedEventArgs : EventArgs
+    {
+        public GroupChatModel Chat { get; private set; }
+        public Message Message { get; private set; }
+
+        public MessageReceivedEventArgs(GroupChatModel chat, Message message)
+        {
+            Chat = chat;
+            Message = message;
+        }
+    }
+
+    internal class CampfireEventStream : IDisposable
+    {
+        public EventHandler<MessageReceivedEventArgs> MessageReceived;
+
+        HttpWebRequest Request { get; set; }
+        GroupChatModel Chat { get; set; }
+        NetworkCredential Cred { get; set; }
+        Thread Thread { get; set; }
+        Uri BaseUri { get; set; }
+        string Host { get; set; }
+        int LastMessage { get; set; }
+
+        public CampfireEventStream(GroupChatModel chat, Uri baseuri, NetworkCredential cred)
+        {
+            this.Chat = chat;
+            this.Cred = cred;
+            this.Host = Host;
+            this.BaseUri = baseuri;
+            this.LastMessage = 0;
+        }
+        
+        public void Start()
+        {
+            Thread = new Thread(DoWork);
+            Thread.Start();
+        }
+
+        void FillHole()
+        {
+            var client = new JsonServiceClient(BaseUri.AbsoluteUri);
+            client.Credentials = Cred;
+            var messages = client.Get<MessagesResponse>(
+                String.Format("/room/{0}.json?since={1}", Chat.ID, LastMessage)).Messages;
+
+            if (messages == null)
+                return;
+
+            foreach (var message in messages) {
+                if (MessageReceived != null) {
+                    var args = new MessageReceivedEventArgs(Chat, message);
+                    MessageReceived(this, args);
+                }
+                LastMessage = message.Id;
+            }
+        }
+
+        void DoWork()
+        {
+            while (true) {
+                try {
+                    // if LastMessage > 0 we're reconnecting, so we need to ask
+                    // the server for the messages we've missed
+                    if (LastMessage > 0) {
+                        FillHole();
+                    }
+                    ParseStream();
+                } catch (TimeoutException) {
+                    // Not to worry, let's just connect again
+                } catch (WebException) {
+                }
+            }
+        }
+
+        public void ParseStream()
+        {
+            Request = HttpWebRequest.Create(
+                String.Format("https://streaming.campfirenow.com/room/{0}/live.json", Chat.ID)) as HttpWebRequest;
+            Request.Credentials = Cred;
+            Request.PreAuthenticate = true;
+            var res = Request.GetResponse() as HttpWebResponse;
+
+            using (StreamReader reader = new StreamReader(res.GetResponseStream()))
+            {
+                /* Stupid but easy way to figure out when we've reached the end of a JSON object */
+                int brackets = 0;
+                StringBuilder bld = new StringBuilder();
+
+                while (!reader.EndOfStream) {
+                    var line = reader.ReadLine();
+
+                    for (int i = 0; i < line.Length; i++) {
+                        bld.Append(line[i]);
+                        switch (line[i]) {
+                            case '{':
+                                brackets++;
+                                break;
+                            case '}':
+                                brackets--;
+                                break;
+                            default:
+                                continue;
+                        }
+
+                        if (brackets == 0) {
+                            var str = bld.ToString().Trim();
+                            bld.Length = 0;
+                            var message = JsonSerializer.DeserializeFromString<Message>(str);
+                            if (MessageReceived != null) {
+                                var args = new MessageReceivedEventArgs(Chat, message);
+                                MessageReceived(this, args);
+                            }
+                            LastMessage = message.Id;
+                        }
+                    }
+                }
+
+                reader.Close();
+            }
+
+            res.Close();
+            Request = null;
+        }
+
+        public void Dispose()
+        {
+            Thread.Abort();
+        }
+    }
+}
+
diff --git a/src/Engine-Campfire/Protocols/Campfire/CampfirePersonModel.cs b/src/Engine-Campfire/Protocols/Campfire/CampfirePersonModel.cs
new file mode 100644
index 0000000..223f8bd
--- /dev/null
+++ b/src/Engine-Campfire/Protocols/Campfire/CampfirePersonModel.cs
@@ -0,0 +1,60 @@
+// Smuxi - Smart MUltipleXed Irc
+// 
+// Copyright (c) 2012 Carlos Martín Nieto <cmn at dwim.me>
+
+// 
+// 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.Runtime.Serialization;
+using Smuxi.Common;
+using Smuxi.Engine.Campfire;
+
+namespace Smuxi.Engine.Campfire
+{
+    [Serializable]
+    internal class CampfirePersonModel : PersonModel
+    {
+        public int Uid { get; internal set; }
+        public string Ident { get; internal set; }
+        public string Host { get; internal set; }
+        public string Name {get; internal set; }
+        public string Email {get; internal set; }
+        public bool Admin {get; internal set; }
+        public string AvatarUrl {get; internal set; }
+
+        internal protected CampfirePersonModel(User user, string network, IProtocolManager pm)
+            : base(user.Id.ToString(), user.Name, network, "Campfire", pm)
+        {
+            Uid = user.Id;
+            Name = user.Name;
+            Email = user.Email_Address;
+            Admin = user.Admin;
+            AvatarUrl = user.Avatar_Url;
+            Host = network;
+            Ident = Name;
+        }
+
+        internal protected CampfirePersonModel(SerializationInfo info,
+                                          StreamingContext ctx) :
+                                     base(info, ctx)
+        {
+        }
+
+    }
+}
+
diff --git a/src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs b/src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs
new file mode 100644
index 0000000..526ab93
--- /dev/null
+++ b/src/Engine-Campfire/Protocols/Campfire/CampfireProtocolManager.cs
@@ -0,0 +1,550 @@
+// Smuxi - Smart MUltipleXed Irc
+// 
+// Copyright (c) 2012 Carlos Martín Nieto <cmn at dwim.me>
+// 
+// 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.Web;
+using System.Net;
+using System.Linq;
+using System.Collections;
+using System.Collections.Generic;
+using System.Threading;
+using Smuxi.Common;
+using Smuxi.Engine.Campfire;
+using ServiceStack.ServiceClient.Web;
+
+namespace Smuxi.Engine
+{
+    [ProtocolManagerInfo(Name = "Campfire", Description = "Campfire chat", Alias = "campfire")]
+    public class CampfireProtocolManager : ProtocolManagerBase
+    {
+        static readonly string f_LibraryTextDomain = "smuxi-engine-campfire";
+
+        Dictionary<ChatModel, CampfireEventStream> EventStreams { get; set; }
+        int LastSentId { get; set; }
+        IEnumerable<Room> Rooms { get; set; }
+        DateTime RoomsUpdated { get; set; }
+        TimeSpan RefreshInterval { get; set; }
+        Dictionary<int, CampfirePersonModel>  Users { get; set; }
+        string Key { get; set; }
+        string Network { get; set; }
+        Uri BaseUri { get; set; }
+        ChatModel NetworkChat { get; set; }
+        JsonServiceClient Client { get; set; }
+
+        public override string Protocol {
+            get {
+                return "Campfire";
+            }
+        }
+
+        public override string NetworkID {
+            get {
+                return Network;
+            }
+        }
+
+        public override ChatModel Chat {
+            get {
+                return NetworkChat;
+            }
+        }
+
+        static CampfireProtocolManager()
+        {
+        }
+
+        private CampfirePersonModel CreatePerson(User user)
+        {
+            var person = new CampfirePersonModel(user, NetworkID, this);
+            return person;
+        }
+
+        private void GetUserDetails(int id)
+        {
+            if (Users.ContainsKey(id) || id == 0)
+                return;
+
+            var u = Client.Get<UserResponse>(String.Format("/users/{0}.json", id)).User;
+            Users[u.Id] = CreatePerson(u);
+        }
+
+        private void RefreshRooms()
+        {
+            if (Rooms == null ||
+                RefreshInterval.CompareTo(RoomsUpdated - DateTime.Now) > 0)
+                Rooms = Client.Get<RoomsResponse>("/rooms.json").Rooms;
+        }
+
+        public CampfireProtocolManager(Session session) : base(session)
+        {
+            Trace.Call(session);
+            RefreshInterval = TimeSpan.FromMinutes(5);
+            RoomsUpdated = DateTime.MinValue;
+            Users = new Dictionary<int, CampfirePersonModel>();
+            EventStreams = new Dictionary<ChatModel, CampfireEventStream>();
+        }
+
+        private void FailedToConnect(string str, Exception e)
+        {
+            Session.AddMessageToChat(NetworkChat, CreateMessageBuilder()
+                                     .AppendErrorText("{0}: {1}", str, e.Message)
+                                     .ToMessage());
+        }
+
+        public override void Connect(FrontendManager fm, ServerModel server)
+        {
+            Trace.Call(fm, server);
+
+            Network = server.Hostname.Substring(0, server.Hostname.IndexOf('.'));
+            Host = server.Hostname;
+            BaseUri = new Uri(String.Format("https://{0}", Host));
+
+            NetworkChat = new ProtocolChatModel(Network, "Campfire " + Network, this);
+            NetworkChat.InitMessageBuffer(MessageBufferPersistencyType.Volatile);
+            NetworkChat.ApplyConfig(Session.UserConfig);
+            Session.AddChat(NetworkChat);
+            Session.SyncChat(NetworkChat);
+            var msg = _("Connecting to campfire... ");
+            fm.SetStatus(msg);
+            var bld = CreateMessageBuilder().AppendEventPrefix().AppendText(msg);
+            Session.AddMessageToChat(NetworkChat, bld.ToMessage());
+
+
+
+            Client = new JsonServiceClient(BaseUri.AbsoluteUri);
+            var creds = new NetworkCredential(server.Username, server.Password);
+            Client.Credentials = creds;
+
+            try {
+                var me = Client.Get<UserResponse>("/users/me.json").User;
+                Key = me.Api_Auth_Token;
+                Me = CreatePerson(me);
+                // The blue color is hardcoded for now
+                Me.IdentityNameColored.ForegroundColor = new TextColor(0x0000FF);
+                Me.IdentityNameColored.BackgroundColor = TextColor.None;
+                Me.IdentityNameColored.Bold = true;
+
+            } catch (Exception e) {
+                FailedToConnect("Failed to connect to Campfire", e);
+                return;
+            }
+
+            Client.Credentials = new NetworkCredential(Key, "X");
+            msg = _("Connected to campfire");
+            fm.SetStatus(msg);
+            bld = CreateMessageBuilder().AppendEventPrefix().AppendText(msg);
+            Session.AddMessageToChat(NetworkChat, bld.ToMessage());
+
+            // Campfire lets us know what channels the user is currently in, so
+            // connect to those rooms automatically
+            Rooms = Client.Get<RoomsResponse>("/rooms.json").Rooms;
+            RoomsUpdated = DateTime.Now;
+
+            var myrooms = Client.Get<RoomsResponse>("/presence.json").Rooms;
+            if (myrooms.Length > 0) {
+                bld = CreateMessageBuilder().
+                    AppendEventPrefix().
+                    AppendText("Present in {0}",
+                        String.Join(", ", myrooms.Select(r => r.Name).ToArray())
+                    );
+                Session.AddMessageToChat(NetworkChat, bld.ToMessage());
+            }
+
+            foreach (var room in myrooms) {
+                var chat = new GroupChatModel(room.Id.ToString(), room.Name, null);
+                OpenChat(fm, chat);
+            }
+        }
+
+        public void CommandHelp(CommandModel cd)
+        {
+            var builder = CreateMessageBuilder();
+            builder.AppendEventPrefix();
+            // TRANSLATOR: this line is used as a label / category for a
+            // list of commands below
+            builder.AppendHeader(_("Campfire Commands"));
+            cd.FrontendManager.AddMessageToChat(cd.Chat, builder.ToMessage());
+
+            string[] help = {
+                "help",
+                "connect campfire username password",
+                "list",
+                "uploads",
+            };
+
+            foreach (string line in help) {
+                builder = CreateMessageBuilder();
+                builder.AppendEventPrefix();
+                builder.AppendText(line);
+                cd.FrontendManager.AddMessageToChat(cd.Chat, builder.ToMessage());
+            }
+        }
+
+
+        public void CommandJoin(CommandModel cmd)
+        {
+            Trace.Call(cmd);
+
+            RefreshRooms();
+
+            /*
+             * cmd.DataArray is split at SP, but that's an allowed character
+             * for Campfire. Instead of relying on that, we need to remove the "/join "
+             * part and then split on ','
+             */
+            var chans = cmd.Parameter.Split(',');
+            var list = Rooms.Where(r => chans.Any(r.Name.Equals));
+
+            foreach(Room room in list) {
+                var chat = new GroupChatModel(room.Id.ToString(), room.Name, null);
+                OpenChat(cmd.FrontendManager, chat);
+            }
+
+        }
+
+        public void CommandTopic(CommandModel cmd)
+        {
+            Trace.Call(cmd);
+
+            var update = new UpdateTopicWrapper {
+                room = new TopicChange {
+                    topic = cmd.Parameter
+                }
+            };
+
+            Client.Put<object>(String.Format("/room/{0}.json", cmd.Chat.ID), update);
+        }
+
+        public void CommandUploads(CommandModel cmd)
+        {
+            Trace.Call(cmd);
+
+            var uploads = Client.Get<UploadsResponse>(String.Format("/room/{0}/uploads.json", cmd.Chat.ID)).Uploads;
+
+            foreach (var upload in uploads) {
+                var bld = CreateMessageBuilder();
+                bld.AppendEventPrefix().AppendHeader(_("Upload")).AppendSpace();
+                bld.AppendText(_("'{0}' ({1} B) {2}"), upload.Name, upload.Byte_Size, upload.Full_Url);
+                Session.AddMessageToChat(cmd.Chat, bld.ToMessage());
+            }
+        }
+
+        public void CommandSay(CommandModel cmd)
+        {
+            Trace.Call(cmd);
+            SendMessage((GroupChatModel) cmd.Chat, cmd.Parameter);
+        }
+
+        public override bool Command(CommandModel command)
+        {
+            Trace.Call(command);
+
+            bool handled = false;
+
+            switch (command.Command) {
+                case "j":
+                case "join":
+                    CommandJoin(command);
+                    handled = true;
+                    break;
+                case "say":
+                    CommandSay(command);
+                    handled = true;
+                    break;
+                case "help":
+                    CommandHelp(command);
+                    handled = true;
+                    break;
+                case "topic":
+                    CommandTopic(command);
+                    handled = true;
+                    break;
+                case "uploads":
+                    CommandUploads(command);
+                    handled = true;
+                    break;
+                default: // nothing, normal chat
+                    handled = true;
+                    if (command.Chat is GroupChatModel)
+                        SendMessage((GroupChatModel) command.Chat, command.Data);
+                    break;
+            }
+
+            return handled;
+        }
+
+        public override IList<GroupChatModel> FindGroupChats(GroupChatModel filter)
+        {
+            Trace.Call(filter);
+
+            RefreshRooms();
+            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 {
+                    searchPattern = filter.Name;
+                }
+            }
+
+            List<GroupChatModel> chats = new List<GroupChatModel>(Rooms.Count());
+            IEnumerable<Room> matching;
+
+            matching = searchPattern == null ? Rooms :
+                Rooms.Where(r => Pattern.IsMatch(r.Name, searchPattern));
+
+            foreach (var room in matching) {
+                GroupChatModel chat = new GroupChatModel(room.Id.ToString(), room.Name, null);
+                var users = Client.Get<RoomResponse>(String.Format("/room/{0}.json", chat.ID)).Room.Users;
+
+                /* Don't waste this data */
+                lock (Users) {
+                    foreach (var user in users) {
+                        if (!Users.ContainsKey(user.Id))
+                            Users[user.Id] = CreatePerson(user);
+                    }
+                }
+
+
+                chat.PersonCount = users.Length;
+
+                chat.Topic = CreateMessageBuilder().AppendMessage(room.Topic).ToMessage();
+                lock (chat) {
+                    chats.Add(chat);
+                }
+            }
+
+            return chats;
+        }
+
+        void SendMessage(GroupChatModel chat, string text)
+        {
+            var message = new MessageSending { body = text, type = Campfire.MessageType.TextMessage};
+            var wrapper = new MessageWrapper { message = message };
+            var res = Client.Post<MessageResponse>(String.Format("/room/{0}/speak.json", chat.ID), wrapper).Message;
+            ShowMessage(this, new MessageReceivedEventArgs(chat, res));
+            LastSentId = res.Id;
+        }
+
+        void FormatUpload(MessageBuilder bld, PersonModel person, ChatModel chat, Message message)
+        {
+            // Figure out what the user uploaded, we need to issue another call for this
+            var upload = Client.Get<UploadWrapper>(String.Format("/room/{0}/messages/{1}/upload.json", chat.ID, message.Id)).Upload;
+
+            bld.AppendEventPrefix();
+            bld.AppendIdendityName(person).AppendSpace();
+            bld.AppendText(_("has uploaded '{0}' ({1} B) {2}"), upload.Name, upload.Byte_Size, upload.Full_Url);
+        }
+
+        void FormatEvent(MessageBuilder bld, PersonModel person, string action)
+        {
+            bld.AppendEventPrefix();
+            bld.AppendIdendityName(person).AppendSpace();
+            bld.AppendText(action);
+        }
+
+        void ShowMessage(object sender, MessageReceivedEventArgs args)
+        {
+            var message = args.Message;
+            var chat = args.Chat;
+            bool processed = true;
+
+            if (message.Type == Campfire.MessageType.TimestampMessage)
+                return;
+
+
+            CampfirePersonModel person;
+            lock (Users) {
+                GetUserDetails(message.User_Id); /* Make sure we know who this is */
+                person = Users[message.User_Id];
+            }
+
+            var bld = CreateMessageBuilder();
+            bld.TimeStamp = message.Created_At.DateTime;
+
+            switch (message.Type) {
+                case Campfire.MessageType.EnterMessage:
+                    // TRANSLATOR: {0} is the name of the room
+                    FormatEvent(bld, person, String.Format(_("has joined {0}"), chat.Name));
+                    lock (chat) {
+                        if (chat.GetPerson(person.ID) == null)
+                            Session.AddPersonToGroupChat(chat, person);
+                    }
+                    break;
+                case Campfire.MessageType.KickMessage:
+                case Campfire.MessageType.LeaveMessage:
+                    // TRANSLATOR: {0} is the name of the room
+                    FormatEvent(bld, person, String.Format(_("has left {0}"), chat.Name));
+                    lock (chat) {
+                        if (chat.GetPerson(person.ID) != null)
+                            Session.RemovePersonFromGroupChat(chat, person);
+                    }
+                    break;
+                case Campfire.MessageType.LockMessage:
+                    // TRANSLATOR: {0} is the name of the room
+                    FormatEvent(bld, person, String.Format(_("has locked {0}"), chat.Name));
+                    break;
+                case Campfire.MessageType.UnlockMessage:
+                    // TRANSLATOR: {0} is the name of the room
+                    FormatEvent(bld, person, String.Format(_("has unlocked {0}"), chat.Name));
+                    break;
+                case Campfire.MessageType.TopicChangeMessage:
+                    var topic = CreateMessageBuilder().AppendMessage(message.Body);
+                    Session.UpdateTopicInGroupChat(chat, topic.ToMessage());
+                    FormatEvent(bld, person, _("has changed the topic"));
+                    break;
+                case Campfire.MessageType.UploadMessage:
+                    FormatUpload(bld, person, chat, message);
+                    break;
+                case Campfire.MessageType.TextMessage:
+                case Campfire.MessageType.PasteMessage:
+                    processed = false;
+                    break;
+                default:
+                    FormatEvent(bld, person, String.Format(_("has performed an unknown action"), chat.Name));
+                    break;
+            }
+
+            if (processed) {
+                Session.AddMessageToChat(chat, bld.ToMessage());
+                return;
+            }
+
+            bool mine = person == Me;
+
+            // Don't double-post the messages we've sent
+            if (mine && message.Id <= LastSentId)
+                return;
+
+            if (mine)
+                bld.AppendSenderPrefix(Me);
+            else
+                bld.AppendNick(person).AppendSpace();
+
+            if (message.Type == Campfire.MessageType.TextMessage ||
+                message.Type == Campfire.MessageType.TweetMessage) {
+                bld.AppendMessage(message.Body);
+            } else if (message.Type == Campfire.MessageType.PasteMessage) {
+                bld.AppendText("\n");
+                foreach (string part in message.Body.Split('\n')) {
+                    bld.AppendText("    {0}\n", part);
+                }
+            }
+
+            if (!mine)
+                bld.MarkHighlights();
+
+            Session.AddMessageToChat(chat, bld.ToMessage());
+    }
+
+        public override void OpenChat(FrontendManager fm, ChatModel chat_)
+        {
+            Trace.Call(fm, chat_);
+
+            var room = Rooms.Single(r => r.Name.Equals(chat_.Name));
+            Client.Post<object>(String.Format("/room/{0}/join.json", room.Id), null);
+            room = Client.Get<RoomResponse>(String.Format("/room/{0}.json", room.Id)).Room;
+            var chat = Session.GetChat(room.Name, ChatType.Group, this) as GroupChatModel;
+            if (chat == null)
+                chat = Session.CreateChat<GroupChatModel>(room.Id.ToString(), room.Name, this);
+
+            var bld = CreateMessageBuilder();
+            bld.AppendMessage(room.Topic);
+            chat.Topic = bld.ToMessage();
+
+            Session.AddChat(chat);
+
+            /* Fill what we know about the users, this is only the currently-connected ones */
+            lock (Users) {
+                foreach (User user in room.Users) {
+                    if (!Users.ContainsKey(user.Id))
+                        Users[user.Id] = CreatePerson(user);
+                    Session.AddPersonToGroupChat(chat, Users[user.Id]);
+                }
+            }
+
+            /* Show the recent messages, then go live. FIXME: race condition */
+            var recent = Client.Get<MessagesResponse>(String.Format("/room/{0}/recent.json", chat.ID)).Messages;
+            foreach (Message message in recent)
+                ShowMessage(this, new MessageReceivedEventArgs(chat, message));
+
+            Session.SyncChat(chat);
+            chat.IsSynced = true; // Let the part and join messages take affect
+
+            var stream = new CampfireEventStream(chat, BaseUri, new NetworkCredential(Key, "X"));
+            lock (EventStreams)
+                EventStreams.Add(chat, stream);
+
+            stream.MessageReceived += ShowMessage;
+            stream.Start();
+        }
+
+        public override void CloseChat(FrontendManager fm, ChatModel ChatInfo)
+        {
+            var chat = GetChat(ChatInfo.ID, ChatType.Group);
+            Client.Post<object>(String.Format("/room/{0}/leave.json", chat.ID), null);
+            Session.RemoveChat(chat);
+            lock (EventStreams) {
+                var stream = EventStreams[chat];
+                stream.Dispose();
+                EventStreams.Remove(chat);
+            }
+        }
+
+        public override void Reconnect(FrontendManager fm)
+        {
+            Trace.Call(fm);
+        }
+
+        public override void Disconnect(FrontendManager fm)
+        {
+            Trace.Call(fm);
+        }
+
+        public override void SetPresenceStatus(PresenceStatus status, string message)
+        {
+        }
+
+        public override void Dispose()
+        {
+            Trace.Call();
+
+            lock (EventStreams) {
+                foreach (var stream in EventStreams.Values)
+                    stream.Dispose();
+            }
+
+            base.Dispose();
+        }
+
+        public override string ToString()
+        {
+            return Network;
+        }
+
+        private static string _(string msg)
+        {
+            return LibraryCatalog.GetString(msg, f_LibraryTextDomain);
+        }
+
+    }
+}
+
diff --git a/src/Engine-Campfire/Protocols/Campfire/DTO.cs b/src/Engine-Campfire/Protocols/Campfire/DTO.cs
new file mode 100644
index 0000000..c781b93
--- /dev/null
+++ b/src/Engine-Campfire/Protocols/Campfire/DTO.cs
@@ -0,0 +1,98 @@
+// Smuxi - Smart MUltipleXed Irc
+//
+// Copyright (c) 2012 Carlos Martín Nieto <cmn at dwim.me>
+//
+// 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.Campfire
+{
+    internal class UserResponse { public User User { get; set; } }
+    internal class RoomsResponse { public Room[] Rooms { get; set; } }
+    internal class RoomResponse { public Room Room { get; set; } }
+    internal class MessagesResponse { public Message[] Messages { get; set; } }
+    internal class MessageResponse { public Message Message { get; set; } }
+    internal class MessageWrapper { public MessageSending message { get; set; } }
+    internal class TopicChange { public string topic { get; set; } }
+    internal class UpdateTopicWrapper { public TopicChange room { get; set; } }
+    internal class UploadWrapper { public Upload Upload { get; set; } }
+    internal class UploadsResponse { public Upload[] Uploads { get; set; } }
+
+    internal enum MessageType {
+        UnknownMessage,
+        EnterMessage,
+        KickMessage,
+        LeaveMessage,
+        TimestampMessage,
+        TextMessage,
+        PasteMessage,
+        SoundMessage,
+        LockMessage,
+        UnlockMessage,
+        TopicChangeMessage,
+        TweetMessage,
+        UploadMessage,
+    }
+
+    internal class Room {
+        public string Topic { get; set; }
+        public string Name { get; set; }
+        public int Id { get; set; }
+        public bool Locked { get; set; }
+        public int MembershipLimit { get; set; }
+        public DateTime CreatedAt { get; set; }
+        public DateTime UpdatedAt { get; set; }
+        public User[] Users { get; set; }
+    }
+
+    internal class User {
+        public int Id { get; set; }
+        public string Name { get; set; }
+        public string Email_Address { get; set; }
+        public bool Admin { get; set; }
+        public DateTimeOffset Created_At { get; set; }
+        public string Type { get; set; }
+        public string Avatar_Url { get; set; }
+        public string Api_Auth_Token { get; set; }
+    }
+
+    internal class MessageSending {
+        public MessageType type { get; set; }
+        public string body { get; set; }
+    }
+
+    internal class Message {
+        public int Id { get; set; }
+        public string Body { get; set; }
+        public int Room_Id { get; set; }
+        public int User_Id { get; set; }
+        public DateTimeOffset Created_At { get; set; }
+        public MessageType Type { get; set; }
+        public bool Starred { get; set; }
+    }
+
+    internal class Upload {
+        public int Id { get; set; }
+        public int Room_Id { get; set; }
+        public string Name { get; set; }
+        public string Full_Url { get; set; }
+        public DateTimeOffset Created_At { get; set; }
+        public string Content_Type { get; set; }
+        public int User_Id { get; set; }
+        public int Byte_Size { get; set; }
+    }
+}
diff --git a/src/Engine-IRC/Makefile.in b/src/Engine-IRC/Makefile.in
index 0039fea..f32356b 100644
--- a/src/Engine-IRC/Makefile.in
+++ b/src/Engine-IRC/Makefile.in
@@ -58,8 +58,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
@@ -150,9 +153,8 @@ 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_CAMPFIRE = @GETTEXT_PACKAGE_ENGINE_CAMPFIRE@
 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@
@@ -164,6 +166,9 @@ 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@
+GIO_SHARP_CFLAGS = @GIO_SHARP_CFLAGS@
+GIO_SHARP_FILES = @GIO_SHARP_FILES@
+GIO_SHARP_LIBS = @GIO_SHARP_LIBS@
 GLADE_SHARP_20_CFLAGS = @GLADE_SHARP_20_CFLAGS@
 GLADE_SHARP_20_LIBS = @GLADE_SHARP_20_LIBS@
 GLIB_SHARP_20_CFLAGS = @GLIB_SHARP_20_CFLAGS@
@@ -210,6 +215,11 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
+MESSAGINGMENU_SHARP_CFLAGS = @MESSAGINGMENU_SHARP_CFLAGS@
+MESSAGINGMENU_SHARP_FILES = @MESSAGINGMENU_SHARP_FILES@
+MESSAGINGMENU_SHARP_LIBS = @MESSAGINGMENU_SHARP_LIBS@
+MESSAGING_MENU_CFLAGS = @MESSAGING_MENU_CFLAGS@
+MESSAGING_MENU_LIBS = @MESSAGING_MENU_LIBS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
 MONO_MODULE_CFLAGS = @MONO_MODULE_CFLAGS@
@@ -217,8 +227,6 @@ 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@
@@ -231,8 +239,6 @@ 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@
diff --git a/src/Engine-IRC/Protocols/Irc/IrcGroupPersonModel.cs b/src/Engine-IRC/Protocols/Irc/IrcGroupPersonModel.cs
index 7cb1e42..6261eea 100644
--- a/src/Engine-IRC/Protocols/Irc/IrcGroupPersonModel.cs
+++ b/src/Engine-IRC/Protocols/Irc/IrcGroupPersonModel.cs
@@ -29,9 +29,6 @@ namespace Smuxi.Engine
     [Serializable]
     public class IrcGroupPersonModel : IrcPersonModel
     {
-#if LOG4NET
-        private static readonly log4net.ILog _Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
-#endif
         private bool _IsOp;
         private bool _IsVoice;
         
diff --git a/src/Engine-IRC/Protocols/Irc/IrcMessageBuilder.cs b/src/Engine-IRC/Protocols/Irc/IrcMessageBuilder.cs
index fa66d64..3aa07dd 100644
--- a/src/Engine-IRC/Protocols/Irc/IrcMessageBuilder.cs
+++ b/src/Engine-IRC/Protocols/Irc/IrcMessageBuilder.cs
@@ -33,9 +33,6 @@ namespace Smuxi.Engine
 
     public class IrcMessageBuilder : MessageBuilder
     {
-#if LOG4NET
-        private static readonly log4net.ILog Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
-#endif
         private static char[] IrcControlChars { get; set; }
 
         static IrcMessageBuilder()
diff --git a/src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs b/src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs
index d447224..1aee2a3 100644
--- a/src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs
+++ b/src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs
@@ -50,7 +50,6 @@ namespace Smuxi.Engine
         private int             _CurrentNickname;
         private string          _Username;
         private string          _Password;
-        private IrcPersonModel  _MyPerson;
         private FrontendManager _FrontendManager;
         private bool            _Listening;
         private ChatModel       _NetworkChat;
@@ -123,24 +122,24 @@ namespace Smuxi.Engine
                     return String.Empty;
                 }
 
-                if (_MyPerson == null) {
+                if (IrcMe == null) {
                     return _IrcClient.Nickname;
                 }
 
                 return String.Format("{0}!{1}@{2}", _IrcClient.Nickname,
-                                     _MyPerson.Ident, _MyPerson.Host);
+                                     IrcMe.Ident, IrcMe.Host);
             }
         }
 
-        private IrcPersonModel MyPerson {
+        private IrcPersonModel IrcMe {
             get {
-                if (_MyPerson == null) {
-                    _MyPerson = CreatePerson(_IrcClient.Nickname);
-                }
-                return _MyPerson;
+                return (IrcPersonModel) Me;
+            }
+            set {
+                Me = value;
             }
         }
-        
+
         public IrcProtocolManager(Session session) : base(session)
         {
             Trace.Call(session);
@@ -229,9 +228,9 @@ namespace Smuxi.Engine
         {
             if (e.WhoInfo.Nick == _IrcClient.Nickname) {
                 // that's me!
-                MyPerson.Ident = e.WhoInfo.Ident;
-                MyPerson.Host = e.WhoInfo.Host;
-                MyPerson.RealName = e.WhoInfo.Realname;
+                IrcMe.Ident = e.WhoInfo.Ident;
+                IrcMe.Host = e.WhoInfo.Host;
+                IrcMe.RealName = e.WhoInfo.Realname;
             }
         }
 
@@ -247,6 +246,17 @@ namespace Smuxi.Engine
             text.IsHighlight = true;
             builder.AppendText(text);
             Session.AddMessageToChat(_NetworkChat, builder.ToMessage());
+
+            builder = CreateMessageBuilder();
+            string host;
+            if (String.IsNullOrEmpty(NetworkID)) {
+                host = _IrcClient.Address;
+            } else {
+                host = NetworkID;
+            }
+            string url = String.Format("irc://{0}/{1}", host, e.Channel);
+            builder.AppendUrl(url, _("Accept invite (join room)"));
+            Session.AddMessageToChat(_NetworkChat, builder.ToMessage());
         }
 
         void OnReadLine(object sender, ReadLineEventArgs e)
@@ -307,12 +317,6 @@ namespace Smuxi.Engine
 
             ApplyConfig(Session.UserConfig, server);
 
-            // add fallbacks if only one nick was specified, else we get random
-            // number nicks when nick collisions happen
-            if (_Nicknames.Length == 1) {
-                _Nicknames = new string[] { _Nicknames[0], _Nicknames[0] + "_", _Nicknames[0] + "__" };
-            }
-
             // TODO: use config for single network chat or once per network manager
             _NetworkChat = Session.CreateChat<ProtocolChatModel>(
                 _Network, "IRC " + _Network, this
@@ -346,8 +350,8 @@ namespace Smuxi.Engine
         {
             Trace.Call(fm);
             
+            MessageBuilder builder;
             try {
-                MessageBuilder builder;
                 if (!String.IsNullOrEmpty(_IrcClient.ProxyHost)) {
                     builder = CreateMessageBuilder();
                     builder.AppendEventPrefix();
@@ -360,14 +364,24 @@ namespace Smuxi.Engine
                 string msg;
                 msg = String.Format(_("Connecting to {0} port {1}..."), _Host, _Port);
                 fm.SetStatus(msg);
-                Session.AddTextToChat(_NetworkChat, "-!- " + msg);
+                builder = CreateMessageBuilder();
+                builder.AppendEventPrefix().AppendText(msg);
+                Session.AddMessageToChat(Chat, builder.ToMessage());
+
                 // TODO: add SSL support
                 _IrcClient.Connect(_Host, _Port);
                 fm.UpdateNetworkStatus();
+
                 msg = String.Format(_("Connection to {0} established"), _Host);
                 fm.SetStatus(msg);
-                Session.AddTextToChat(_NetworkChat, "-!- " + msg);
-                Session.AddTextToChat(_NetworkChat, "-!- " + _("Logging in..."));
+                builder = CreateMessageBuilder();
+                builder.AppendEventPrefix().AppendText(msg);
+                Session.AddMessageToChat(Chat, builder.ToMessage());
+
+                builder = CreateMessageBuilder();
+                builder.AppendEventPrefix().AppendText(_("Logging in..."));
+                Session.AddMessageToChat(Chat, builder.ToMessage());
+
                 string realname = (string) Session.UserConfig["Connection/Realname"];
                 if (realname.Trim().Length == 0) {
                     realname = "unset";
@@ -384,7 +398,10 @@ namespace Smuxi.Engine
                     Session.AddMessageToChat(_NetworkChat, builder.ToMessage());
                 }
                 _IrcClient.Login(_Nicknames, realname, 0, _Username, _Password);
-                
+                // set Me property very early as we might need to know who we
+                // are before the registration was confirmed in _OnRegistered()
+                Me = CreatePerson(_IrcClient.Nickname);
+
                 foreach (string command in (string[]) Session.UserConfig["Connection/OnConnectCommands"]) {
                     if (command.Length == 0) {
                         continue;
@@ -402,7 +419,11 @@ namespace Smuxi.Engine
                 _Listening = true;
             } catch (CouldNotConnectException ex) {
                 fm.SetStatus(_("Connection failed!"));
-                Session.AddTextToChat(_NetworkChat, "-!- " + _("Connection failed! Reason: ") + ex.Message);
+                builder = CreateMessageBuilder();
+                builder.AppendEventPrefix();
+                builder.AppendText(_("Connection failed! Reason: "));
+                builder.AppendText(ex.Message);
+                Session.AddMessageToChat(Chat, builder.ToMessage());
                 throw;
             }
         }
@@ -410,24 +431,32 @@ namespace Smuxi.Engine
         public override void Disconnect(FrontendManager fm)
         {
             Trace.Call(fm);
-            
+
+            MessageBuilder builder;
             fm.SetStatus(_("Disconnecting..."));
             if (IsConnected) {
-                Session.AddTextToChat(_NetworkChat, "-!- " + 
-                    String.Format(_("Disconnecting from {0}..."),
-                                  _IrcClient.Address));
+                builder = CreateMessageBuilder();
+                builder.AppendEventPrefix();
+                builder.AppendText(_("Disconnecting from {0}..."),
+                                   _IrcClient.Address);
+                Session.AddMessageToChat(Chat, builder.ToMessage());
                 // else the Listen() thread would try to connect again
                 _Listening = false;
                 _IrcClient.Disconnect();
                 fm.SetStatus(String.Format(_("Disconnected from {0}"),
                                            _IrcClient.Address));
-                Session.AddTextToChat(_NetworkChat, "-!- " +
-                    _("Connection closed"));
-                
+
+                builder = CreateMessageBuilder();
+                builder.AppendEventPrefix();
+                builder.AppendText(_("Connection closed"));
+                Session.AddMessageToChat(Chat, builder.ToMessage());
                 // TODO: set someone else as current network manager?
             } else {
                 fm.SetStatus(String.Empty);
-                fm.AddTextToChat(_NetworkChat, "-!- " + _("Not connected"));
+                builder = CreateMessageBuilder();
+                builder.AppendEventPrefix();
+                builder.AppendText(_("Not connected"));
+                fm.AddMessageToChat(Chat, builder.ToMessage());
             }
             
             if (_RunThread != null && _RunThread.IsAlive) {
@@ -455,36 +484,44 @@ namespace Smuxi.Engine
         public override void Reconnect(FrontendManager fm)
         {
             Trace.Call(fm);
-            
+
+            MessageBuilder builder;
             fm.SetStatus(_("Reconnecting..."));
             try {
                 string msg;
                 if (_IrcClient != null) {
                     if (_IrcClient.IsConnected) {
-                        Session.AddTextToChat(
-                            _NetworkChat,
-                            String.Format(
-                                "-!- " + _("Reconnecting to {0}..."),
-                                _IrcClient.Address
-                            )
-                        );
+                        builder = CreateMessageBuilder();
+                        builder.AppendEventPrefix();
+                        builder.AppendText(_("Reconnecting to {0}..."),
+                                           _IrcClient.Address);
+                        Session.AddMessageToChat(Chat, builder.ToMessage());
+
                         ApplyConfig(Session.UserConfig, _ServerModel);
                         _IrcClient.Reconnect(true);
                         msg = String.Format(_("Connection to {0} established"),
                                             _IrcClient.Address);
-                        fm.SetStatus(msg); 
-                        Session.AddTextToChat(_NetworkChat, "-!- " + msg);
+                        fm.SetStatus(msg);
+
+                        builder = CreateMessageBuilder();
+                        builder.AppendEventPrefix().AppendText(msg);
+                        Session.AddMessageToChat(Chat, builder.ToMessage());
                     } else {
                         Connect(fm);
                     }
                 } else {
                     msg =  _("Reconnect Error");
                     fm.SetStatus(msg);
-                    Session.AddTextToChat(_NetworkChat, "-!- " + msg);
+
+                    builder = CreateMessageBuilder();
+                    builder.AppendEventPrefix().AppendText(msg);
+                    Session.AddMessageToChat(Chat, builder.ToMessage());
                 }
             } catch (ConnectionException) {
                 fm.SetStatus(String.Empty);
-                fm.AddTextToChat(_NetworkChat, "-!- " + _("Not connected"));
+                builder = CreateMessageBuilder();
+                builder.AppendEventPrefix().AppendText(_("Not connected"));
+                fm.AddMessageToChat(Chat, builder.ToMessage());
             }
             fm.UpdateNetworkStatus();
         }
@@ -567,7 +604,7 @@ namespace Smuxi.Engine
             CommandModel cmd = new CommandModel(fm, _NetworkChat, chat.ID);
             switch (chat.ChatType) {
                 case ChatType.Person:
-                    CommandMessage(cmd);
+                    CommandQuery(cmd);
                     break;
                 case ChatType.Group:
                     CommandJoin(cmd);
@@ -659,10 +696,13 @@ namespace Smuxi.Engine
                             handled = true;
                             break;
                         case "msg":
-                        case "query":
                             CommandMessage(command);
                             handled = true;
                             break;
+                        case "query":
+                            CommandQuery(command);
+                            handled = true;
+                            break;
                         case "amsg":
                             CommandAllMessage(command);
                             handled = true;
@@ -808,6 +848,23 @@ namespace Smuxi.Engine
                             CommandQuit(command);
                             handled = true;
                             break;
+                    case "sleep":
+                            int amount = 0;
+                            if (Int32.TryParse(command.Parameter, out amount)) {
+                                var msg = CreateMessageBuilder().
+                                    AppendEventPrefix().
+                                    AppendText(
+                                        _("Sleeping for {0} milliseconds"),
+                                        amount
+                                    ).
+                                    ToMessage();
+                                Session.AddMessageToChat(Chat, msg);
+                                Thread.Sleep(amount);
+                            } else {
+                                _NotEnoughParameters(command);
+                            }
+                            handled = true;
+                            break;
                         default:
                             CommandFallback(command);
                             handled = true;
@@ -820,11 +877,15 @@ namespace Smuxi.Engine
                         // we are on the session chat or protocol chat 
                         _IrcClient.WriteLine(command.Data);
                     } else {
-                        // split too long messages
-                        var messages = SplitMessage("PRIVMSG", command.Chat.ID,
-                                                    command.Data);
-                        foreach (string message in messages) {
-                            _Say(command.Chat, message);
+                        // split multiline messages
+                        string[] lines = command.Data.Split(new char[] {'\n'});
+                        foreach (string line in lines) {
+                            // split too long messages
+                            var messages = SplitMessage("PRIVMSG", command.Chat.ID,
+                                                        line);
+                            foreach (string message in messages) {
+                                _Say(command.Chat, message);
+                            }
                         }
                     }
                     handled = true;
@@ -953,15 +1014,11 @@ namespace Smuxi.Engine
                 try {
                     server.Port = Int32.Parse(port);
                 } catch (FormatException) {
-                    fm.AddTextToChat(
-                        cd.Chat,
-                        String.Format("-!- {0}",
-                            String.Format(
-                                _("Invalid port: {0}"),
-                                cd.DataArray[3]
-                            )
-                        )
-                    );
+                    var builder = CreateMessageBuilder();
+                    builder.AppendEventPrefix();
+                    builder.AppendText(_("Invalid port: {0}"),
+                                       cd.DataArray[3]);
+                    fm.AddMessageToChat(Chat, builder.ToMessage());
                     return;
                 }
             } else {
@@ -1001,7 +1058,7 @@ namespace Smuxi.Engine
             _IrcClient.SendMessage(SendType.Message, chat.ID, message);
 
             var builder = CreateMessageBuilder();
-            builder.AppendSenderPrefix(MyPerson);
+            builder.AppendSenderPrefix(Me);
             Match m = Regex.Match(message, String.Format(@"^@(?<nick>\S+)|^(?<nick>\S+)(?:\:|,)"));
             if (m.Success) {
                 // this is probably a reply with a nickname
@@ -1024,7 +1081,8 @@ namespace Smuxi.Engine
         public void CommandJoin(CommandModel cd)
         {
             Trace.Call(cd);
-            
+
+            MessageBuilder builder;
             string channelStr = null;
             if ((cd.DataArray.Length >= 2) &&
                 (cd.DataArray[1].Length >= 1)) {
@@ -1057,27 +1115,25 @@ namespace Smuxi.Engine
             }
             if (activeCount > 0) {
                 // ok, these channels will be queued
-                cd.FrontendManager.AddTextToChat(
-                    _NetworkChat,
-                    "-!- " +
-                    String.Format(
-                        _("Queuing joins: {0}"),
-                        String.Join(" ", channels)
-                    )
-                );
+                builder = CreateMessageBuilder();
+                builder.AppendEventPrefix();
+                builder.AppendText(_("Queuing joins: {0}"),
+                                   String.Join(" ", channels));
+                cd.FrontendManager.AddMessageToChat(Chat, builder.ToMessage());
             }
 
             int i = 0;
             foreach (string channel in channels) {
                 string key = keys != null && keys.Length > i ? keys[i] : null;
                 if (_IrcClient.IsJoined(channel)) {
-                    cd.FrontendManager.AddTextToChat(
-                        cd.Chat,
-                        "-!- " +
-                        String.Format(
-                            _("Already joined to channel: {0}." +
-                            " Type /window {0} to switch to it."),
-                            channel));
+                    builder = CreateMessageBuilder();
+                    builder.AppendEventPrefix();
+                    builder.AppendText(
+                        _("Already joined to channel: {0}." +
+                          " Type /window {0} to switch to it."),
+                        channel
+                    );
+                    cd.FrontendManager.AddMessageToChat(cd.Chat, builder.ToMessage());
                     continue;
                 }
 
@@ -1106,14 +1162,13 @@ namespace Smuxi.Engine
                                     " ",  _QueuedChannelJoinList.ToArray()
                                 );
                             }
-                            cd.FrontendManager.AddTextToChat(
-                                _NetworkChat,
-                                "-!- " +
-                                String.Format(
-                                    _("Active joins: {0} - Queued joins: {1}"),
-                                    activeChans, queuedChans
-                                )
+                            builder = CreateMessageBuilder();
+                            builder.AppendEventPrefix();
+                            builder.AppendText(
+                                _("Active joins: {0} - Queued joins: {1}"),
+                                activeChans, queuedChans
                             );
+                            cd.FrontendManager.AddMessageToChat(Chat, builder.ToMessage());
 
 #if LOG4NET
                             _Logger.Debug("CommandJoin(): waiting to join: " + chan);
@@ -1153,19 +1208,17 @@ namespace Smuxi.Engine
                                     queuedChans
                                 );
                             }
-                            cd.FrontendManager.AddTextToChat(
-                                _NetworkChat,
-                                "-!- " + msg
-                            );
+                            builder = CreateMessageBuilder();
+                            builder.AppendEventPrefix().AppendText(msg);
+                            cd.FrontendManager.AddMessageToChat(Chat, builder.ToMessage());
                         } else {
                             lock (_QueuedChannelJoinList) {
                                 _QueuedChannelJoinList.Remove(chan);
                             }
-                            cd.FrontendManager.AddTextToChat(
-                                _NetworkChat,
-                                "-!- " +
-                                String.Format(_("Joining: {0}"), chan)
-                            );
+                            builder = CreateMessageBuilder();
+                            builder.AppendEventPrefix();
+                            builder.AppendText(_("Joining: {0}"), chan);
+                            cd.FrontendManager.AddMessageToChat(Chat, builder.ToMessage());
                         }
 #if LOG4NET
                         _Logger.Debug("CommandJoin(): joining: " + chan);
@@ -1218,7 +1271,6 @@ namespace Smuxi.Engine
 
         public void CommandCycle(CommandModel cd)
         {
-            FrontendManager fm = cd.FrontendManager;
             if (cd.Chat.ChatType == ChatType.Group) {
                 if (cd.Chat.IsEnabled) {
                     // disable chat so we don't loose the message buffer
@@ -1245,15 +1297,15 @@ namespace Smuxi.Engine
                         break;
                     default:
                         // seems to be a nick
-                        CommandMessageQuery(cd);
+                        CommandMessageNick(cd);
                         break;
                 }
             } else {
-                CommandMessageQuery(cd);
+                NotEnoughParameters(cd);
             }
         }
         
-        public void CommandMessageQuery(CommandModel cd)
+        public void CommandQuery(CommandModel cd)
         {
             ChatModel chat = null;
             if (cd.DataArray.Length >= 2) {
@@ -1286,18 +1338,61 @@ namespace Smuxi.Engine
                 ChatModel chat = GetChat(channelname, ChatType.Group);
                 if (chat == null) {
                     // server chat as fallback if we are not joined
-                    chat = _NetworkChat;
-                    Session.AddTextToChat(chat, "<" + _IrcClient.Nickname + ":" + channelname + "> " + message, true);
+                    var builder = CreateMessageBuilder();
+                    builder.AppendText("<{0}:{1}> ", _IrcClient.Nickname,
+                                       channelname);
+                    builder.AppendMessage(message);
+                    Session.AddMessageToChat(Chat, builder.ToMessage(), true);
+                    _IrcClient.SendMessage(SendType.Message, channelname, message);
                 } else {
                      _Say(chat, message);
                 }
-
-                _IrcClient.SendMessage(SendType.Message, channelname, message);
             } else {
                 _NotEnoughParameters(cd);
             }
         }
 
+        [Obsolete("CommandMessageQuery() is deprecated, use CommandQuery() instead")]
+        public void CommandMessageQuery(CommandModel cmd)
+        {
+            CommandQuery(cmd);
+        }
+
+        public void CommandMessageNick(CommandModel cmd)
+        {
+            if (cmd == null) {
+                throw new ArgumentNullException("cmd");
+            }
+            if (cmd.DataArray.Length < 3) {
+                NotEnoughParameters(cmd);
+                return;
+            }
+
+            var nickname = cmd.DataArray[1];
+            string message = String.Join(" ", cmd.DataArray, 2,
+                                         cmd.DataArray.Length - 2);
+            // ignore empty messages
+            if (message.TrimEnd(' ').Length == 0) {
+                return;
+            }
+
+            var chat = GetChat(nickname, ChatType.Person);
+            if (chat == null) {
+                // fallback to protocol chat + where the command was issued
+                var msg = CreateMessageBuilder().
+                    AppendText("<{0}:{1}> ", _IrcClient.Nickname, nickname).
+                    AppendMessage(message).
+                    ToMessage();
+                Session.AddMessageToChat(_NetworkChat, msg, true);
+                if (cmd.Chat != _NetworkChat) {
+                    cmd.FrontendManager.AddMessageToChat(cmd.Chat, msg);
+                }
+                _IrcClient.SendMessage(SendType.Message, nickname, message);
+            } else {
+                _Say(chat, message);
+            }
+        }
+
         private IList<string> SplitMessage(string command, string target, string message)
         {
             List<string> messages = new List<string>();
@@ -1466,7 +1561,10 @@ namespace Smuxi.Engine
                 if (cd.DataArray.Length >= 4) {
                     parameters = String.Join(" ", cd.DataArray, 3, cd.DataArray.Length-3);
                 }
-                Session.AddTextToChat(_NetworkChat, "[ctcp(" + destination + ")] " + command + " " + parameters);
+                var builder = CreateMessageBuilder();
+                builder.AppendText("[ctcp({0})] {1} {2}", destination, command,
+                                   parameters);
+                Session.AddMessageToChat(Chat, builder.ToMessage());
                 _IrcClient.SendMessage(SendType.CtcpRequest, destination, command + " " + parameters);
             } else {
                 _NotEnoughParameters(cd);
@@ -1478,7 +1576,10 @@ namespace Smuxi.Engine
             if (cd.DataArray.Length >= 2) {
                 string destination = cd.DataArray[1];
                 string timestamp = DateTime.Now.ToFileTime().ToString();
-                Session.AddTextToChat(_NetworkChat, "[ctcp(" + destination + ")] PING " + timestamp);
+                var builder = CreateMessageBuilder();
+                builder.AppendText("[ctcp({0})] {1} {2}", destination, "PING",
+                                   timestamp);
+                Session.AddMessageToChat(Chat, builder.ToMessage());
                 _IrcClient.SendMessage(SendType.CtcpRequest, destination, "PING " + timestamp);
             } else {
                 _NotEnoughParameters(cd);
@@ -1489,7 +1590,9 @@ namespace Smuxi.Engine
         {
             if (cd.DataArray.Length >= 2) {
                 string destination = cd.DataArray[1];
-                Session.AddTextToChat(_NetworkChat, "[ctcp(" + destination + ")] TIME");
+                var builder = CreateMessageBuilder();
+                builder.AppendText("[ctcp({0})] {1}", destination, "TIME");
+                Session.AddMessageToChat(Chat, builder.ToMessage());
                 _IrcClient.SendMessage(SendType.CtcpRequest, destination, "TIME");
             } else {
                 _NotEnoughParameters(cd);
@@ -1500,7 +1603,9 @@ namespace Smuxi.Engine
         {
             if (cd.DataArray.Length >= 2) {
                 string destination = cd.DataArray[1];
-                Session.AddTextToChat(_NetworkChat, "[ctcp(" + destination + ")] VERSION");
+                var builder = CreateMessageBuilder();
+                builder.AppendText("[ctcp({0})] {1}", destination, "VERSION");
+                Session.AddMessageToChat(Chat, builder.ToMessage());
                 _IrcClient.SendMessage(SendType.CtcpRequest, destination, "VERSION");
             } else {
                 _NotEnoughParameters(cd);
@@ -1511,7 +1616,9 @@ namespace Smuxi.Engine
         {
             if (cd.DataArray.Length >= 2) {
                 string destination = cd.DataArray[1];
-                Session.AddTextToChat(_NetworkChat, "[ctcp(" + destination + ")] FINGER");
+                var builder = CreateMessageBuilder();
+                builder.AppendText("[ctcp({0})] {1}", destination, "FINGER");
+                Session.AddMessageToChat(Chat, builder.ToMessage());
                 _IrcClient.SendMessage(SendType.CtcpRequest, destination, "FINGER");
             } else {
                 _NotEnoughParameters(cd);
@@ -1547,8 +1654,10 @@ namespace Smuxi.Engine
                     info.HopCount,
                     info.Ident,
                     info.Host,
-                    info.Realname);
-                Session.AddTextToChat(cd.Chat, msg);
+                    info.Realname
+                );
+                var builder = CreateMessageBuilder().AppendText(msg);
+                Session.AddMessageToChat(cd.Chat, builder.ToMessage());
             }
         }
 
@@ -1582,6 +1691,7 @@ namespace Smuxi.Engine
         
         public void CommandTopic(CommandModel cd)
         {
+            MessageBuilder builder;
             FrontendManager fm = cd.FrontendManager;
             ChatModel chat = cd.Chat;
             string channel = chat.ID;
@@ -1590,17 +1700,16 @@ namespace Smuxi.Engine
             } else {
                 if (_IrcClient.IsJoined(channel)) {
                     string topic = _IrcClient.GetChannel(channel).Topic;
+                    builder = CreateMessageBuilder();
+                    builder.AppendEventPrefix();
                     if (topic.Length > 0) {
-                        var builder = CreateMessageBuilder();
-                        builder.AppendEventPrefix();
                         // TRANSLATOR: do NOT change the position of {1}!
                         builder.AppendText(_("Topic for {0}: {1}"), channel, String.Empty);
                         builder.AppendMessage(topic);
-                        fm.AddMessageToChat(chat, builder.ToMessage());
                     } else {
-                        fm.AddTextToChat(chat,
-                            "-!- " + String.Format(_("No topic set for {0}"), channel));
+                        builder.AppendText(_("No topic set for {0}"), channel);
                     }
+                    fm.AddMessageToChat(chat, builder.ToMessage());
                 }
             }
         }
@@ -1663,6 +1772,7 @@ namespace Smuxi.Engine
 
         public void CommandBan(CommandModel cd)
         {
+            MessageBuilder builder;
             ChatModel chat = cd.Chat;
             string channel = chat.ID;
             if (cd.DataArray.Length == 2) {
@@ -1676,23 +1786,22 @@ namespace Smuxi.Engine
                 int i = 1;
                 foreach (BanInfo info in infos) {
                     string msg = String.Format(
-                        "-!- {0} - {1}: {2} {3}",
+                        "{0} - {1}: {2} {3}",
                         i++,
                         info.Channel,
                         _("ban"),
                         info.Mask
                     );
-                    Session.AddTextToChat(cd.Chat, msg);
+                    builder = CreateMessageBuilder();
+                    builder.AppendEventPrefix();
+                    builder.AppendText(msg);
+                    cd.FrontendManager.AddMessageToChat(cd.Chat, builder.ToMessage());
                 }
                 if (infos.Count == 0) {
-                    Session.AddTextToChat(
-                        cd.Chat,
-                        String.Format(
-                            "-!- {0} {1}",
-                            _("No bans in channel"),
-                            channel
-                        )
-                    );
+                    builder = CreateMessageBuilder();
+                    builder.AppendEventPrefix();
+                    builder.AppendText(_("No bans in channel"), channel);
+                    cd.FrontendManager.AddMessageToChat(cd.Chat, builder.ToMessage());
                 }
             }
         }
@@ -1764,6 +1873,7 @@ namespace Smuxi.Engine
 
         public void CommandMode(CommandModel cd)
         {
+            MessageBuilder builder;
             ChatModel chat = cd.Chat;
             if (cd.DataArray.Length >= 2) {
                 // does cd.Chat cause a remoting call?
@@ -1776,20 +1886,22 @@ namespace Smuxi.Engine
             } else {
                 if (chat.ChatType == ChatType.Group) {
                     Channel chan = _IrcClient.GetChannel(cd.Chat.ID);
-                    cd.FrontendManager.AddTextToChat(cd.Chat, String.Format(
-                                                                "-!- mode/{0} [{1}]",
-                                                                chat.Name, chan.Mode));
+                    builder = CreateMessageBuilder();
+                    builder.AppendEventPrefix();
+                    builder.AppendText("mode/{0} [{1}]", chat.Name, chan.Mode);
+                    cd.FrontendManager.AddMessageToChat(cd.Chat, builder.ToMessage());
                 } else {
-                    cd.FrontendManager.AddTextToChat(cd.Chat, String.Format(
-                                                                "-!- Your user mode is [{0}]",
-                                                                _IrcClient.Usermode));
+                    builder = CreateMessageBuilder();
+                    builder.AppendEventPrefix();
+                    builder.AppendText(_("Your user mode is {0}"),
+                                       String.Format("[{0}]", _IrcClient.Usermode));
+                    cd.FrontendManager.AddMessageToChat(cd.Chat, builder.ToMessage());
                 }
             }
         }
 
         public void CommandInvite(CommandModel cd)
         {
-            FrontendManager fm = cd.FrontendManager;
             ChatModel chat = cd.Chat;
             string channel;
             if (cd.DataArray.Length >= 3) {
@@ -1800,13 +1912,19 @@ namespace Smuxi.Engine
             if (cd.DataArray.Length >= 2) {
                 if (!_IrcClient.IsJoined(channel, cd.DataArray[1])) {
                     _IrcClient.RfcInvite(cd.DataArray[1], channel);
-                    fm.AddTextToChat(chat, "-!- " + String.Format(
-                                                        _("Inviting {0} to {1}"),
-                                                        cd.DataArray[1], channel));
+                    var msg = CreateMessageBuilder().
+                        AppendEventPrefix().
+                        AppendText(_("Inviting {0} to {1}"),
+                                   cd.DataArray[1], channel).
+                        ToMessage();
+                    cd.FrontendManager.AddMessageToChat(chat, msg);
                 } else {
-                    fm.AddTextToChat(chat, "-!- " + String.Format(
-                                                        _("{0} is already on {1}"),
-                                                        cd.DataArray[1], channel));
+                    var msg = CreateMessageBuilder().
+                        AppendEventPrefix().
+                        AppendText(_("{0} is already on {1}"),
+                                   cd.DataArray[1], channel).
+                        ToMessage();
+                    cd.FrontendManager.AddMessageToChat(chat, msg);
                 }
             } else {
                 _NotEnoughParameters(cd);
@@ -1898,7 +2016,7 @@ namespace Smuxi.Engine
 
             var builder = CreateMessageBuilder();
             builder.AppendActionPrefix();
-            builder.AppendIdendityName(MyPerson);
+            builder.AppendIdendityName(Me);
             builder.AppendText(" ");
             builder.AppendMessage(cd.Parameter);
             Session.AddMessageToChat(cd.Chat, builder.ToMessage(), true);
@@ -1921,8 +2039,11 @@ namespace Smuxi.Engine
                 if (chat == null) {
                     chat = _NetworkChat;
                 }
-                Session.AddTextToChat(chat, "[notice(" + target + ")] " +
-                                      message, true);
+                var msg = CreateMessageBuilder().
+                    AppendText("[notice({0})] ", target).
+                    AppendMessage(message).
+                    ToMessage();
+                Session.AddMessageToChat(chat, msg, true);
             }
         }
         
@@ -1971,7 +2092,7 @@ namespace Smuxi.Engine
 #if LOG4NET
                         _Logger.Warn("_Run(): _Listen() returned.");
 #endif
-                    } catch (ThreadAbortException ex) {
+                    } catch (ThreadAbortException) {
                         throw;
                     } catch (Exception ex) {
 #if LOG4NET
@@ -1984,7 +2105,7 @@ namespace Smuxi.Engine
                     // sleep for 10 seconds, we don't want to be abusive
                     System.Threading.Thread.Sleep(10000);
                 }
-            } catch (ThreadAbortException ex) {
+            } catch (ThreadAbortException) {
 #if LOG4NET
                 _Logger.Debug("_Run(): thread aborted");
 #endif
@@ -2003,110 +2124,32 @@ namespace Smuxi.Engine
             try {
                 _IrcClient.Listen();
             } catch (Exception ex) {
-                Session.AddTextToChat(_NetworkChat, "-!- " + _("Connection error! Reason: ") + ex.Message);
+                var msg = CreateMessageBuilder().
+                    AppendEventPrefix().
+                    AppendText(_("Connection error! Reason: ")).
+                    AppendText(ex.Message).
+                    ToMessage();
+                Session.AddMessageToChat(Chat, msg);
                 throw;
             }
         }
         
         private void _NotEnoughParameters(CommandModel cd)
         {
-            cd.FrontendManager.AddTextToChat(
-                cd.Chat,
-                String.Format("-!- {0}",
-                    String.Format(_("Not enough parameters for {0} command"),
-                        cd.Command
-                    )
-                )
-            );
+            var msg = CreateMessageBuilder().
+                AppendEventPrefix().
+                AppendText(_("Not enough parameters for {0} command"), cd.Command).
+                ToMessage();
+            cd.FrontendManager.AddMessageToChat(cd.Chat, msg);
         }
         
         private void _NotConnected(CommandModel cd)
         {
-            cd.FrontendManager.AddTextToChat(
-                cd.Chat, String.Format("-!- {0}", _("Not connected to server"))
-            );
-        }
-
-        protected override bool ContainsHighlight (string msg)
-        {
-            Regex regex;
-            // First check to see if our current nick is in there.
-            regex = new Regex(String.Format("(^|\\W){0}($|\\W)",
-                                            Regex.Escape(_IrcClient.Nickname)),
-                              RegexOptions.IgnoreCase);
-            if (regex.Match(msg).Success) {
-                return true;
-            } else {
-                return base.ContainsHighlight(msg);
-            }
-        }
-
-        private void ClearHighlights(MessageModel msg)
-        {
-            if (msg == null) {
-                throw new ArgumentNullException("msg");
-            }
-
-            foreach (MessagePartModel msgPart in msg.MessageParts) {
-                if (!msgPart.IsHighlight || !(msgPart is TextMessagePartModel)) {
-                    continue;
-                }
-
-                TextMessagePartModel textMsg = (TextMessagePartModel) msgPart;
-                textMsg.IsHighlight = false;
-                textMsg.ForegroundColor = null;
-            }
-        }
-
-        private void MarkHighlights(MessageModel msg)
-        {
-            if (msg == null) {
-                throw new ArgumentNullException("msg");
-            }
-
-            bool containsHighlight = false;
-            foreach (MessagePartModel msgPart in msg.MessageParts) {
-                if (!(msgPart is TextMessagePartModel)) {
-                    continue;
-                }
-
-                TextMessagePartModel textMsg = (TextMessagePartModel) msgPart;
-                if (String.IsNullOrEmpty(textMsg.Text)) {
-                    // URLs without a link name don't have text
-                    continue;
-                }
-                if (ContainsHighlight(textMsg.Text)) {
-                    containsHighlight = true;
-                }
-            }
-
-            if (!containsHighlight) {
-                // nothing to do
-                return;
-            }
-
-            // colorize the whole message
-            var highlightColor = TextColor.Parse(
-                (string) Session.UserConfig["Interface/Notebook/Tab/HighlightColor"]
-            );
-            foreach (MessagePartModel msgPart in msg.MessageParts) {
-                if (!(msgPart is TextMessagePartModel)) {
-                    continue;
-                }
-
-                TextMessagePartModel textMsg = (TextMessagePartModel) msgPart;
-                if (textMsg.ForegroundColor != null &&
-                    textMsg.ForegroundColor != TextColor.None) {
-                    // HACK: don't overwrite colors as that would replace
-                    // nick-colors for example
-                    continue;
-                }
-                // HACK: we have to mark all parts as highlight else
-                // ClearHighlights() has no chance to properly undo all
-                // highlights
-                textMsg.IsHighlight = true;
-                textMsg.ForegroundColor = highlightColor;
-            }
+            var msg = CreateMessageBuilder().
+                AppendEventPrefix().
+                AppendText(_("Not connected to server")).
+                ToMessage();
+            cd.FrontendManager.AddMessageToChat(cd.Chat, msg);
         }
 
         private void ApplyConfig(UserConfig config, ServerModel server)
@@ -2143,6 +2186,12 @@ namespace Smuxi.Engine
                 _Nicknames = (string[]) config["Connection/Nicknames"];
             }
 
+            // add fallbacks if only one nick was specified, else we get random
+            // number nicks when nick collisions happen
+            if (_Nicknames.Length == 1) {
+                _Nicknames = new string[] { _Nicknames[0], _Nicknames[0] + "_", _Nicknames[0] + "__" };
+            }
+
             string encodingName = (string) config["Connection/Encoding"];
             if (String.IsNullOrEmpty(encodingName)) {
                 _IrcClient.Encoding = Encoding.Default;
@@ -2223,19 +2272,16 @@ namespace Smuxi.Engine
                        handled = true;
                         break;
                     case ReceiveType.WhoIs:
-                        _OnReceiveTypeWhois(e);
-                       handled = true;
-                        break;
                     case ReceiveType.WhoWas:
-                        _OnReceiveTypeWhowas(e);
-                        handled = true;
+                        _OnReceiveTypeWho(e);
+                       handled = true;
                         break;
                 }
             }
 
             string chan;
             string nick;
-            string msg;
+            MessageModel msg;
             ChatModel chat;
             switch (e.Data.ReplyCode) {
                 case ReplyCode.Null:
@@ -2289,13 +2335,12 @@ namespace Smuxi.Engine
                     break;
                 case ReplyCode.ErrorNoSuchNickname:
                     nick = e.Data.RawMessageArray[3];
-                    msg = "-!- " + String.Format(_("{0}: No such nick/channel"), nick);
-                    chat = GetChat(nick, ChatType.Person);
-                    if (chat != null) {
-                        Session.AddTextToChat(chat, msg);
-                    } else {
-                        Session.AddTextToChat(_NetworkChat, msg);
-                    }
+                    chat = GetChat(nick, ChatType.Person) ?? Chat;
+                    msg = CreateMessageBuilder().
+                        AppendEventPrefix().
+                        AppendText(_("{0}: No such nick/channel"), nick).
+                        ToMessage();
+                    Session.AddMessageToChat(chat, msg);
                     break;
                 case ReplyCode.ErrorChannelIsFull:
                 case ReplyCode.ErrorInviteOnlyChannel:
@@ -2305,13 +2350,13 @@ namespace Smuxi.Engine
                 case ReplyCode.ErrorCannotSendToChannel:
                 case ReplyCode.ErrorUnavailableResource:
                     chan = e.Data.RawMessageArray[3];
-                    msg = "-!- " + chan + " " + e.Data.Message;
-                    chat = GetChat(chan, ChatType.Group);
-                    if (chat != null) {
-                        Session.AddTextToChat(chat, msg);
-                    } else {
-                        Session.AddTextToChat(_NetworkChat, msg);
-                    }
+                    chat = GetChat(chan, ChatType.Group) ?? Chat;
+                    msg = CreateMessageBuilder().
+                        AppendEventPrefix().
+                        AppendText(chan).AppendSpace().
+                        AppendMessage(e.Data.Message).
+                        ToMessage();
+                    Session.AddMessageToChat(chat, msg);
 
                     // if our own nick is temporarily not available then we
                     // need to deal this like an already used nick
@@ -2415,14 +2460,14 @@ namespace Smuxi.Engine
             if (e.Data.Message.ToLower().Contains("flood")) {
                 _IrcClient.SendDelay += 250;
 
-                Session.AddTextToChat(
-                    _NetworkChat,
-                    "-!- " + String.Format(
-                         _("Increased send delay to {0}ms to avoid being " +
-                           "flooded off the server again."),
+                var msg = CreateMessageBuilder().
+                    AppendEventPrefix().
+                    AppendText(
+                        _("Increased send delay to {0}ms to avoid being " +
+                          "flooded off the server again."),
                         _IrcClient.SendDelay
-                    )
-                );
+                    ).ToMessage();
+                Session.AddMessageToChat(Chat, msg);
             }
         }
         
@@ -2464,8 +2509,9 @@ namespace Smuxi.Engine
             Session.AddMessageToChat(_NetworkChat, builder.ToMessage());
         }
         
-        private void _OnReceiveTypeWhois(IrcEventArgs e)
+        private void _OnReceiveTypeWho(IrcEventArgs e)
         {
+            MessageModel msg;
             string nick = e.Data.RawMessageArray[3];
             ChatModel chat = GetChat(nick, ChatType.Person);
             if (chat == null) {
@@ -2473,16 +2519,30 @@ namespace Smuxi.Engine
             }
             switch (e.Data.ReplyCode) {
                 case ReplyCode.WhoIsUser:
+                case ReplyCode.WhoWasUser:
                     string ident = e.Data.RawMessageArray[4];
                     string host = e.Data.RawMessageArray[5];
                     string realname = e.Data.Message;
-                    Session.AddTextToChat(chat, "-!- " + nick + " [" + ident + "@" + host + "]");
-                    Session.AddTextToChat(chat, "-!-  realname: " + realname);
+                    msg = CreateMessageBuilder().
+                        AppendEventPrefix().
+                        AppendText("{0} [{1}@{2}]", nick, ident, host).
+                        ToMessage();
+                    Session.AddMessageToChat(chat, msg);
+
+                    msg = CreateMessageBuilder().
+                        AppendEventPrefix().AppendSpace().
+                        AppendText("realname: {0}", realname).
+                        ToMessage();
+                    Session.AddMessageToChat(chat, msg);
                     break;
                 case ReplyCode.WhoIsServer:
                     string server = e.Data.RawMessageArray[4];
                     string serverinfo = e.Data.Message;
-                    Session.AddTextToChat(chat, "-!-  server: " + server + " [" + serverinfo + "]");
+                    msg = CreateMessageBuilder().
+                        AppendEventPrefix().AppendSpace().
+                        AppendText("server: {0} [{1}]", server, serverinfo).
+                        ToMessage();
+                    Session.AddMessageToChat(chat, msg);
                     break;
                 case ReplyCode.WhoIsIdle:
                     string idle = e.Data.RawMessageArray[4];
@@ -2490,48 +2550,40 @@ namespace Smuxi.Engine
                         long timestamp = Int64.Parse(e.Data.RawMessageArray[5]);
                         DateTime signon =  new DateTime(1970, 1, 1, 0, 0, 0, 0);
                         signon = signon.AddSeconds(timestamp).ToLocalTime();
-                        Session.AddTextToChat(chat, "-!-  idle: "+idle+" [signon: "+signon.ToString()+"]");
+                        msg = CreateMessageBuilder().
+                            AppendEventPrefix().AppendSpace().
+                            AppendText("idle: {0} [signon: {1}]",
+                                       idle, signon.ToString()).
+                            ToMessage();
+                        Session.AddMessageToChat(chat, msg);
                     } catch (FormatException) {
                     }
                     break;
                 case ReplyCode.WhoIsChannels:
                     string channels = e.Data.Message;
-                    Session.AddTextToChat(chat, "-!-  channels: " + channels);
+                    msg = CreateMessageBuilder().
+                        AppendEventPrefix().AppendSpace().
+                        AppendText("channels: {0}", channels).
+                        ToMessage();
+                    Session.AddMessageToChat(chat, msg);
                     break;
                 case ReplyCode.WhoIsOperator:
-                    Session.AddTextToChat(chat, "-!-  " + e.Data.Message);
-                    break;
                 case ReplyCode.EndOfWhoIs:
-                    Session.AddTextToChat(chat, "-!-  " + e.Data.Message);
-                    break;
-            }
-        }
-        
-        private void _OnReceiveTypeWhowas(IrcEventArgs e)
-        {
-            string nick = e.Data.RawMessageArray[3];
-            ChatModel chat = GetChat(nick, ChatType.Person);
-            if (chat == null) {
-                chat = _NetworkChat;
-            }
-            switch (e.Data.ReplyCode) {
-                case ReplyCode.WhoWasUser:
-                    string ident = e.Data.RawMessageArray[4];
-                    string host = e.Data.RawMessageArray[5];
-                    string realname = e.Data.Message;
-                    Session.AddTextToChat(chat, "-!- " + nick + " [" + ident + "@" + host + "]");
-                    Session.AddTextToChat(chat, "-!-  realname: " + realname);
-                    break;
                 case ReplyCode.EndOfWhoWas:
-                    Session.AddTextToChat(chat, "-!-  " + e.Data.Message);
+                    msg = CreateMessageBuilder().
+                        AppendEventPrefix().AppendSpace().
+                        AppendText(e.Data.Message).
+                        ToMessage();
+                    Session.AddMessageToChat(chat, msg);
                     break;
             }
         }
         
         private void _OnCtcpRequest(object sender, CtcpEventArgs e)
         {
-            Session.AddTextToChat(_NetworkChat,
-                String.Format(
+            var msg = CreateMessageBuilder().
+                AppendEventPrefix().
+                AppendText(
                     // TRANSLATOR: {0}: nickname, {1}: ident at host,
                     // {2}: CTCP command, {3}: own nickname, {4}: CTCP parameter
                     // example:
@@ -2540,8 +2592,9 @@ namespace Smuxi.Engine
                     e.Data.Nick, e.Data.Ident+"@"+e.Data.Host,
                     e.CtcpCommand, _IrcClient.Nickname,
                     e.CtcpParameter
-                )
-            );
+                ).
+                ToMessage();
+            Session.AddMessageToChat(Chat, msg);
         }
 
         private void _OnCtcpReply(object sender, CtcpEventArgs e)
@@ -2560,57 +2613,61 @@ namespace Smuxi.Engine
                     DateTime sent = DateTime.FromFileTime(timestamp);
                     string duration = DateTime.Now.Subtract(sent).TotalSeconds.ToString();
 
-                    Session.AddTextToChat(chat, String.Format(
-                                                    _("CTCP PING reply from {0}: {1} seconds"),
-                                                    e.Data.Nick, duration));
-
-
+                    var msg = CreateMessageBuilder().
+                        AppendEventPrefix().
+                        AppendText(_("CTCP PING reply from {0}: {1} seconds"),
+                                   e.Data.Nick, duration).
+                        ToMessage();
+                    Session.AddMessageToChat(chat, msg);
                 } catch (FormatException) {
                 }
             } else {
-                Session.AddTextToChat(chat, String.Format(
-                                            _("CTCP {0} reply from {1}: {2}"),
-                                            e.CtcpCommand, e.Data.Nick, e.CtcpParameter));
+                var msg = CreateMessageBuilder().
+                    AppendEventPrefix().
+                    AppendText(_("CTCP {0} reply from {1}: {2}"),
+                               e.CtcpCommand, e.Data.Nick, e.CtcpParameter).
+                    ToMessage();
+                Session.AddMessageToChat(chat, msg);
             }
         }
 
         private void _OnChannelMessage(object sender, IrcEventArgs e)
         {
-            ChatModel chat = GetChat(e.Data.Channel, ChatType.Group) ?? _NetworkChat;
+            var chat = GetChat(e.Data.Channel, ChatType.Group) ?? Chat;
 
             var builder = CreateMessageBuilder();
             builder.AppendMessage(GetPerson(chat, e.Data.Nick), e.Data.Message);
+            builder.MarkHighlights();
 
             var msg = builder.ToMessage();
-            MarkHighlights(msg);
             Session.AddMessageToChat(chat, msg);
         }
         
         private void _OnChannelAction(object sender, ActionEventArgs e)
         {
-            ChatModel chat = GetChat(e.Data.Channel, ChatType.Group);
+            var chat = GetChat(e.Data.Channel, ChatType.Group) ?? Chat;
 
             var builder = CreateMessageBuilder();
             builder.AppendActionPrefix();
             builder.AppendIdendityName(GetPerson(chat, e.Data.Nick));
             builder.AppendText(" ");
             builder.AppendMessage(e.ActionMessage);
-            
+            builder.MarkHighlights();
+
             var msg = builder.ToMessage();
-            MarkHighlights(msg);
             Session.AddMessageToChat(chat, msg);
         }
         
         private void _OnChannelNotice(object sender, IrcEventArgs e)
         {
-            ChatModel chat = GetChat(e.Data.Channel, ChatType.Group);
+            var chat = GetChat(e.Data.Channel, ChatType.Group) ?? Chat;
 
             var builder = CreateMessageBuilder();
             builder.AppendText("-{0}:{1}- ", e.Data.Nick, e.Data.Channel);
             builder.AppendMessage(e.Data.Message);
+            builder.MarkHighlights();
 
             var msg = builder.ToMessage();
-            MarkHighlights(msg);
             Session.AddMessageToChat(chat, msg);
         }
         
@@ -2630,6 +2687,7 @@ namespace Smuxi.Engine
             var builder = CreateMessageBuilder();
             builder.AppendSenderPrefix(chat.Person, true);
             builder.AppendMessage(e.Data.Message);
+            builder.MarkHighlights();
             var msg = builder.ToMessage();
 
             if (newChat) {
@@ -2663,9 +2721,9 @@ namespace Smuxi.Engine
             builder.AppendIdendityName(chat.Person, true);
             builder.AppendSpace();
             builder.AppendMessage(e.ActionMessage);
-            var msg = builder.ToMessage();
-            MarkHighlights(msg);
+            builder.MarkHighlights();
 
+            var msg = builder.ToMessage();
             if (newChat) {
                 // don't create chats for filtered messages
                 if (Session.IsFilteredMessage(chat, msg)) {
@@ -2692,18 +2750,16 @@ namespace Smuxi.Engine
                 // 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);
-                        }
+                foreach (var chat in Chats) {
+                    if (!(chat is GroupChatModel)) {
+                        continue;
+                    }
+                    var groupChat = (GroupChatModel) chat;
+                    if (groupChat.UnsafePersons == null) {
+                        continue;
+                    }
+                    if (groupChat.UnsafePersons.ContainsKey(e.Data.Nick)) {
+                        targetChats.Add(groupChat);
                     }
                 }
             }
@@ -2723,9 +2779,9 @@ namespace Smuxi.Engine
                 builder.AppendText(" ({0}@{1})- ", e.Data.Ident, e.Data.Host);
             }
             builder.AppendMessage(e.Data.Message);
-            var msg = builder.ToMessage();
-            MarkHighlights(msg);
+            builder.MarkHighlights();
 
+            var msg = builder.ToMessage();
             foreach (var targetChat in targetChats) {
                 Session.AddMessageToChat(targetChat, msg);
             }
@@ -2755,7 +2811,7 @@ namespace Smuxi.Engine
                 // someone else joined, let's add him to the channel chat
                 // HACK: some buggy networks might send JOIN messages for users
                 // that are already on the channel
-                if (groupChat.UnsafePersons.ContainsKey(e.Who.ToLower())) {
+                if (groupChat.UnsafePersons.ContainsKey(e.Who)) {
 #if LOG4NET
                    _Logger.Error("_OnJoin(): groupChat.UnsafePerson contains " +
                                   "already: '" + e.Who + "', ignoring...");
@@ -2766,7 +2822,6 @@ namespace Smuxi.Engine
                     var icuser = CreateGroupPerson(e.Who);
                     icuser.Ident = siuser.Ident;
                     icuser.Host = siuser.Host;
-                    groupChat.UnsafePersons.Add(icuser.NickName.ToLower(), icuser);
                     Session.AddPersonToGroupChat(groupChat, icuser);
                 }
             }
@@ -2818,7 +2873,7 @@ namespace Smuxi.Engine
                 
                 var groupPerson = CreateGroupPerson(username);
                 
-                groupChat.UnsafePersons.Add(groupPerson.NickName.ToLower(), groupPerson);
+                groupChat.UnsafePersons.Add(groupPerson.NickName, groupPerson);
 #if LOG4NET
                 // logging noise
                 //_Logger.Debug("_OnNames() added user: " + username + " to: " + groupChat.Name);
@@ -2952,8 +3007,8 @@ namespace Smuxi.Engine
             _Logger.Debug("_OnNickChange() e.OldNickname: "+e.OldNickname+" e.NewNickname: "+e.NewNickname);
 #endif
             if (e.Data.Irc.IsMe(e.NewNickname)) {
-                _MyPerson = CreatePerson(e.NewNickname, MyPerson.RealName,
-                                         MyPerson.Ident, MyPerson.Host);
+                IrcMe = CreatePerson(e.NewNickname, IrcMe.RealName,
+                                     IrcMe.Ident, IrcMe.Host);
 
                 var builder = CreateMessageBuilder();
                 builder.AppendEventPrefix();
@@ -3024,7 +3079,6 @@ namespace Smuxi.Engine
             builder = CreateMessageBuilder();
             builder.AppendEventPrefix();
 
-            string who;
             if (String.IsNullOrEmpty(e.Who)) {
                 // server changed topic
                 builder.AppendText(e.Data.From);
@@ -3105,7 +3159,10 @@ namespace Smuxi.Engine
             ChatModel target = null;
             switch (e.Data.Type) {
                 case ReceiveType.UserModeChange:
-                    modechange = e.Data.Message;
+                    modechange = e.Data.RawMessageArray[3];
+                    if (modechange.StartsWith(":")) {
+                        modechange = modechange.Substring(1);
+                    }
                     who = e.Data.Irc.Nickname;
                     target = _NetworkChat;
 
@@ -3117,7 +3174,7 @@ namespace Smuxi.Engine
                 case ReceiveType.ChannelModeChange:
                     modechange = String.Join(" ", e.Data.RawMessageArray, 3,
                                              e.Data.RawMessageArray.Length - 3);
-                    target = GetChat(e.Data.Channel, ChatType.Group);
+                    target = GetChat(e.Data.Channel, ChatType.Group) ?? Chat;
 
                     // TRANSLATOR: do NOT change the position of {2}!
                     builder.AppendText(_("mode/{0} [{1}] by {2}"),
@@ -3189,7 +3246,7 @@ namespace Smuxi.Engine
             OnConnected(EventArgs.Empty);
 
             // preliminary person
-            _MyPerson = CreatePerson(_IrcClient.Nickname);
+            Me = CreatePerson(_IrcClient.Nickname);
 
             // WHO ourself so OnWho() can retrieve our ident, host and realname
             _IrcClient.RfcWho(_IrcClient.Nickname);
@@ -3282,20 +3339,31 @@ namespace Smuxi.Engine
                 }
                 ircperson.IsAwaySeen = true;
             }
-            Session.AddTextToChat(chat, "-!- " + String.Format(
-                                                    _("{0} is away: {1}"),
-                                                    e.Who, e.AwayMessage));
+            var msg = CreateMessageBuilder().
+                AppendEventPrefix().
+                AppendText(_("{0} is away: {1}"),
+                           e.Who, e.AwayMessage).
+                ToMessage();
+            Session.AddMessageToChat(chat, msg);
         }
 
         private void _OnUnAway(object sender, IrcEventArgs e)
         {
-            Session.AddTextToChat(_NetworkChat, "-!- " + _("You are no longer marked as being away"));
+            var msg = CreateMessageBuilder().
+                AppendEventPrefix().
+                AppendText(_("You are no longer marked as being away")).
+                ToMessage();
+            Session.AddMessageToChat(Chat, msg);
             Session.UpdateNetworkStatus();
         }
         
         private void _OnNowAway(object sender, IrcEventArgs e)
         {
-            Session.AddTextToChat(_NetworkChat, "-!- " + _("You have been marked as being away"));
+            var msg = CreateMessageBuilder().
+                AppendEventPrefix().
+                AppendText(_("You have been marked as being away")).
+                ToMessage();
+            Session.AddMessageToChat(Chat, msg);
             Session.UpdateNetworkStatus();
         }
         
@@ -3324,7 +3392,7 @@ namespace Smuxi.Engine
                     }
                     _LastLag = lag;
                 }
-            } catch (ThreadAbortException ex) {
+            } catch (ThreadAbortException) {
 #if LOG4NET
                 _Logger.Debug("_LagWatcher(): thread aborted");
 #endif
@@ -3346,38 +3414,33 @@ namespace Smuxi.Engine
                    _IrcClient.Encoding.GetByteCount(message) + 2;
         }
 
-        private IrcPersonModel GetPerson(ChatModel chat, string nick)
+        // HACK: workaround a compiler bug in Mono
+#if __MonoCS__
+        protected new T GetPerson<T>(ChatModel chat, string nick) where T : PersonModel
+#else
+        protected override T GetPerson<T>(ChatModel chat, string nick)
+#endif
         {
+            var person = base.GetPerson<T>(chat, nick);
+#if LOG4NET
             if (chat == null) {
-                throw new ArgumentNullException("chat");
+                _Logger.Warn("GetPerson(" + chat + ", " + nick + "): chat is null!");
             }
-            if (nick == null) {
-                throw new ArgumentNullException("nick");
-            }
-
-            IrcPersonModel person = null;
-            if (chat is GroupChatModel) {
-                var groupChat = (GroupChatModel) chat;
-                person = (IrcPersonModel) groupChat.GetPerson(nick);
-            } else if (chat is PersonChatModel) {
-                var personChat = (PersonChatModel) chat;
-                if (nick == personChat.Person.ID) {
-                    person = (IrcPersonModel) personChat.Person;
-                } else if (nick == MyPerson.ID) {
-                    person = MyPerson;
-                }
-            }
-
             if (person == null) {
-#if LOG4NET
                 _Logger.Warn("GetPerson(" + chat + ", " + nick + "): person is null!");
+            }
 #endif
-                person = CreatePerson(nick);
+            if (chat == null || person == null) {
+                person = (T)(object) CreatePerson(nick);
             }
-
             return person;
         }
 
+        IrcPersonModel GetPerson(ChatModel chat, string nick)
+        {
+            return GetPerson<IrcPersonModel>(chat, nick);
+        }
+
         private IrcPersonModel CreatePerson(string nick)
         {
             return CreatePerson(nick, null, null, null);
@@ -3429,11 +3492,9 @@ namespace Smuxi.Engine
             return null;
         }
 
-        protected override MessageBuilder CreateMessageBuilder()
+        protected override T CreateMessageBuilder<T>()
         {
-            var builder = new IrcMessageBuilder();
-            builder.ApplyConfig(Session.UserConfig);
-            return builder;
+            return (T)(object) base.CreateMessageBuilder<IrcMessageBuilder>();
         }
 
         void AutoRenick()
diff --git a/src/Engine-MSNP/AssemblyInfo.cs b/src/Engine-MSNP/AssemblyInfo.cs
deleted file mode 100644
index 816c4d5..0000000
--- a/src/Engine-MSNP/AssemblyInfo.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * $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>
- *
- * 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.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-[assembly: AssemblyTitle("Smuxi - MSNP protocol support for engine")]
-[assembly: AssemblyCopyright("2005-2008 (C) Mirco Bauer <meebey at meebey.net>")]
-
-[assembly: AssemblyDelaySign(false)]
-[assembly: AssemblyKeyFile("")]
-
-[assembly: CLSCompliant(true)]
-[assembly: ComVisible(false)]
diff --git a/src/Engine-MSNP/ChangeLog b/src/Engine-MSNP/ChangeLog
deleted file mode 100644
index 383c5a9..0000000
--- a/src/Engine-MSNP/ChangeLog
+++ /dev/null
@@ -1,47 +0,0 @@
-2008-12-28  Mirco Bauer <meebey at meebey.net> 
-
-	* Makefile.am: Replaced hardcoded gmcs calls with configure variable.
-
-2008-08-28  Mirco Bauer <meebey at meebey.net> 
-
-	* AssemblyInfo.cs, Protocols/Msnp/MsnpProtocolManager.cs: Set eol-style to
-	  native and converted files using dos2unix where needed.
-
-2008-07-27  Mirco Bauer <meebey at meebey.net> 
-
-	* Engine-MSNP.mdp: Removed assembly attributes that are now part of the
-	  shared AssemblyVersion.cs file.
-
-2008-07-17  Mirco Bauer <meebey at meebey.net> 
-
-	* AssemblyInfo.cs: Bumped version to 0.6.0.
-
-2008-07-15  Mirco Bauer <meebey at meebey.net> 
-
-	* Protocols/Msnp/MsnpProtocolManager.cs: Added FindGroupChats().
-	
-	  Added OpenChat().
-	
-	  Added CloseChat().
-
-2008-06-02  Mirco Bauer <meebey at meebey.net> 
-
-	* Protocols/Msnp/MsnpProtocolManager.cs: Renamed confusing NetworkChatModel
-	  to ProtocolChatModel and ChatType.Network to ChatType.Protocol.
-
-2008-04-01  Mirco Bauer <meebey at meebey.net> 
-
-	* AssemblyInfo.cs: Bumped version to 0.5.31
-
-2008-03-04  Mirco Bauer <meebey at meebey.net> 
-
-	* Protocols/Msnp/MsnpProtocolManager.cs: Fixed network chat.
-
-2008-01-31  Mirco Bauer <meebey at meebey.net> 
-
-	* AssemblyInfo.cs: Bumped version to 0.5.30.
-
-2007-12-25  Mirco Bauer <meebey at meebey.net> 
-
-	* Engine-MSNP.mdp: Updated using MonoDevelop 0.18.1
-
diff --git a/src/Engine-MSNP/Makefile.am b/src/Engine-MSNP/Makefile.am
deleted file mode 100644
index ca04e2e..0000000
--- a/src/Engine-MSNP/Makefile.am
+++ /dev/null
@@ -1,114 +0,0 @@
-
-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-msnp.dll
-ASSEMBLY_MDB = 
-COMPILE_TARGET = library
-PROJECT_REFERENCES =  \
-	../../bin/release/smuxi-engine.dll \
-	../../bin/release/smuxi-common.dll
-BUILD_DIR = ../../bin/release
-
-LOG4NET_DLL_SOURCE=../../lib/log4net.dll
-SMUXI_ENGINE_DLL_MDB=
-MSNPSHARP_DLL_SOURCE=../../lib/MSNPSharp.dll
-NINI_DLL_SOURCE=../../lib/Nini.dll
-SMUXI_ENGINE_DLL_SOURCE=../../bin/release/smuxi-engine.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-msnp.dll
-ASSEMBLY_MDB = $(ASSEMBLY).mdb
-COMPILE_TARGET = library
-PROJECT_REFERENCES =  \
-	../../bin/debug/smuxi-engine.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
-MSNPSHARP_DLL_SOURCE=../../lib/MSNPSharp.dll
-NINI_DLL_SOURCE=../../lib/Nini.dll
-SMUXI_ENGINE_DLL_SOURCE=../../bin/debug/smuxi-engine.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) \
-	$(MSNPSHARP_DLL) \
-	$(NINI_DLL) \
-	$(SMUXI_ENGINE_DLL) \
-	$(SMUXI_COMMON_DLL)  
-
-LINUX_PKGCONFIG = \
-	$(ENGINE_MSNP_PC)  
-
-
-	
-all: $(ASSEMBLY) $(PROGRAMFILES) $(LINUX_PKGCONFIG) 
-
-FILES = \
-	$(top_srcdir)/src/AssemblyVersion.cs \
-	AssemblyInfo.cs \
-	Protocols/Msnp/MsnpProtocolManager.cs 
-
-DATA_FILES = 
-
-RESOURCES = 
-
-EXTRAS = \
-	smuxi-engine-msnp.pc.in 
-
-REFERENCES =  \
-	System \
-	Mono.Posix \
-	$(MSNPSHARP_LIBS) \
-	$(LOG4NET_LIBS)
-
-DLL_REFERENCES = 
-
-CLEANFILES = $(PROGRAMFILES) $(LINUX_PKGCONFIG) 
-
-include $(top_srcdir)/Makefile.include
-
-LOG4NET_DLL = $(BUILD_DIR)/log4net.dll
-MSNPSHARP_DLL = $(BUILD_DIR)/MSNPSharp.dll
-NINI_DLL = $(BUILD_DIR)/Nini.dll
-SMUXI_ENGINE_DLL = $(BUILD_DIR)/smuxi-engine.dll
-ENGINE_MSNP_PC = $(BUILD_DIR)/smuxi-engine-msnp.pc
-SMUXI_COMMON_DLL = $(BUILD_DIR)/smuxi-common.dll
-
-$(eval $(call emit-deploy-target,LOG4NET_DLL))
-$(eval $(call emit-deploy-target,SMUXI_ENGINE_DLL_MDB))
-$(eval $(call emit-deploy-target,MSNPSHARP_DLL))
-$(eval $(call emit-deploy-target,NINI_DLL))
-$(eval $(call emit-deploy-target,SMUXI_ENGINE_DLL))
-$(eval $(call emit-deploy-wrapper,ENGINE_MSNP_PC,smuxi-engine-msnp.pc))
-$(eval $(call emit-deploy-target,SMUXI_COMMON_DLL))
-
-
-$(build_xamlg_list): %.xaml.g.cs: %.xaml
-	xamlg '$<'
-
-$(build_resx_resources) : %.resources: %.resx
-	resgen2 '$<' '$@'
-
-$(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)
diff --git a/src/Engine-MSNP/Makefile.in b/src/Engine-MSNP/Makefile.in
deleted file mode 100644
index dab0cd4..0000000
--- a/src/Engine-MSNP/Makefile.in
+++ /dev/null
@@ -1,866 +0,0 @@
-# Makefile.in generated by automake 1.11.6 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@
-am__make_dryrun = \
-  { \
-    am__dry=no; \
-    case $$MAKEFLAGS in \
-      *\\[\ \	]*) \
-        echo 'am--echo: ; @echo "AM"  OK' | $(MAKE) -f - 2>/dev/null \
-          | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
-      *) \
-        for am__flg in $$MAKEFLAGS; do \
-          case $$am__flg in \
-            *=*|--*) ;; \
-            *n*) am__dry=yes; break;; \
-          esac; \
-        done;; \
-    esac; \
-    test $$am__dry = yes; \
-  }
-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@
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
-	$(srcdir)/smuxi-engine-msnp.pc.in \
-	$(top_srcdir)/Makefile.include ChangeLog
-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
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
-	$(ACLOCAL_M4)
-mkinstalldirs = $(install_sh) -d
-CONFIG_CLEAN_FILES = smuxi-engine-msnp.pc
-CONFIG_CLEAN_VPATH_FILES =
-am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
-am__vpath_adj = case $$p in \
-    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
-    *) f=$$p;; \
-  esac;
-am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
-am__install_max = 40
-am__nobase_strip_setup = \
-  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
-am__nobase_strip = \
-  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
-am__nobase_list = $(am__nobase_strip_setup); \
-  for p in $$list; do echo "$$p $$p"; done | \
-  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
-  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
-    if (++n[$$2] == $(am__install_max)) \
-      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
-    END { for (dir in files) print dir, files[dir] }'
-am__base_list = \
-  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
-  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
-am__uninstall_files_from_dir = { \
-  test -z "$$files" \
-    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
-    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
-         $(am__cd) "$$dir" && rm -f $$files; }; \
-  }
-am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgappdir)" \
-	"$(DESTDIR)$(linuxdesktopapplicationsdir)" \
-	"$(DESTDIR)$(linuxpkgconfigdir)" \
-	"$(DESTDIR)$(programfilesdir)" \
-	"$(DESTDIR)$(programfilesiconsdir)"
-SCRIPTS = $(bin_SCRIPTS) $(pkgapp_SCRIPTS)
-SOURCES =
-DIST_SOURCES =
-am__can_run_installinfo = \
-  case $$AM_UPDATE_INFO_DIR in \
-    n|no|NO) false;; \
-    *) (install-info --version) >/dev/null 2>&1;; \
-  esac
-DATA = $(linuxdesktopapplications_DATA) $(linuxpkgconfig_DATA) \
-	$(programfiles_DATA) $(programfilesicons_DATA)
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-ALL_LINGUAS = @ALL_LINGUAS@
-AMTAR = @AMTAR@
-AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
-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@
-GTKSPELL_CFLAGS = @GTKSPELL_CFLAGS@
-GTKSPELL_LIBS = @GTKSPELL_LIBS@
-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@
-INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
-INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
-INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
-INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
-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@
-intltool__v_merge_options_ = @intltool__v_merge_options_@
-intltool__v_merge_options_0 = @intltool__v_merge_options_0@
-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@
-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-msnp.dll
- at ENABLE_RELEASE_TRUE@ASSEMBLY = ../../bin/release/smuxi-engine-msnp.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-engine.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-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@MSNPSHARP_DLL_SOURCE = ../../lib/MSNPSharp.dll
- at ENABLE_RELEASE_TRUE@MSNPSHARP_DLL_SOURCE = ../../lib/MSNPSharp.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@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 = \
-	$(LOG4NET_DLL) \
-	$(SMUXI_ENGINE_DLL_MDB) \
-	$(MSNPSHARP_DLL) \
-	$(NINI_DLL) \
-	$(SMUXI_ENGINE_DLL) \
-	$(SMUXI_COMMON_DLL)  
-
-LINUX_PKGCONFIG = \
-	$(ENGINE_MSNP_PC)  
-
-FILES = \
-	$(top_srcdir)/src/AssemblyVersion.cs \
-	AssemblyInfo.cs \
-	Protocols/Msnp/MsnpProtocolManager.cs 
-
-DATA_FILES = 
-RESOURCES = 
-EXTRAS = \
-	smuxi-engine-msnp.pc.in 
-
-REFERENCES = \
-	System \
-	Mono.Posix \
-	$(MSNPSHARP_LIBS) \
-	$(LOG4NET_LIBS)
-
-DLL_REFERENCES = 
-CLEANFILES = $(PROGRAMFILES) $(LINUX_PKGCONFIG) $(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)
-build_sources_embed = $(build_sources:%='$(srcdir)/%')
-comma__ = ,
-get_resource_name = $(firstword $(subst $(comma__), ,$1))
-get_culture = $(lastword $(subst ., ,$(basename $1)))
-is_cultured_resource = $(and $(word 3,$(subst ., ,$1)), $(filter $(VALID_CULTURES),$(lastword $(subst ., ,$(basename $1)))))
-build_resx_list = $(foreach res, $(RESOURCES), $(if $(filter %.resx, $(call get_resource_name,$(res))),$(res),))
-build_non_culture_resx_list = $(foreach res, $(build_resx_list),$(if $(call is_cultured_resource,$(call get_resource_name,$(res))),,$(res)))
-build_non_culture_others_list = $(foreach res, $(filter-out $(build_resx_list),$(RESOURCES)),$(if $(call is_cultured_resource,$(call get_resource_name,$(res))),,$(res)))
-build_others_list = $(build_non_culture_others_list)
-build_xamlg_list = $(filter %.xaml.g.cs, $(FILES))
-
-# resgen all .resx resources
-build_resx_files = $(foreach res, $(build_resx_list), $(call get_resource_name,$(res)))
-build_resx_resources = $(build_resx_files:.resx=.resources)
-
-# embed resources for the main assembly
-build_resx_resources_hack = $(subst .resx,.resources, $(build_non_culture_resx_list))
-build_resx_resources_embed = $(build_resx_resources_hack:%='-resource:%')
-build_others_files = $(foreach res, $(build_others_list),$(call get_resource_name,$(res)))
-build_others_resources = $(build_others_files)
-build_others_resources_embed = $(build_others_list:%='-resource:$(srcdir)/%')
-build_resources = $(build_resx_resources) $(build_others_resources)
-build_resources_embed = $(build_resx_resources_embed) $(build_others_resources_embed)
-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)
-pkgappdir = $(pkglibdir)
-pkgapp_SCRIPTS = $(ASSEMBLY)
-bin_SCRIPTS = $(BINARIES)
-programfilesdir = @libdir@/@PACKAGE@
-programfiles_DATA = $(PROGRAMFILES)
-programfilesiconsdir = @libdir@/@PACKAGE@/icons
-programfilesicons_DATA = $(PROGRAMFILES_ICONS)
-linuxpkgconfigdir = @libdir@/pkgconfig
-linuxpkgconfig_DATA = $(LINUX_PKGCONFIG)
-linuxdesktopapplicationsdir = @prefix@/share/applications
-linuxdesktopapplications_DATA = $(LINUX_DESKTOPAPPLICATIONS)
-
-# generating satellite assemblies
-culture_resources = $(foreach res, $(RESOURCES), $(if $(call is_cultured_resource,$(call get_resource_name, $(res))),$(res)))
-cultures = $(sort $(foreach res, $(culture_resources), $(call get_culture,$(call get_resource_name,$(res)))))
-culture_resource_dependencies = $(BUILD_DIR)/$1/$(SATELLITE_ASSEMBLY_NAME): $(subst .resx,.resources,$2)
-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
-MSNPSHARP_DLL = $(BUILD_DIR)/MSNPSharp.dll
-NINI_DLL = $(BUILD_DIR)/Nini.dll
-SMUXI_ENGINE_DLL = $(BUILD_DIR)/smuxi-engine.dll
-ENGINE_MSNP_PC = $(BUILD_DIR)/smuxi-engine-msnp.pc
-SMUXI_COMMON_DLL = $(BUILD_DIR)/smuxi-common.dll
-all: all-am
-
-.SUFFIXES:
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/Makefile.include $(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/Engine-MSNP/Makefile'; \
-	$(am__cd) $(top_srcdir) && \
-	  $(AUTOMAKE) --foreign src/Engine-MSNP/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_srcdir)/Makefile.include:
-
-$(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):
-smuxi-engine-msnp.pc: $(top_builddir)/config.status $(srcdir)/smuxi-engine-msnp.pc.in
-	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
-install-binSCRIPTS: $(bin_SCRIPTS)
-	@$(NORMAL_INSTALL)
-	@list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \
-	if test -n "$$list"; then \
-	  echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
-	  $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
-	fi; \
-	for p in $$list; do \
-	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
-	  if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
-	done | \
-	sed -e 'p;s,.*/,,;n' \
-	    -e 'h;s|.*|.|' \
-	    -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
-	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
-	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
-	    if ($$2 == $$4) { files[d] = files[d] " " $$1; \
-	      if (++n[d] == $(am__install_max)) { \
-		print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
-	    else { print "f", d "/" $$4, $$1 } } \
-	  END { for (d in files) print "f", d, files[d] }' | \
-	while read type dir files; do \
-	     if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
-	     test -z "$$files" || { \
-	       echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \
-	       $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
-	     } \
-	; done
-
-uninstall-binSCRIPTS:
-	@$(NORMAL_UNINSTALL)
-	@list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \
-	files=`for p in $$list; do echo "$$p"; done | \
-	       sed -e 's,.*/,,;$(transform)'`; \
-	dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir)
-install-pkgappSCRIPTS: $(pkgapp_SCRIPTS)
-	@$(NORMAL_INSTALL)
-	@list='$(pkgapp_SCRIPTS)'; test -n "$(pkgappdir)" || list=; \
-	if test -n "$$list"; then \
-	  echo " $(MKDIR_P) '$(DESTDIR)$(pkgappdir)'"; \
-	  $(MKDIR_P) "$(DESTDIR)$(pkgappdir)" || exit 1; \
-	fi; \
-	for p in $$list; do \
-	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
-	  if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
-	done | \
-	sed -e 'p;s,.*/,,;n' \
-	    -e 'h;s|.*|.|' \
-	    -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
-	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
-	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
-	    if ($$2 == $$4) { files[d] = files[d] " " $$1; \
-	      if (++n[d] == $(am__install_max)) { \
-		print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
-	    else { print "f", d "/" $$4, $$1 } } \
-	  END { for (d in files) print "f", d, files[d] }' | \
-	while read type dir files; do \
-	     if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
-	     test -z "$$files" || { \
-	       echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(pkgappdir)$$dir'"; \
-	       $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(pkgappdir)$$dir" || exit $$?; \
-	     } \
-	; done
-
-uninstall-pkgappSCRIPTS:
-	@$(NORMAL_UNINSTALL)
-	@list='$(pkgapp_SCRIPTS)'; test -n "$(pkgappdir)" || exit 0; \
-	files=`for p in $$list; do echo "$$p"; done | \
-	       sed -e 's,.*/,,;$(transform)'`; \
-	dir='$(DESTDIR)$(pkgappdir)'; $(am__uninstall_files_from_dir)
-
-mostlyclean-libtool:
-	-rm -f *.lo
-
-clean-libtool:
-	-rm -rf .libs _libs
-install-linuxdesktopapplicationsDATA: $(linuxdesktopapplications_DATA)
-	@$(NORMAL_INSTALL)
-	@list='$(linuxdesktopapplications_DATA)'; test -n "$(linuxdesktopapplicationsdir)" || list=; \
-	if test -n "$$list"; then \
-	  echo " $(MKDIR_P) '$(DESTDIR)$(linuxdesktopapplicationsdir)'"; \
-	  $(MKDIR_P) "$(DESTDIR)$(linuxdesktopapplicationsdir)" || exit 1; \
-	fi; \
-	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)$(linuxdesktopapplicationsdir)'"; \
-	  $(INSTALL_DATA) $$files "$(DESTDIR)$(linuxdesktopapplicationsdir)" || exit $$?; \
-	done
-
-uninstall-linuxdesktopapplicationsDATA:
-	@$(NORMAL_UNINSTALL)
-	@list='$(linuxdesktopapplications_DATA)'; test -n "$(linuxdesktopapplicationsdir)" || list=; \
-	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	dir='$(DESTDIR)$(linuxdesktopapplicationsdir)'; $(am__uninstall_files_from_dir)
-install-linuxpkgconfigDATA: $(linuxpkgconfig_DATA)
-	@$(NORMAL_INSTALL)
-	@list='$(linuxpkgconfig_DATA)'; test -n "$(linuxpkgconfigdir)" || list=; \
-	if test -n "$$list"; then \
-	  echo " $(MKDIR_P) '$(DESTDIR)$(linuxpkgconfigdir)'"; \
-	  $(MKDIR_P) "$(DESTDIR)$(linuxpkgconfigdir)" || exit 1; \
-	fi; \
-	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)$(linuxpkgconfigdir)'"; \
-	  $(INSTALL_DATA) $$files "$(DESTDIR)$(linuxpkgconfigdir)" || exit $$?; \
-	done
-
-uninstall-linuxpkgconfigDATA:
-	@$(NORMAL_UNINSTALL)
-	@list='$(linuxpkgconfig_DATA)'; test -n "$(linuxpkgconfigdir)" || list=; \
-	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	dir='$(DESTDIR)$(linuxpkgconfigdir)'; $(am__uninstall_files_from_dir)
-install-programfilesDATA: $(programfiles_DATA)
-	@$(NORMAL_INSTALL)
-	@list='$(programfiles_DATA)'; test -n "$(programfilesdir)" || list=; \
-	if test -n "$$list"; then \
-	  echo " $(MKDIR_P) '$(DESTDIR)$(programfilesdir)'"; \
-	  $(MKDIR_P) "$(DESTDIR)$(programfilesdir)" || exit 1; \
-	fi; \
-	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)$(programfilesdir)'"; \
-	  $(INSTALL_DATA) $$files "$(DESTDIR)$(programfilesdir)" || exit $$?; \
-	done
-
-uninstall-programfilesDATA:
-	@$(NORMAL_UNINSTALL)
-	@list='$(programfiles_DATA)'; test -n "$(programfilesdir)" || list=; \
-	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	dir='$(DESTDIR)$(programfilesdir)'; $(am__uninstall_files_from_dir)
-install-programfilesiconsDATA: $(programfilesicons_DATA)
-	@$(NORMAL_INSTALL)
-	@list='$(programfilesicons_DATA)'; test -n "$(programfilesiconsdir)" || list=; \
-	if test -n "$$list"; then \
-	  echo " $(MKDIR_P) '$(DESTDIR)$(programfilesiconsdir)'"; \
-	  $(MKDIR_P) "$(DESTDIR)$(programfilesiconsdir)" || exit 1; \
-	fi; \
-	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)$(programfilesiconsdir)'"; \
-	  $(INSTALL_DATA) $$files "$(DESTDIR)$(programfilesiconsdir)" || exit $$?; \
-	done
-
-uninstall-programfilesiconsDATA:
-	@$(NORMAL_UNINSTALL)
-	@list='$(programfilesicons_DATA)'; test -n "$(programfilesiconsdir)" || list=; \
-	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	dir='$(DESTDIR)$(programfilesiconsdir)'; $(am__uninstall_files_from_dir)
-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 $(SCRIPTS) $(DATA)
-installdirs:
-	for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgappdir)" "$(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-am: all-am
-	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
-	if test -z '$(STRIP)'; then \
-	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	      install; \
-	else \
-	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
-	fi
-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)
-	-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
-
-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-linuxdesktopapplicationsDATA \
-	install-linuxpkgconfigDATA install-pkgappSCRIPTS \
-	install-programfilesDATA install-programfilesiconsDATA
-
-install-dvi: install-dvi-am
-
-install-dvi-am:
-
-install-exec-am: install-binSCRIPTS
-
-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: uninstall-binSCRIPTS \
-	uninstall-linuxdesktopapplicationsDATA \
-	uninstall-linuxpkgconfigDATA uninstall-pkgappSCRIPTS \
-	uninstall-programfilesDATA uninstall-programfilesiconsDATA
-
-.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-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-pkgappSCRIPTS 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-pkgappSCRIPTS \
-	uninstall-programfilesDATA uninstall-programfilesiconsDATA
-
-
-all: $(ASSEMBLY) $(PROGRAMFILES) $(LINUX_PKGCONFIG) 
-
-# macros
-
-# $(call emit-deploy-target,deploy-variable-name)
-define emit-deploy-target
-$($1): $($1_SOURCE)
-	mkdir -p $$(dir $($1))
-	cp '$$<' '$$@'
-endef
-
-# $(call emit-deploy-wrapper,wrapper-variable-name,wrapper-sourcefile,x)
-# assumes that for a wrapper foo.pc its source template is foo.pc.in
-# if $3 is non-empty then wrapper is marked exec
-define emit-deploy-wrapper
-$($1): $2 
-	mkdir -p '$$(@D)'
-	cp '$$<' '$$@'
-	$(if $3,chmod +x '$$@')
-
-endef
-
-$(eval $(foreach res, $(culture_resources), $(eval $(call culture_resource_dependencies,$(call get_culture,$(call get_resource_name,$(res))),$(call get_resource_name,$(res))))))
-$(eval $(foreach res, $(culture_resources), $(eval $(call culture_resource_commandlines,$(call get_culture,$(call get_resource_name,$(res))),$(res)))))
-
-$(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,LOG4NET_DLL))
-$(eval $(call emit-deploy-target,SMUXI_ENGINE_DLL_MDB))
-$(eval $(call emit-deploy-target,MSNPSHARP_DLL))
-$(eval $(call emit-deploy-target,NINI_DLL))
-$(eval $(call emit-deploy-target,SMUXI_ENGINE_DLL))
-$(eval $(call emit-deploy-wrapper,ENGINE_MSNP_PC,smuxi-engine-msnp.pc))
-$(eval $(call emit-deploy-target,SMUXI_COMMON_DLL))
-
-$(build_xamlg_list): %.xaml.g.cs: %.xaml
-	xamlg '$<'
-
-$(build_resx_resources) : %.resources: %.resx
-	resgen2 '$<' '$@'
-
-$(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)
-
-# 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/Engine-MSNP/Protocols/Msnp/MsnpProtocolManager.cs b/src/Engine-MSNP/Protocols/Msnp/MsnpProtocolManager.cs
deleted file mode 100644
index befb934..0000000
--- a/src/Engine-MSNP/Protocols/Msnp/MsnpProtocolManager.cs
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- * $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) 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.Text;
-using System.Text.RegularExpressions;
-using System.Threading;
-using System.Collections;
-using System.Collections.Generic;
-using System.Globalization;
-/*
-using XihSolutions.DotMSN;
-using XihSolutions.DotMSN.Core;
-*/
-using MSNPSharp;
-using MSNPSharp.Core;
-using MsnPresenceStatus = MSNPSharp.PresenceStatus;
-using Smuxi.Common;
-
-namespace Smuxi.Engine
-{
-    [ProtocolManagerInfo(Name = "MSNP", Description = "MSN Messenger Protocol", Alias = "msn")]
-    public class MsnProtocolManager : MsnpProtocolManager
-    {
-        public MsnProtocolManager(Session session) : base(session)
-        {
-        }
-    }
-    
-    [ProtocolManagerInfo(Name = "MSNP", Description = "MSN Messenger Protocol", Alias = "msnp")]
-    public class MsnpProtocolManager : ProtocolManagerBase
-    {
-#if LOG4NET
-        private static readonly log4net.ILog _Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
-#endif
-        private Messenger       _MsnClient;
-        private FrontendManager _FrontendManager;
-        private ChatModel       _NetworkChat;
-        private Conversation    _Conversation;
-        private string          _UsersAddress;
-        
-        public override string NetworkID {
-            get {
-                return "MSN";
-            }
-        }
-        
-        public override string Protocol {
-            get {
-                return "MSNP";
-            }
-        }
-        
-        public override ChatModel Chat {
-            get {
-                return _NetworkChat;
-            }
-        }
-
-        public MsnpProtocolManager(Session session) : base(session)
-        {
-            Trace.Call(session);
-            
-            _MsnClient = new Messenger();
-            _MsnClient.Credentials.ClientID = "msmsgs at msnmsgr.com";
-            _MsnClient.Credentials.ClientCode = "Q1P7W2E4J9R8U3S5";   
-            
-            _MsnClient.NameserverProcessor.ConnectionEstablished += new EventHandler(NameserverProcessor_ConnectionEstablished);
-            _MsnClient.NameserverProcessor.ConnectionClosed += new EventHandler(NameserverProcessor_ConnectionClosed);
-            _MsnClient.Nameserver.AuthenticationError += new HandlerExceptionEventHandler(_NameServerAuthenticationError);
-            _MsnClient.Nameserver.SignedIn += new EventHandler(Nameserver_SignedIn);
-            _MsnClient.Nameserver.SignedOff += new SignedOffEventHandler(Nameserver_SignedOff);
-//            _MsnClient.NameserverProcessor.ConnectingException += new ProcessorExceptionEventHandler(NameserverProcessor_ConnectingException);            
-//            _MsnClient.Nameserver.ExceptionOccurred += new HandlerExceptionEventHandler(Nameserver_ExceptionOccurred);                    
-//            _MsnClient.Nameserver.AuthenticationError += new HandlerExceptionEventHandler(Nameserver_AuthenticationError);
-//            _MsnClient.Nameserver.ServerErrorReceived += new ErrorReceivedEventHandler(Nameserver_ServerErrorReceived);
-            _MsnClient.ConversationCreated += new ConversationCreatedEventHandler(MsnClient_ConversationCreated);
-            
-//            _Conversation.Switchboard.SessionClosed += new .SBChangedEventHandler(SessionClosed);
-//            _Conversation.Switchboard.ContactJoined += new .ContactChangedEventHandler(ContactJoined);
-//            _Conversation.Switchboard.ContactLeft   += new .ContactChangedEventHandler(ContactLeft);            
-        }
-        
-        public override void Connect(FrontendManager fm, ServerModel server)
-        {
-            Trace.Call(fm, server);
-
-            if (fm == null) {
-                throw new ArgumentNullException("fm");
-            }
-            if (server == null) {
-                throw new ArgumentNullException("server");
-            }
-
-            _FrontendManager = fm;
-            _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 = server.Username;
-            _MsnClient.Credentials.Password = server.Password;
-            _MsnClient.Connect();
-        }
-        
-        public override void Reconnect(FrontendManager fm)
-        {
-            Trace.Call(fm);
-        }
-        
-        public override void Disconnect(FrontendManager fm)
-        {
-            Trace.Call(fm);
-        }
-        
-        public override string ToString()
-        {
-            string result = "MSN ";
-            
-            if (!IsConnected) {
-                result += " (" + _("not connected") + ")";
-            } else {
-                result += " (" + _("connected") + ")";
-            }
-            return result;
-        }
-        
-        public override void Dispose()
-        {
-            Trace.Call();
-            
-            // we can't delete directly, it will break the enumerator, let's use a list
-            ArrayList removelist = new ArrayList();
-            lock (Session.Chats) {
-                foreach (ChatModel chat in Session.Chats) {
-                    if (chat.ProtocolManager == this) {
-                        removelist.Add(chat);
-                    }
-                }
-            }
-            
-            // now we can delete
-            foreach (ChatModel  chat in removelist) {
-                Session.RemoveChat(chat);
-            }
-        }
-        
-        public override IList<GroupChatModel> FindGroupChats(GroupChatModel filter)
-        {
-            Trace.Call(filter);
-            
-            throw new NotImplementedException();
-        }
-        
-        public override void OpenChat(FrontendManager fm, ChatModel chat)
-        {
-            Trace.Call(fm, chat);
-            
-            throw new NotImplementedException();
-        }
-
-        public override void CloseChat(FrontendManager fm, ChatModel chat)
-        {
-            Trace.Call(fm, chat);
-            
-            throw new NotImplementedException();
-        }
-
-        public override void SetPresenceStatus(PresenceStatus status,
-                                               string message)
-        {
-            Trace.Call(status, message);
-
-            // TODO: implement me
-        }
-
-        public override bool Command(CommandModel command)
-        {
-            bool handled = false;
-            if (IsConnected) {
-                if (command.IsCommand) {
-                } else {
-                    _Say(command, command.Data);
-                    handled = true;
-                }
-            } else {
-                if (command.IsCommand) {
-                    // commands which work even without beeing connected
-                    switch (command.Command) {
-                        case "help":
-                            CommandHelp(command);
-                            handled = true;
-                            break;
-                        case "connect":
-                            CommandConnect(command);
-                            handled = true;
-                            break;
-                    }
-                } else {
-                    // normal text, without connection
-                    NotConnected(command);
-                    handled = true;
-                }
-            }
-            
-            return handled;
-        }
-
-        public void CommandHelp(CommandModel cd)
-        {
-            MessageModel fmsg = new MessageModel();
-            TextMessagePartModel fmsgti;
-
-            fmsgti = new TextMessagePartModel();
-            // TRANSLATOR: this line is used as a label / category for a
-            // list of commands below
-            fmsgti.Text = "[" + _("MSN Commands") + "]";
-            fmsgti.Bold = true;
-            fmsg.MessageParts.Add(fmsgti);
-            
-            Session.AddMessageToChat(cd.Chat, fmsg);
-            
-            string[] help = {
-            "help",
-            "connect msn username password",
-            };
-            
-            foreach (string line in help) { 
-                cd.FrontendManager.AddTextToChat(cd.Chat, "-!- " + line);
-            }
-        }
-        
-        public void CommandConnect(CommandModel cd)
-        {
-            FrontendManager fm = cd.FrontendManager;
-            
-            var server = new ServerModel();
-            if (cd.DataArray.Length >= 1) {
-                server.Username = cd.DataArray[2];
-            } else {
-                NotEnoughParameters(cd);
-                return;
-            }
-            
-            if (cd.DataArray.Length >= 2) {
-                server.Password = cd.DataArray[3];
-            } else {
-                NotEnoughParameters(cd);
-                return;
-            }
-            
-            Connect(fm, server);
-        }
-        
-        private void _Say(CommandModel command, string text)
-        {
-            if (!command.Chat.IsEnabled) {
-                return;
-            }
-            
-//            string target = command.Chat.ID;
-//            
-//            _JabberClient.Message(target, text);
-            
-            MessageModel msg = new MessageModel();
-            TextMessagePartModel msgPart;
-            
-            msgPart = new TextMessagePartModel();
-            msgPart.Text = "<";
-            msg.MessageParts.Add(msgPart);
-            
-            msgPart = new TextMessagePartModel();
-            msgPart.Text = _UsersAddress;
-            //msgPart.ForegroundColor = IrcTextColor.Blue;
-            msgPart.ForegroundColor = new TextColor(0x0000FF);
-            msg.MessageParts.Add(msgPart);
-            
-            msgPart = new TextMessagePartModel();
-            msgPart.Text = "> ";
-            msg.MessageParts.Add(msgPart);
-                
-            msgPart = new TextMessagePartModel();
-            msgPart.Text = text;
-            msg.MessageParts.Add(msgPart);
-            
-                Session.AddMessageToChat(command.Chat, msg);
-        }
-        
-//        private void _OnReadText(xobject sender, string text)
-//        {
-//                Session.AddTextToChat(_NetworkChat, "-!- RECV: " + text);
-//        }
-        
-//        private void _OnWriteText(xobject sender, string text)
-//        {
-//                Session.AddTextToChat(_NetworkChat, "-!- SENT: " + text);
-//        }
-
-            
-         private void MsnClient_ConversationCreated(object sender, ConversationCreatedEventArgs e) 
-         {
-             Trace.Call(sender, e);
-            
-            
-             
-            // Session.AddTextToChat(_NetworkChat, "Conversation bla");
-            //e.Conversation.Switchboard.Co
-            //_MsnClient.Nameserver.RequestScreenName();
-            
-            // NetworkChatModel nchat = new NetworkChatModel("MSN", "MSN", this);
-             //Session.AddChat(nchat);
-             
-            e.Conversation.Switchboard.TextMessageReceived +=  delegate(object sender2, TextMessageEventArgs e2) {
-                PersonModel person = new PersonModel(e2.Sender.Name,
-                                                     e2.Sender.Name,
-                                                     NetworkID, Protocol,
-                                                     this);
-                PersonChatModel personChat = new PersonChatModel(person,
-                                                                 e2.Sender.Name,
-                                                                 e2.Sender.Name,
-                                                                 this);
-                Session.AddChat(personChat);
-                Session.AddTextToChat(personChat, e2.Message.Text);
-             };
-         }
-
-        private void TextMessageReceived(object sender, TextMessageEventArgs e) 
-        {
-            Trace.Call(sender, e);
-                
-            string user = e.Sender.Name;
-            string status = e.Sender.Status.ToString();
-            string message = e.Message.Text;
-
-            ChatModel chat = Session.GetChat(user, ChatType.Person, this);
-            if (chat == null) {
-               PersonModel person = new PersonModel(user, user, NetworkID, Protocol, this);
-                   Session.AddChat(chat);
-            }
-
-            MessageModel msg = new MessageModel();
-            TextMessagePartModel msgPart;
-
-            msgPart = new TextMessagePartModel();
-            msgPart.Text = String.Format("{0} (Status: {1}) says:\n{2}", user, status, message);
-            msg.MessageParts.Add(msgPart);
-
-            Session.AddMessageToChat(chat, msg);
-        }
-        
-//        private void _OnDisconnect(xobject sender)
-//        {
-//            IsConnected = false;
-//        }
-        
-        private void NameserverProcessor_ConnectionEstablished(object sender, EventArgs e)
-        {
-            IsConnected = true;
-            Session.AddTextToChat(_NetworkChat, "-!- Connection to MSN Server established.");
-        }        
-        
-        private void NameserverProcessor_ConnectionClosed(object sender, EventArgs e)
-        {
-            IsConnected = false;
-            Session.AddTextToChat(_NetworkChat, "-!- Connection to MSN Server closed.");
-        }
-        
-        private void Nameserver_SignedIn(object sender, EventArgs e)
-        {
-            Session.AddTextToChat(_NetworkChat, "-!- Signed into MSN.");
-            _Conversation = _MsnClient.CreateConversation();
-            _Conversation.Switchboard.TextMessageReceived += new TextMessageReceivedEventHandler(TextMessageReceived);    
-            _MsnClient.Owner.Status = MsnPresenceStatus.Online;
-            _MsnClient.Owner.Name = "Test";
-        }
-        
-        private void Nameserver_SignedOff(object sender, EventArgs e)
-        {
-            Session.AddTextToChat(_NetworkChat, "-!- Signed off in MSN.");
-        }
-        
-        private void _NameServerAuthenticationError(object sender, ExceptionEventArgs e)
-        {
-            Session.AddTextToChat(_NetworkChat, "-!- Authentication error: " + e.Exception.Message);
-            _MsnClient.Disconnect();
-        }
-        
-        private static string _(string msg)
-        {
-            return Mono.Unix.Catalog.GetString(msg);
-        }
-    }
-}
diff --git a/src/Engine-MSNP/smuxi-engine-msnp.pc.in b/src/Engine-MSNP/smuxi-engine-msnp.pc.in
deleted file mode 100644
index 0e43264..0000000
--- a/src/Engine-MSNP/smuxi-engine-msnp.pc.in
+++ /dev/null
@@ -1,6 +0,0 @@
-Name: Engine-MSNP
-Description: Engine-MSNP
-Version: @VERSION@
-
-Requires: smuxi-engine
-Libs: -r:@expanded_libdir@/@PACKAGE@/smuxi-engine-msnp.dll
diff --git a/src/Engine-OSCAR/AssemblyInfo.cs b/src/Engine-OSCAR/AssemblyInfo.cs
deleted file mode 100644
index de4b28e..0000000
--- a/src/Engine-OSCAR/AssemblyInfo.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * $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>
- *
- * 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.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-[assembly: AssemblyTitle("Smuxi - OSCAR protocol support for engine")]
-[assembly: AssemblyCopyright("2007-2008 (C) Mirco Bauer <meebey at meebey.net>")]
-
-[assembly: AssemblyDelaySign(false)]
-[assembly: AssemblyKeyFile("")]
-
-[assembly: CLSCompliant(true)]
-[assembly: ComVisible(false)]
diff --git a/src/Engine-OSCAR/ChangeLog b/src/Engine-OSCAR/ChangeLog
deleted file mode 100644
index fe2b11d..0000000
--- a/src/Engine-OSCAR/ChangeLog
+++ /dev/null
@@ -1,54 +0,0 @@
-2008-12-28  Mirco Bauer <meebey at meebey.net> 
-
-	* Makefile.am: Replaced hardcoded gmcs calls with configure variable.
-
-2008-08-28  Mirco Bauer <meebey at meebey.net> 
-
-	* Protocols/Oscar/OscarProtocolManager.cs: Set eol-style to native and
-	  converted files using dos2unix where needed.
-
-2008-07-27  Mirco Bauer <meebey at meebey.net> 
-
-	* AssemblyInfo.cs, Engine-OSCAR.mdp: Removed assembly attributes that are
-	  now part of the shared AssemblyVersion.cs file.
-
-2008-07-17  Mirco Bauer <meebey at meebey.net> 
-
-	* AssemblyInfo.cs: Bumped version to 0.6.0.
-
-2008-07-15  Mirco Bauer <meebey at meebey.net> 
-
-	* Protocols/Oscar/OscarProtocolManager.cs: Added FindGroupChats().
-	
-	  Added OpenChat().
-	
-	  Added CloseChat().
-
-2008-06-30  Mirco Bauer <meebey at meebey.net> 
-
-	
-
-2008-06-02  Mirco Bauer <meebey at meebey.net> 
-
-	* Protocols/Oscar/OscarProtocolManager.cs: Renamed confusing
-	  NetworkChatModel to ProtocolChatModel and ChatType.Network to
-	  ChatType.Protocol.
-
-2008-04-01  Mirco Bauer <meebey at meebey.net> 
-
-	* AssemblyInfo.cs: Bumped version to 0.5.31
-
-2008-03-04  Mirco Bauer <meebey at meebey.net> 
-
-	* Protocols/Oscar/OscarProtocolManager.cs: Fixed network chat.
-	
-	  Implemented private message support for AIM/ICQ.
-
-2008-01-31  Mirco Bauer <meebey at meebey.net> 
-
-	* AssemblyInfo.cs: Bumped version to 0.5.30.
-
-2007-12-25  Mirco Bauer <meebey at meebey.net> 
-
-	* Engine-OSCAR.mdp: Updated using MonoDevelop 0.18.1
-
diff --git a/src/Engine-OSCAR/Makefile.am b/src/Engine-OSCAR/Makefile.am
deleted file mode 100644
index 91fbe47..0000000
--- a/src/Engine-OSCAR/Makefile.am
+++ /dev/null
@@ -1,105 +0,0 @@
-
-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-oscar.dll
-ASSEMBLY_MDB = 
-COMPILE_TARGET = library
-PROJECT_REFERENCES =  \
-	../../bin/release/smuxi-common.dll \
-	../../bin/release/smuxi-engine.dll
-BUILD_DIR = ../../bin/release
-
-OSCARLIB_DLL_SOURCE=../../lib/OscarLib.dll
-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
-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-oscar.dll
-ASSEMBLY_MDB = $(ASSEMBLY).mdb
-COMPILE_TARGET = library
-PROJECT_REFERENCES =  \
-	../../bin/debug/smuxi-common.dll \
-	../../bin/debug/smuxi-engine.dll
-BUILD_DIR = ../../bin/debug
-
-OSCARLIB_DLL_SOURCE=../../lib/OscarLib.dll
-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
-SMUXI_COMMON_DLL_SOURCE=../../bin/debug/smuxi-common.dll
-
-endif
-
-AL=al2
-SATELLITE_ASSEMBLY_NAME=.resources.dll
-
-PROGRAMFILES = \
-	$(SMUXI_ENGINE_DLL_MDB) \
-	$(SMUXI_ENGINE_DLL) \
-	$(SMUXI_COMMON_DLL)  
-
-LINUX_PKGCONFIG = \
-	$(ENGINE_OSCAR_PC)  
-
-
-	
-all: $(ASSEMBLY) $(PROGRAMFILES) $(LINUX_PKGCONFIG) 
-
-FILES = \
-	$(top_srcdir)/src/AssemblyVersion.cs \
-	AssemblyInfo.cs \
-	Protocols/Oscar/OscarProtocolManager.cs 
-
-DATA_FILES = 
-
-RESOURCES = 
-
-EXTRAS = \
-	smuxi-engine-oscar.pc.in 
-
-REFERENCES =  \
-	Mono.Posix \
-	System \
-	$(OSCARLIB_LIBS) \
-	$(LOG4NET_LIBS)
-
-DLL_REFERENCES = 
-
-CLEANFILES = $(PROGRAMFILES) $(LINUX_PKGCONFIG) 
-
-include $(top_srcdir)/Makefile.include
-
-ENGINE_OSCAR_PC = $(BUILD_DIR)/smuxi-engine-oscar.pc
-SMUXI_ENGINE_DLL = $(BUILD_DIR)/smuxi-engine.dll
-SMUXI_COMMON_DLL = $(BUILD_DIR)/smuxi-common.dll
-
-$(eval $(call emit-deploy-target,SMUXI_ENGINE_DLL_MDB))
-$(eval $(call emit-deploy-wrapper,ENGINE_OSCAR_PC,smuxi-engine-oscar.pc))
-$(eval $(call emit-deploy-target,SMUXI_ENGINE_DLL))
-$(eval $(call emit-deploy-target,SMUXI_COMMON_DLL))
-
-
-$(build_xamlg_list): %.xaml.g.cs: %.xaml
-	xamlg '$<'
-
-$(build_resx_resources) : %.resources: %.resx
-	resgen2 '$<' '$@'
-
-$(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) $(OSCARLIB_LIBS) $(LOG4NET_LIBS)
diff --git a/src/Engine-OSCAR/Makefile.in b/src/Engine-OSCAR/Makefile.in
deleted file mode 100644
index dc3d5a3..0000000
--- a/src/Engine-OSCAR/Makefile.in
+++ /dev/null
@@ -1,857 +0,0 @@
-# Makefile.in generated by automake 1.11.6 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@
-am__make_dryrun = \
-  { \
-    am__dry=no; \
-    case $$MAKEFLAGS in \
-      *\\[\ \	]*) \
-        echo 'am--echo: ; @echo "AM"  OK' | $(MAKE) -f - 2>/dev/null \
-          | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
-      *) \
-        for am__flg in $$MAKEFLAGS; do \
-          case $$am__flg in \
-            *=*|--*) ;; \
-            *n*) am__dry=yes; break;; \
-          esac; \
-        done;; \
-    esac; \
-    test $$am__dry = yes; \
-  }
-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@
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
-	$(srcdir)/smuxi-engine-oscar.pc.in \
-	$(top_srcdir)/Makefile.include ChangeLog
-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
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
-	$(ACLOCAL_M4)
-mkinstalldirs = $(install_sh) -d
-CONFIG_CLEAN_FILES = smuxi-engine-oscar.pc
-CONFIG_CLEAN_VPATH_FILES =
-am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
-am__vpath_adj = case $$p in \
-    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
-    *) f=$$p;; \
-  esac;
-am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
-am__install_max = 40
-am__nobase_strip_setup = \
-  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
-am__nobase_strip = \
-  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
-am__nobase_list = $(am__nobase_strip_setup); \
-  for p in $$list; do echo "$$p $$p"; done | \
-  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
-  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
-    if (++n[$$2] == $(am__install_max)) \
-      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
-    END { for (dir in files) print dir, files[dir] }'
-am__base_list = \
-  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
-  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
-am__uninstall_files_from_dir = { \
-  test -z "$$files" \
-    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
-    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
-         $(am__cd) "$$dir" && rm -f $$files; }; \
-  }
-am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgappdir)" \
-	"$(DESTDIR)$(linuxdesktopapplicationsdir)" \
-	"$(DESTDIR)$(linuxpkgconfigdir)" \
-	"$(DESTDIR)$(programfilesdir)" \
-	"$(DESTDIR)$(programfilesiconsdir)"
-SCRIPTS = $(bin_SCRIPTS) $(pkgapp_SCRIPTS)
-SOURCES =
-DIST_SOURCES =
-am__can_run_installinfo = \
-  case $$AM_UPDATE_INFO_DIR in \
-    n|no|NO) false;; \
-    *) (install-info --version) >/dev/null 2>&1;; \
-  esac
-DATA = $(linuxdesktopapplications_DATA) $(linuxpkgconfig_DATA) \
-	$(programfiles_DATA) $(programfilesicons_DATA)
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-ALL_LINGUAS = @ALL_LINGUAS@
-AMTAR = @AMTAR@
-AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
-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@
-GTKSPELL_CFLAGS = @GTKSPELL_CFLAGS@
-GTKSPELL_LIBS = @GTKSPELL_LIBS@
-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@
-INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
-INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
-INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
-INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
-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@
-intltool__v_merge_options_ = @intltool__v_merge_options_@
-intltool__v_merge_options_0 = @intltool__v_merge_options_0@
-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@
-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-oscar.dll
- at ENABLE_RELEASE_TRUE@ASSEMBLY = ../../bin/release/smuxi-engine-oscar.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@OSCARLIB_DLL_SOURCE = ../../lib/OscarLib.dll
- at ENABLE_RELEASE_TRUE@OSCARLIB_DLL_SOURCE = ../../lib/OscarLib.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@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@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) \
-	$(SMUXI_ENGINE_DLL) \
-	$(SMUXI_COMMON_DLL)  
-
-LINUX_PKGCONFIG = \
-	$(ENGINE_OSCAR_PC)  
-
-FILES = \
-	$(top_srcdir)/src/AssemblyVersion.cs \
-	AssemblyInfo.cs \
-	Protocols/Oscar/OscarProtocolManager.cs 
-
-DATA_FILES = 
-RESOURCES = 
-EXTRAS = \
-	smuxi-engine-oscar.pc.in 
-
-REFERENCES = \
-	Mono.Posix \
-	System \
-	$(OSCARLIB_LIBS) \
-	$(LOG4NET_LIBS)
-
-DLL_REFERENCES = 
-CLEANFILES = $(PROGRAMFILES) $(LINUX_PKGCONFIG) $(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)
-build_sources_embed = $(build_sources:%='$(srcdir)/%')
-comma__ = ,
-get_resource_name = $(firstword $(subst $(comma__), ,$1))
-get_culture = $(lastword $(subst ., ,$(basename $1)))
-is_cultured_resource = $(and $(word 3,$(subst ., ,$1)), $(filter $(VALID_CULTURES),$(lastword $(subst ., ,$(basename $1)))))
-build_resx_list = $(foreach res, $(RESOURCES), $(if $(filter %.resx, $(call get_resource_name,$(res))),$(res),))
-build_non_culture_resx_list = $(foreach res, $(build_resx_list),$(if $(call is_cultured_resource,$(call get_resource_name,$(res))),,$(res)))
-build_non_culture_others_list = $(foreach res, $(filter-out $(build_resx_list),$(RESOURCES)),$(if $(call is_cultured_resource,$(call get_resource_name,$(res))),,$(res)))
-build_others_list = $(build_non_culture_others_list)
-build_xamlg_list = $(filter %.xaml.g.cs, $(FILES))
-
-# resgen all .resx resources
-build_resx_files = $(foreach res, $(build_resx_list), $(call get_resource_name,$(res)))
-build_resx_resources = $(build_resx_files:.resx=.resources)
-
-# embed resources for the main assembly
-build_resx_resources_hack = $(subst .resx,.resources, $(build_non_culture_resx_list))
-build_resx_resources_embed = $(build_resx_resources_hack:%='-resource:%')
-build_others_files = $(foreach res, $(build_others_list),$(call get_resource_name,$(res)))
-build_others_resources = $(build_others_files)
-build_others_resources_embed = $(build_others_list:%='-resource:$(srcdir)/%')
-build_resources = $(build_resx_resources) $(build_others_resources)
-build_resources_embed = $(build_resx_resources_embed) $(build_others_resources_embed)
-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)
-pkgappdir = $(pkglibdir)
-pkgapp_SCRIPTS = $(ASSEMBLY)
-bin_SCRIPTS = $(BINARIES)
-programfilesdir = @libdir@/@PACKAGE@
-programfiles_DATA = $(PROGRAMFILES)
-programfilesiconsdir = @libdir@/@PACKAGE@/icons
-programfilesicons_DATA = $(PROGRAMFILES_ICONS)
-linuxpkgconfigdir = @libdir@/pkgconfig
-linuxpkgconfig_DATA = $(LINUX_PKGCONFIG)
-linuxdesktopapplicationsdir = @prefix@/share/applications
-linuxdesktopapplications_DATA = $(LINUX_DESKTOPAPPLICATIONS)
-
-# generating satellite assemblies
-culture_resources = $(foreach res, $(RESOURCES), $(if $(call is_cultured_resource,$(call get_resource_name, $(res))),$(res)))
-cultures = $(sort $(foreach res, $(culture_resources), $(call get_culture,$(call get_resource_name,$(res)))))
-culture_resource_dependencies = $(BUILD_DIR)/$1/$(SATELLITE_ASSEMBLY_NAME): $(subst .resx,.resources,$2)
-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)))
-ENGINE_OSCAR_PC = $(BUILD_DIR)/smuxi-engine-oscar.pc
-SMUXI_ENGINE_DLL = $(BUILD_DIR)/smuxi-engine.dll
-SMUXI_COMMON_DLL = $(BUILD_DIR)/smuxi-common.dll
-all: all-am
-
-.SUFFIXES:
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/Makefile.include $(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/Engine-OSCAR/Makefile'; \
-	$(am__cd) $(top_srcdir) && \
-	  $(AUTOMAKE) --foreign src/Engine-OSCAR/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_srcdir)/Makefile.include:
-
-$(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):
-smuxi-engine-oscar.pc: $(top_builddir)/config.status $(srcdir)/smuxi-engine-oscar.pc.in
-	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
-install-binSCRIPTS: $(bin_SCRIPTS)
-	@$(NORMAL_INSTALL)
-	@list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \
-	if test -n "$$list"; then \
-	  echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
-	  $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
-	fi; \
-	for p in $$list; do \
-	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
-	  if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
-	done | \
-	sed -e 'p;s,.*/,,;n' \
-	    -e 'h;s|.*|.|' \
-	    -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
-	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
-	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
-	    if ($$2 == $$4) { files[d] = files[d] " " $$1; \
-	      if (++n[d] == $(am__install_max)) { \
-		print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
-	    else { print "f", d "/" $$4, $$1 } } \
-	  END { for (d in files) print "f", d, files[d] }' | \
-	while read type dir files; do \
-	     if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
-	     test -z "$$files" || { \
-	       echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \
-	       $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
-	     } \
-	; done
-
-uninstall-binSCRIPTS:
-	@$(NORMAL_UNINSTALL)
-	@list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \
-	files=`for p in $$list; do echo "$$p"; done | \
-	       sed -e 's,.*/,,;$(transform)'`; \
-	dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir)
-install-pkgappSCRIPTS: $(pkgapp_SCRIPTS)
-	@$(NORMAL_INSTALL)
-	@list='$(pkgapp_SCRIPTS)'; test -n "$(pkgappdir)" || list=; \
-	if test -n "$$list"; then \
-	  echo " $(MKDIR_P) '$(DESTDIR)$(pkgappdir)'"; \
-	  $(MKDIR_P) "$(DESTDIR)$(pkgappdir)" || exit 1; \
-	fi; \
-	for p in $$list; do \
-	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
-	  if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
-	done | \
-	sed -e 'p;s,.*/,,;n' \
-	    -e 'h;s|.*|.|' \
-	    -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
-	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
-	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
-	    if ($$2 == $$4) { files[d] = files[d] " " $$1; \
-	      if (++n[d] == $(am__install_max)) { \
-		print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
-	    else { print "f", d "/" $$4, $$1 } } \
-	  END { for (d in files) print "f", d, files[d] }' | \
-	while read type dir files; do \
-	     if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
-	     test -z "$$files" || { \
-	       echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(pkgappdir)$$dir'"; \
-	       $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(pkgappdir)$$dir" || exit $$?; \
-	     } \
-	; done
-
-uninstall-pkgappSCRIPTS:
-	@$(NORMAL_UNINSTALL)
-	@list='$(pkgapp_SCRIPTS)'; test -n "$(pkgappdir)" || exit 0; \
-	files=`for p in $$list; do echo "$$p"; done | \
-	       sed -e 's,.*/,,;$(transform)'`; \
-	dir='$(DESTDIR)$(pkgappdir)'; $(am__uninstall_files_from_dir)
-
-mostlyclean-libtool:
-	-rm -f *.lo
-
-clean-libtool:
-	-rm -rf .libs _libs
-install-linuxdesktopapplicationsDATA: $(linuxdesktopapplications_DATA)
-	@$(NORMAL_INSTALL)
-	@list='$(linuxdesktopapplications_DATA)'; test -n "$(linuxdesktopapplicationsdir)" || list=; \
-	if test -n "$$list"; then \
-	  echo " $(MKDIR_P) '$(DESTDIR)$(linuxdesktopapplicationsdir)'"; \
-	  $(MKDIR_P) "$(DESTDIR)$(linuxdesktopapplicationsdir)" || exit 1; \
-	fi; \
-	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)$(linuxdesktopapplicationsdir)'"; \
-	  $(INSTALL_DATA) $$files "$(DESTDIR)$(linuxdesktopapplicationsdir)" || exit $$?; \
-	done
-
-uninstall-linuxdesktopapplicationsDATA:
-	@$(NORMAL_UNINSTALL)
-	@list='$(linuxdesktopapplications_DATA)'; test -n "$(linuxdesktopapplicationsdir)" || list=; \
-	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	dir='$(DESTDIR)$(linuxdesktopapplicationsdir)'; $(am__uninstall_files_from_dir)
-install-linuxpkgconfigDATA: $(linuxpkgconfig_DATA)
-	@$(NORMAL_INSTALL)
-	@list='$(linuxpkgconfig_DATA)'; test -n "$(linuxpkgconfigdir)" || list=; \
-	if test -n "$$list"; then \
-	  echo " $(MKDIR_P) '$(DESTDIR)$(linuxpkgconfigdir)'"; \
-	  $(MKDIR_P) "$(DESTDIR)$(linuxpkgconfigdir)" || exit 1; \
-	fi; \
-	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)$(linuxpkgconfigdir)'"; \
-	  $(INSTALL_DATA) $$files "$(DESTDIR)$(linuxpkgconfigdir)" || exit $$?; \
-	done
-
-uninstall-linuxpkgconfigDATA:
-	@$(NORMAL_UNINSTALL)
-	@list='$(linuxpkgconfig_DATA)'; test -n "$(linuxpkgconfigdir)" || list=; \
-	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	dir='$(DESTDIR)$(linuxpkgconfigdir)'; $(am__uninstall_files_from_dir)
-install-programfilesDATA: $(programfiles_DATA)
-	@$(NORMAL_INSTALL)
-	@list='$(programfiles_DATA)'; test -n "$(programfilesdir)" || list=; \
-	if test -n "$$list"; then \
-	  echo " $(MKDIR_P) '$(DESTDIR)$(programfilesdir)'"; \
-	  $(MKDIR_P) "$(DESTDIR)$(programfilesdir)" || exit 1; \
-	fi; \
-	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)$(programfilesdir)'"; \
-	  $(INSTALL_DATA) $$files "$(DESTDIR)$(programfilesdir)" || exit $$?; \
-	done
-
-uninstall-programfilesDATA:
-	@$(NORMAL_UNINSTALL)
-	@list='$(programfiles_DATA)'; test -n "$(programfilesdir)" || list=; \
-	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	dir='$(DESTDIR)$(programfilesdir)'; $(am__uninstall_files_from_dir)
-install-programfilesiconsDATA: $(programfilesicons_DATA)
-	@$(NORMAL_INSTALL)
-	@list='$(programfilesicons_DATA)'; test -n "$(programfilesiconsdir)" || list=; \
-	if test -n "$$list"; then \
-	  echo " $(MKDIR_P) '$(DESTDIR)$(programfilesiconsdir)'"; \
-	  $(MKDIR_P) "$(DESTDIR)$(programfilesiconsdir)" || exit 1; \
-	fi; \
-	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)$(programfilesiconsdir)'"; \
-	  $(INSTALL_DATA) $$files "$(DESTDIR)$(programfilesiconsdir)" || exit $$?; \
-	done
-
-uninstall-programfilesiconsDATA:
-	@$(NORMAL_UNINSTALL)
-	@list='$(programfilesicons_DATA)'; test -n "$(programfilesiconsdir)" || list=; \
-	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	dir='$(DESTDIR)$(programfilesiconsdir)'; $(am__uninstall_files_from_dir)
-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 $(SCRIPTS) $(DATA)
-installdirs:
-	for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgappdir)" "$(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-am: all-am
-	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
-	if test -z '$(STRIP)'; then \
-	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	      install; \
-	else \
-	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
-	fi
-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)
-	-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
-
-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-linuxdesktopapplicationsDATA \
-	install-linuxpkgconfigDATA install-pkgappSCRIPTS \
-	install-programfilesDATA install-programfilesiconsDATA
-
-install-dvi: install-dvi-am
-
-install-dvi-am:
-
-install-exec-am: install-binSCRIPTS
-
-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: uninstall-binSCRIPTS \
-	uninstall-linuxdesktopapplicationsDATA \
-	uninstall-linuxpkgconfigDATA uninstall-pkgappSCRIPTS \
-	uninstall-programfilesDATA uninstall-programfilesiconsDATA
-
-.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-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-pkgappSCRIPTS 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-pkgappSCRIPTS \
-	uninstall-programfilesDATA uninstall-programfilesiconsDATA
-
-
-all: $(ASSEMBLY) $(PROGRAMFILES) $(LINUX_PKGCONFIG) 
-
-# macros
-
-# $(call emit-deploy-target,deploy-variable-name)
-define emit-deploy-target
-$($1): $($1_SOURCE)
-	mkdir -p $$(dir $($1))
-	cp '$$<' '$$@'
-endef
-
-# $(call emit-deploy-wrapper,wrapper-variable-name,wrapper-sourcefile,x)
-# assumes that for a wrapper foo.pc its source template is foo.pc.in
-# if $3 is non-empty then wrapper is marked exec
-define emit-deploy-wrapper
-$($1): $2 
-	mkdir -p '$$(@D)'
-	cp '$$<' '$$@'
-	$(if $3,chmod +x '$$@')
-
-endef
-
-$(eval $(foreach res, $(culture_resources), $(eval $(call culture_resource_dependencies,$(call get_culture,$(call get_resource_name,$(res))),$(call get_resource_name,$(res))))))
-$(eval $(foreach res, $(culture_resources), $(eval $(call culture_resource_commandlines,$(call get_culture,$(call get_resource_name,$(res))),$(res)))))
-
-$(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-wrapper,ENGINE_OSCAR_PC,smuxi-engine-oscar.pc))
-$(eval $(call emit-deploy-target,SMUXI_ENGINE_DLL))
-$(eval $(call emit-deploy-target,SMUXI_COMMON_DLL))
-
-$(build_xamlg_list): %.xaml.g.cs: %.xaml
-	xamlg '$<'
-
-$(build_resx_resources) : %.resources: %.resx
-	resgen2 '$<' '$@'
-
-$(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) $(OSCARLIB_LIBS) $(LOG4NET_LIBS)
-
-# 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/Engine-OSCAR/Protocols/Oscar/OscarProtocolManager.cs b/src/Engine-OSCAR/Protocols/Oscar/OscarProtocolManager.cs
deleted file mode 100644
index 8593e69..0000000
--- a/src/Engine-OSCAR/Protocols/Oscar/OscarProtocolManager.cs
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * $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) 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.Text;
-using System.Text.RegularExpressions;
-using System.Threading;
-using System.Collections;
-using System.Collections.Generic;
-using System.Globalization;
-
-using csammisrun.OscarLib;
-using OscarSession = csammisrun.OscarLib.Session;
-
-using Smuxi.Common;
-
-namespace Smuxi.Engine
-{
-    [ProtocolManagerInfo(Name = "ICQ", Description = "ICQ Messenger", Alias = "icq")]
-    public class IcqProtocolManager : OscarProtocolManager
-    {
-        public override string NetworkID {
-            get {
-                return "ICQ";
-            }
-        }
-        
-        public IcqProtocolManager(Session session) : base(session)
-        {
-        }
-    }
-    
-    [ProtocolManagerInfo(Name = "AIM", Description = "AOL Instant Messenger", Alias = "aim")]
-    public class AimProtocolManager : OscarProtocolManager
-    {
-        public override string NetworkID {
-            get {
-                return "AIM";
-            }
-        }
-        
-        public AimProtocolManager(Session session) : base(session)
-        {
-        }
-    }
-    
-    //[ProtocolManagerInfo(Name = "OSCAR", Description = "Open System for CommunicAtion in Realtime Protocol", Alias = "oscar")]
-    public abstract class OscarProtocolManager : ProtocolManagerBase
-    {
-#if LOG4NET
-        private static readonly log4net.ILog _Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
-#endif
-        private FrontendManager _FrontendManager;
-        private ChatModel       _NetworkChat;
-        private OscarSession    _OscarSession;
-        
-        public override string Protocol {
-            get {
-                return "OSCAR";
-            }
-        }
-        
-        public override ChatModel Chat {
-            get {
-                return _NetworkChat;
-            }
-        }
-
-        public OscarProtocolManager(Session session) : base(session)
-        {
-            Trace.Call(session);
-        }
-        
-        public override void Connect(FrontendManager fm, ServerModel server)
-        {
-            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;
-            
-            // TODO: use config for single network chat or once per network manager
-            _NetworkChat = new ProtocolChatModel(NetworkID, NetworkID + " Messenger", this);
-            Session.AddChat(_NetworkChat);
-            Session.SyncChat(_NetworkChat);
-            
-            _OscarSession = new OscarSession(server.Username, server.Password);
-            _OscarSession.ClientCapabilities = Capabilities.Chat | Capabilities.OscarLib;
-            _OscarSession.LoginCompleted           += new LoginCompletedHandler(_OnLoginCompleted);
-            _OscarSession.LoginFailed              += new LoginFailedHandler(_OnLoginFailed);
-            _OscarSession.LoginStatusUpdate        += new LoginStatusUpdateHandler(_OnLoginStatusUpdate);
-            _OscarSession.ErrorMessage             += new ErrorMessageHandler(_OnErrorMessage);
-            _OscarSession.WarningMessage           += new WarningMessageHandler(_OnWarningMessage);
-            _OscarSession.StatusUpdate             += new InformationMessageHandler(_OnStatusUpdate);
-            _OscarSession.ContactListFinished      += new ContactListFinishedHandler(_OnContactListFinished);
-            _OscarSession.Messages.MessageReceived += new MessageReceivedHandler(_OnMessageReceived);
-            _OscarSession.Logon(Host, Port);
-        }
-        
-        public override void Reconnect(FrontendManager fm)
-        {
-            Trace.Call(fm);
-        }
-        
-        public override void Disconnect(FrontendManager fm)
-        {
-            Trace.Call(fm);
-            
-            _OscarSession.Logoff();
-        }
-        
-        public override string ToString()
-        {
-            string result = NetworkID;
-            
-            if (!IsConnected) {
-                result += " (" + _("not connected") + ")";
-            }
-            return result;
-        }
-        
-        public override IList<GroupChatModel> FindGroupChats(GroupChatModel filter)
-        {
-            throw new NotImplementedException();
-        }
-        
-        
-        public override void OpenChat(FrontendManager fm, ChatModel chat)
-        {
-            Trace.Call(fm, chat);
-            
-            throw new NotImplementedException();
-        }
-
-        public override void CloseChat(FrontendManager fm, ChatModel chat)
-        {
-            Trace.Call(fm, chat);
-            
-            throw new NotImplementedException();
-        }
-        
-
-        public override void SetPresenceStatus(PresenceStatus status,
-                                               string message)
-        {
-            Trace.Call(status, message);
-
-            // TODO: implement me
-        }
-
-        public override bool Command(CommandModel command)
-        {
-            Trace.Call(command);
-            
-            bool handled = false;
-            if (IsConnected) {
-                if (command.IsCommand) {
-                } else {
-                    _Say(command.Chat, command.Data);
-                    handled = true;
-                }
-            } else {
-                if (command.IsCommand) {
-                    // commands which work even without beeing connected
-                    switch (command.Command) {
-                        case "help":
-                            CommandHelp(command);
-                            handled = true;
-                            break;
-                        case "connect":
-                            CommandConnect(command);
-                            handled = true;
-                            break;
-                    }
-                } else {
-                    // normal text, without connection
-                    NotConnected(command);
-                    handled = true;
-                }
-            }
-            
-            return handled;
-        }
-
-        public void CommandConnect(CommandModel cd)
-        {
-            FrontendManager fm = cd.FrontendManager;
-            
-            var server = new ServerModel();
-            if (cd.DataArray.Length >= 3) {
-                server.Username = cd.DataArray[2];
-            } else {
-                NotEnoughParameters(cd);
-                return;
-            }
-            
-            if (cd.DataArray.Length >= 4) {
-                server.Password = cd.DataArray[3];
-            } else {
-                NotEnoughParameters(cd);
-                return;
-            }
-            
-            Connect(fm, server);
-        }
-        
-        public void CommandHelp(CommandModel cd)
-        {
-            MessageModel fmsg = new MessageModel();
-            TextMessagePartModel fmsgti;
-
-            fmsgti = new TextMessagePartModel();
-            // TRANSLATOR: this line is used as a label / category for a
-            // list of commands below. {0} would be AIM or ICQ for example.
-            fmsgti.Text = "[" + String.Format(_("{0} Commands"), NetworkID) + "]";
-            fmsgti.Bold = true;
-            fmsg.MessageParts.Add(fmsgti);
-            
-            this.Session.AddMessageToChat(cd.Chat, fmsg);
-            
-            string[] help = {
-            "help",
-            "connect aim/icq username password",
-            };
-            
-            foreach (string line in help) { 
-                cd.FrontendManager.AddTextToChat(cd.Chat, "-!- " + line);
-            }
-        }
-        
-        private void _Say(ChatModel chat, string message)
-        {
-            if (!chat.IsEnabled) {
-                return;
-            }
-
-            MessageModel msg = new MessageModel();
-            TextMessagePartModel msgPart;
-            
-            _OscarSession.Messages.SendMessage(chat.ID, message);
-            
-            msgPart = new TextMessagePartModel();
-            msgPart.Text = "<";
-            msg.MessageParts.Add(msgPart);
-        
-            msgPart = new TextMessagePartModel();
-            msgPart.Text = _OscarSession.ScreenName;
-            msgPart.ForegroundColor = new TextColor(0x0000FF);
-            msg.MessageParts.Add(msgPart);
-            
-            msgPart = new TextMessagePartModel();
-            msgPart.Text = "> ";
-            msg.MessageParts.Add(msgPart);
-            
-            msgPart = new TextMessagePartModel();
-            msgPart.Text = message;
-            msg.MessageParts.Add(msgPart);
-            
-            Session.AddMessageToChat(chat, msg);
-        }
-        
-        private void _OnLoginCompleted(OscarSession sess)
-        {
-            IsConnected = true;
-            
-            string msg = _("Login successful");
-            Session.AddTextToChat(_NetworkChat, "-!- " + msg);
-        }
-
-        private void _OnLoginStatusUpdate(OscarSession sess, string messages, double percent)
-        {
-            Session.AddTextToChat(_NetworkChat, "-!- Login: " + messages);
-        }
-        
-        private void _OnLoginFailed(OscarSession sess, LoginErrorCode errorCode)
-        {
-            string msg = String.Format(_("Login failed: {0}"), errorCode);
-            Session.AddTextToChat(_NetworkChat, "-!- " + msg);
-        }
-
-        private void _OnStatusUpdate(OscarSession sess, string message)
-        {
-            Session.AddTextToChat(_NetworkChat, "-!- Status: " + message);
-        }
-        
-        private void _OnErrorMessage(OscarSession sess, ServerErrorCode errorCode)
-        {
-            string msg = String.Format(_("Connection Error: {0}"), errorCode);
-            Session.AddTextToChat(_NetworkChat, "-!- " + msg);
-        }
-
-        private void _OnWarningMessage(OscarSession sess, ServerErrorCode errorCode)
-        {
-            string msg = String.Format(_("Connection Warning: {0}"), errorCode);
-            Session.AddTextToChat(_NetworkChat, "-!- " + msg);
-        }
-        
-        private void _OnContactListFinished(OscarSession sess, DateTime time)
-        {
-            Session.AddTextToChat(_NetworkChat, "-!- Contact list finished");
-            
-            _OscarSession.ActivateBuddyList();
-        }
-        
-        //private void _OnMessageReceived(OscarSession sess, UserInfo userInfo, string message, Encoding encoding, MessageFlags msgFlags)
-        private void _OnMessageReceived(object sender, MessageReceivedEventArgs e)
-        {
-            ChatModel chat = GetChat(e.Message.ScreenName, ChatType.Person);
-            if (chat == null) {
-                PersonModel person = new PersonModel(e.Message.ScreenName,
-                                                     e.Message.ScreenName,
-                                                     NetworkID,
-                                                     Protocol,
-                                                     this);
-                chat = new PersonChatModel(person,
-                                           e.Message.ScreenName,
-                                           e.Message.ScreenName,
-                                           this);
-                Session.AddChat(chat);
-                Session.SyncChat(chat);
-            }
-            
-            MessageModel msg = new MessageModel();
-            TextMessagePartModel textMsg;
-            
-            textMsg = new TextMessagePartModel();
-            textMsg.Text = String.Format("<{0}> ", e.Message.ScreenName);
-            textMsg.IsHighlight = true;
-            msg.MessageParts.Add(textMsg);
-            
-            textMsg = new TextMessagePartModel();
-            textMsg.Text = e.Message.Message;
-            msg.MessageParts.Add(textMsg);
-            
-            Session.AddMessageToChat(chat, msg);
-        }
-        
-        private static string _(string msg)
-        {
-            return Mono.Unix.Catalog.GetString(msg);
-        }
-    }
-}
diff --git a/src/Engine-OSCAR/smuxi-engine-oscar.pc.in b/src/Engine-OSCAR/smuxi-engine-oscar.pc.in
deleted file mode 100644
index e44feac..0000000
--- a/src/Engine-OSCAR/smuxi-engine-oscar.pc.in
+++ /dev/null
@@ -1,6 +0,0 @@
-Name: Engine-OSCAR
-Description: Engine-OSCAR
-Version: @VERSION@
-
-Requires: smuxi-engine
-Libs: -r:@expanded_libdir@/@PACKAGE@/smuxi-engine-oscar.dll
diff --git a/src/Engine-Twitter/Makefile.in b/src/Engine-Twitter/Makefile.in
index 69f1d58..f429d33 100644
--- a/src/Engine-Twitter/Makefile.in
+++ b/src/Engine-Twitter/Makefile.in
@@ -57,8 +57,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
@@ -148,9 +151,8 @@ 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_CAMPFIRE = @GETTEXT_PACKAGE_ENGINE_CAMPFIRE@
 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@
@@ -162,6 +164,9 @@ 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@
+GIO_SHARP_CFLAGS = @GIO_SHARP_CFLAGS@
+GIO_SHARP_FILES = @GIO_SHARP_FILES@
+GIO_SHARP_LIBS = @GIO_SHARP_LIBS@
 GLADE_SHARP_20_CFLAGS = @GLADE_SHARP_20_CFLAGS@
 GLADE_SHARP_20_LIBS = @GLADE_SHARP_20_LIBS@
 GLIB_SHARP_20_CFLAGS = @GLIB_SHARP_20_CFLAGS@
@@ -208,6 +213,11 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
+MESSAGINGMENU_SHARP_CFLAGS = @MESSAGINGMENU_SHARP_CFLAGS@
+MESSAGINGMENU_SHARP_FILES = @MESSAGINGMENU_SHARP_FILES@
+MESSAGINGMENU_SHARP_LIBS = @MESSAGINGMENU_SHARP_LIBS@
+MESSAGING_MENU_CFLAGS = @MESSAGING_MENU_CFLAGS@
+MESSAGING_MENU_LIBS = @MESSAGING_MENU_LIBS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
 MONO_MODULE_CFLAGS = @MONO_MODULE_CFLAGS@
@@ -215,8 +225,6 @@ 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@
@@ -229,8 +237,6 @@ 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@
diff --git a/src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs b/src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs
index fb4184b..e3e1867 100644
--- a/src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs
+++ b/src/Engine-Twitter/Protocols/Twitter/TwitterProtocolManager.cs
@@ -1273,7 +1273,6 @@ namespace Smuxi.Engine
                 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;
@@ -1562,11 +1561,11 @@ namespace Smuxi.Engine
             return person;
         }
 
-        protected override MessageBuilder CreateMessageBuilder()
+        protected override T CreateMessageBuilder<T>()
         {
             var builder = new TwitterMessageBuilder();
             builder.ApplyConfig(Session.UserConfig);
-            return builder;
+            return (T)(object) builder;
         }
 
         private static bool ValidateCertificate(object sender,
diff --git a/src/Engine-XMPP/Config/XmppServerModel.cs b/src/Engine-XMPP/Config/XmppServerModel.cs
index 24b9bf5..f7370a5 100644
--- a/src/Engine-XMPP/Config/XmppServerModel.cs
+++ b/src/Engine-XMPP/Config/XmppServerModel.cs
@@ -19,15 +19,77 @@
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 
 using System;
+using System.Collections.Generic;
 
 namespace Smuxi.Engine
 {
     public class XmppServerModel : ServerModel
     {
         public string Resource { get; set; }
+        public Dictionary<PresenceStatus, int> Priorities { get; private set; }
 
+        public void InitDefaults()
+        {
+            Priorities = new Dictionary<PresenceStatus, int>();
+            // choose somewhat reasonable defaults
+            Priorities[PresenceStatus.Online] = 5;
+            Priorities[PresenceStatus.Away] = 0;
+            Resource = "smuxi";
+            Protocol = "XMPP";
+        }
+        
+        public virtual void Load(UserConfig config, string id)
+        {
+            if (config == null) {
+                throw new ArgumentNullException("config");
+            }
+            if (String.IsNullOrEmpty(id)) {
+                throw new ArgumentNullException("id");
+            }
+            Load(config, Protocol, id);
+        }
+        
         public XmppServerModel()
         {
+            InitDefaults();
+        }
+
+        public override void Load(UserConfig config, string protocol, string id)
+        {
+            if (config == null) {
+                throw new ArgumentNullException("config");
+            }
+            if (String.IsNullOrEmpty(protocol)) {
+                throw new ArgumentNullException("protocol");
+            }
+            if (String.IsNullOrEmpty(id)) {
+                throw new ArgumentNullException("id");
+            }
+            base.Load(config, protocol, id);
+            
+            var obj = config[ConfigKeyPrefix + "PriorityOnline"];
+            if (obj != null) {
+                Priorities[PresenceStatus.Online] = (int) obj;
+            }
+            obj = config[ConfigKeyPrefix + "PriorityAway"];
+            if (obj != null) {
+                Priorities[PresenceStatus.Away] = (int) obj;
+            }
+            obj = config[ConfigKeyPrefix + "Resource"];
+            if (obj != null) {
+                Resource = (string) obj;
+            }
+        }
+
+        public override void Save(UserConfig config)
+        {
+            if (config == null) {
+                throw new ArgumentNullException("config");
+            }
+            base.Save(config);
+            config[ConfigKeyPrefix + "PriorityOnline"] = Priorities[PresenceStatus.Online];
+            config[ConfigKeyPrefix + "PriorityAway"] = Priorities[PresenceStatus.Away];
+            config[ConfigKeyPrefix + "Resource"] = Resource;
         }
     }
 }
diff --git a/src/Engine-XMPP/Makefile.in b/src/Engine-XMPP/Makefile.in
index 42aa3e2..0dd7ad0 100644
--- a/src/Engine-XMPP/Makefile.in
+++ b/src/Engine-XMPP/Makefile.in
@@ -58,8 +58,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
@@ -149,9 +152,8 @@ 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_CAMPFIRE = @GETTEXT_PACKAGE_ENGINE_CAMPFIRE@
 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@
@@ -163,6 +165,9 @@ 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@
+GIO_SHARP_CFLAGS = @GIO_SHARP_CFLAGS@
+GIO_SHARP_FILES = @GIO_SHARP_FILES@
+GIO_SHARP_LIBS = @GIO_SHARP_LIBS@
 GLADE_SHARP_20_CFLAGS = @GLADE_SHARP_20_CFLAGS@
 GLADE_SHARP_20_LIBS = @GLADE_SHARP_20_LIBS@
 GLIB_SHARP_20_CFLAGS = @GLIB_SHARP_20_CFLAGS@
@@ -209,6 +214,11 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
+MESSAGINGMENU_SHARP_CFLAGS = @MESSAGINGMENU_SHARP_CFLAGS@
+MESSAGINGMENU_SHARP_FILES = @MESSAGINGMENU_SHARP_FILES@
+MESSAGINGMENU_SHARP_LIBS = @MESSAGINGMENU_SHARP_LIBS@
+MESSAGING_MENU_CFLAGS = @MESSAGING_MENU_CFLAGS@
+MESSAGING_MENU_LIBS = @MESSAGING_MENU_LIBS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
 MONO_MODULE_CFLAGS = @MONO_MODULE_CFLAGS@
@@ -216,8 +226,6 @@ 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@
@@ -230,8 +238,6 @@ 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@
diff --git a/src/Engine-XMPP/Protocols/Xmpp/XmppGroupChatModel.cs b/src/Engine-XMPP/Protocols/Xmpp/XmppGroupChatModel.cs
index d628f00..7e32352 100644
--- a/src/Engine-XMPP/Protocols/Xmpp/XmppGroupChatModel.cs
+++ b/src/Engine-XMPP/Protocols/Xmpp/XmppGroupChatModel.cs
@@ -26,6 +26,7 @@ namespace Smuxi.Engine
     {
         public string LatestSeenStamp { get; set; }
         public bool SeenNewMessages { get; set; }
+        public string OwnNickname { 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 eea9c97..77f358c 100644
--- a/src/Engine-XMPP/Protocols/Xmpp/XmppProtocolManager.cs
+++ b/src/Engine-XMPP/Protocols/Xmpp/XmppProtocolManager.cs
@@ -60,19 +60,27 @@ namespace Smuxi.Engine
 #if LOG4NET
         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;
+        JabberClient JabberClient { get; set; }
+        RosterManager RosterManager { get; set; }
+        ConferenceManager ConferenceManager { get; set; }
+        PresenceManager PresenceManager { get; set; }
+
+        ChatModel NetworkChat { get; set; }
+        GroupChatModel ContactChat { get; set; }
+        
+        XmppServerModel Server { get; set; }
         
+        // facebook messed up, this is part of a hack to fix that messup
+        string LastSentMessage { get; set; }
+        bool SupressLocalMessageEcho { get; set; }
+
         public override string NetworkID {
             get {
-                if (!String.IsNullOrEmpty(_JabberClient.NetworkHost)) {
-                    return _JabberClient.NetworkHost;
+                if (!String.IsNullOrEmpty(JabberClient.NetworkHost)) {
+                    return JabberClient.NetworkHost;
                 }
-                if (!String.IsNullOrEmpty(_JabberClient.Server)) {
-                    return _JabberClient.Server;
+                if (!String.IsNullOrEmpty(JabberClient.Server)) {
+                    return JabberClient.Server;
                 }
                 return "XMPP";
             }
@@ -86,7 +94,7 @@ namespace Smuxi.Engine
         
         public override ChatModel Chat {
             get {
-                return _NetworkChat;
+                return NetworkChat;
             }
         }
 
@@ -94,29 +102,34 @@ namespace Smuxi.Engine
         {
             Trace.Call(session);
 
-            _JabberClient = new JabberClient();
-            _JabberClient.Resource = "Smuxi";
-            _JabberClient.AutoLogin = true;
-            _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;
-
-            _RosterManager = new RosterManager();
-            _RosterManager.Stream = _JabberClient;
-
-            _ConferenceManager = new ConferenceManager();
-            _ConferenceManager.Stream = _JabberClient;
-            _ConferenceManager.OnJoin += OnJoin;
-            _ConferenceManager.OnLeave += OnLeave;
-            _ConferenceManager.OnParticipantJoin += OnParticipantJoin;
-            _ConferenceManager.OnParticipantLeave += OnParticipantLeave;
+            JabberClient = new JabberClient();
+            JabberClient.Resource = "Smuxi";
+            JabberClient.AutoLogin = true;
+            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;
+
+            RosterManager = new RosterManager();
+            RosterManager.Stream = JabberClient;
+            RosterManager.OnRosterItem += OnRosterItem;
+
+            PresenceManager = new PresenceManager();
+            PresenceManager.Stream = JabberClient;
+            JabberClient.OnPresence += OnPresence;
+
+            ConferenceManager = new ConferenceManager();
+            ConferenceManager.Stream = JabberClient;
+            ConferenceManager.OnJoin += OnJoin;
+            ConferenceManager.OnLeave += OnLeave;
+            ConferenceManager.OnParticipantJoin += OnParticipantJoin;
+            ConferenceManager.OnParticipantLeave += OnParticipantLeave;
         }
 
         public override void Connect(FrontendManager fm, ServerModel server)
@@ -129,44 +142,67 @@ namespace Smuxi.Engine
             if (server == null) {
                 throw new ArgumentNullException("server");
             }
-
-            _FrontendManager = fm;
+            
+            if (server is XmppServerModel) {
+                Server = (XmppServerModel) server;
+            } else {
+                Server = new XmppServerModel();
+                if (server.ServerID != null) {
+                    Server.Load(Session.UserConfig, server.ServerID);
+                }
+                // HACK: previous line overwrites any passed values with the values from config
+                // thus we have to copy the original values:
+                Server.Hostname = server.Hostname;
+                Server.Network = server.Network;
+                Server.OnConnectCommands = server.OnConnectCommands;
+                Server.OnStartupConnect = server.OnStartupConnect;
+                Server.Password = server.Password;
+                Server.Port = server.Port;
+                Server.Protocol = server.Protocol;
+                Server.ServerID = server.ServerID;
+                Server.UseEncryption = server.UseEncryption;
+                Server.Username = server.Username;
+                Server.ValidateServerCertificate = server.ValidateServerCertificate;
+            }
+            
             Host = server.Hostname;
             Port = server.Port;
 
-            ApplyConfig(Session.UserConfig, server);
+            ApplyConfig(Session.UserConfig, Server);
 
             // TODO: use config for single network chat or once per network manager
-            _NetworkChat = Session.CreateChat<ProtocolChatModel>(
+            NetworkChat = Session.CreateChat<ProtocolChatModel>(
                 NetworkID, "Jabber " + Host, this
             );
-            Session.AddChat(_NetworkChat);
-            Session.SyncChat(_NetworkChat);
+            Session.AddChat(NetworkChat);
+            Session.SyncChat(NetworkChat);
+
+            OpenContactChat();
 
-            if (!String.IsNullOrEmpty(_JabberClient.ProxyHost)) {
+            if (!String.IsNullOrEmpty(JabberClient.ProxyHost)) {
                 var builder = CreateMessageBuilder();
                 builder.AppendEventPrefix();
                 builder.AppendText(_("Using proxy: {0}:{1}"),
-                                   _JabberClient.ProxyHost,
-                                   _JabberClient.ProxyPort);
+                                   JabberClient.ProxyHost,
+                                   JabberClient.ProxyPort);
                 Session.AddMessageToChat(Chat, builder.ToMessage());
             }
-            _JabberClient.Connect();
+            JabberClient.Connect();
         }
         
         public override void Reconnect(FrontendManager fm)
         {
             Trace.Call(fm);
 
-            _JabberClient.Close();
-            _JabberClient.Connect();
+            JabberClient.Close();
+            JabberClient.Connect();
         }
         
         public override void Disconnect(FrontendManager fm)
         {
             Trace.Call(fm);
 
-            _JabberClient.Close(false);
+            JabberClient.Close(false);
         }
 
         public override void Dispose()
@@ -175,14 +211,14 @@ namespace Smuxi.Engine
 
             base.Dispose();
 
-            _JabberClient.Dispose();
+            JabberClient.Dispose();
         }
 
         public override string ToString()
         {
             string result = "Jabber ";
-            if (_JabberClient != null) {
-                result += _JabberClient.Server + ":" + _JabberClient.Port;
+            if (JabberClient != null) {
+                result += JabberClient.Server + ":" + JabberClient.Port;
             }
             
             if (!IsConnected) {
@@ -195,22 +231,60 @@ namespace Smuxi.Engine
         {
             Trace.Call(filter);
             
-            throw new NotImplementedException();
+            var list = new List<GroupChatModel>();
+            if (ContactChat == null) {
+                list.Add(new GroupChatModel("Contacts", "Contacts", this));
+            }
+            return list;
+        }
+
+        public void OpenContactChat ()
+        {
+            var chat = Session.GetChat("Contacts", ChatType.Group, this);
+
+            if (chat != null) return;
+
+            ContactChat = Session.CreateChat<GroupChatModel>(
+                "Contacts", "Contacts", this
+            );
+            Session.AddChat(ContactChat);
+            Session.SyncChat(ContactChat);
+            foreach(JID jid in PresenceManager) {
+                if (PresenceManager.IsAvailable(jid)) {
+                    lock (ContactChat) {
+                        Session.AddPersonToGroupChat(ContactChat, CreatePerson(jid));
+                    }
+                }
+            }
         }
 
         public override void OpenChat(FrontendManager fm, ChatModel chat)
         {
             Trace.Call(fm, chat);
-            
-            throw new NotImplementedException();
+            if (chat.ID == "Contacts") {
+                OpenContactChat();
+                return;
+            }
+            CommandModel cmd = new CommandModel(fm, NetworkChat, chat.ID);
+            switch (chat.ChatType) {
+                case ChatType.Person:
+                    CommandMessageQuery(cmd);
+                    break;
+                case ChatType.Group:
+                    CommandJoin(cmd);
+                    break;
+            }
         }
 
         public override void CloseChat(FrontendManager fm, ChatModel chat)
         {
             Trace.Call(fm, chat);
 
-            if (chat.ChatType == ChatType.Group) {
-                _ConferenceManager.GetRoom(chat.ID+"/"+_JabberClient.User).Leave("Closed");
+            if (chat == ContactChat) {
+                Session.RemoveChat(chat);
+                ContactChat = null;
+            } else if (chat.ChatType == ChatType.Group) {
+                ConferenceManager.GetRoom(chat.ID+"/"+JabberClient.User).Leave("Closed");
             } else {
                 Session.RemoveChat(chat);
             }
@@ -221,7 +295,7 @@ namespace Smuxi.Engine
         {
             Trace.Call(status, message);
 
-            if (!IsConnected || !_JabberClient.IsAuthenticated) {
+            if (!IsConnected || !JabberClient.IsAuthenticated) {
                 return;
             }
 
@@ -230,9 +304,11 @@ namespace Smuxi.Engine
             switch (status) {
                 case PresenceStatus.Online:
                     xmppType = PresenceType.available;
+                    JabberClient.Priority = Server.Priorities[status];
                     break;
                 case PresenceStatus.Away:
                     xmppType = PresenceType.available;
+                    JabberClient.Priority = Server.Priorities[status];
                     xmppShow = "away";
                     break;
                 case PresenceStatus.Offline:
@@ -243,8 +319,8 @@ namespace Smuxi.Engine
                 return;
             }
 
-            _JabberClient.Presence(xmppType.Value, message, xmppShow,
-                                   _JabberClient.Priority);
+            JabberClient.Presence(xmppType.Value, message, xmppShow,
+                                  JabberClient.Priority);
         }
 
         public override bool Command(CommandModel command)
@@ -279,6 +355,18 @@ namespace Smuxi.Engine
                             CommandAway(command);
                             handled = true;
                             break;
+                        case "roster":
+                            CommandRoster(command);
+                            handled = true;
+                            break;
+                        case "contact":
+                            CommandContact(command);
+                            handled = true;
+                            break;
+                        case "priority":
+                            CommandPriority(command);
+                            handled = true;
+                            break;
                     }
                 } else {
                     _Say(command.Chat, command.Data);
@@ -307,32 +395,77 @@ namespace Smuxi.Engine
             return handled;
         }
 
-        public void CommandHelp(CommandModel cd)
+        public void CommandContact (CommandModel cd)
         {
-            MessageModel fmsg = new MessageModel();
-            TextMessagePartModel fmsgti;
+            FrontendManager fm = cd.FrontendManager;
+            // todo: allow length of 2 in private chat windows
+            if (cd.DataArray.Length < 3) {
+                NotEnoughParameters(cd);
+                return;
+            }
+            JID jid = cd.DataArray[2];
+            string cmd = cd.DataArray[1];
+            switch (cmd) {
+                case "add":
+                case "subscribe":
+                    // also use GetJidFromNickname(jid) here, so jid is checked for validity
+                    RosterManager.Add(GetJidFromNickname(jid));
+                    break;
+                case "remove":
+                case "rm":
+                case "del":
+                    RosterManager.Remove(GetJidFromNickname(jid));
+                    break;
+                case "accept":
+                case "allow":
+                    RosterManager.Allow(GetJidFromNickname(jid));
+                    break;
+                case "deny":
+                    RosterManager.Deny(GetJidFromNickname(jid));
+                    break;
+                case "rename":
+                    if (cd.DataArray.Length < 4) {
+                        NotEnoughParameters(cd);
+                        return;
+                    }
+                    Item it = RosterManager[GetJidFromNickname(jid)];
+                    it.Nickname = cd.DataArray[3];
+                    RosterManager.Modify(it);
+                    break;
+                default:
+                    var builder = CreateMessageBuilder();
+                    builder.AppendText(_("Invalid Contact command: {0}"), cmd);
+                    fm.AddMessageToChat(cd.Chat, builder.ToMessage());
+                    return;
+            }
+        }
 
-            fmsgti = new TextMessagePartModel();
+        public void CommandHelp(CommandModel cmd)
+        {
+            var builder = CreateMessageBuilder();
             // TRANSLATOR: this line is used as a label / category for a
             // list of commands below
-            fmsgti.Text = "[" + _("XMPP Commands") + "]";
-            fmsgti.Bold = true;
-            fmsg.MessageParts.Add(fmsgti);
-            
-            Session.AddMessageToChat(cd.Chat, fmsg);
-            
+            builder.AppendHeader(_("XMPP Commands"));
+            cmd.FrontendManager.AddMessageToChat(cmd.Chat, builder.ToMessage());
+
             string[] help = {
             "help",
             "connect xmpp/jabber server port username password [resource]",
-            "msg/query jid message",
+            "msg/query jid/nick message",
             "say message",
-            "join muc-jid",
+            "join muc-jid [custom-chat-nick]",
             "part/leave [muc-jid]",
-            "away [away-message]"
+            "away [away-message]",
+            "contact add/remove/accept/deny jid/nick",
+            "contact rename jid/nick newnick"
+            ,"priority away/online/temp priority-value"
             };
             
-            foreach (string line in help) { 
-                cd.FrontendManager.AddTextToChat(cd.Chat, "-!- " + line);
+            foreach (string line in help) {
+                builder = CreateMessageBuilder();
+                builder.AppendEventPrefix();
+                builder.AppendText(line);
+                cmd.FrontendManager.AddMessageToChat(cmd.Chat, builder.ToMessage());
             }
         }
         
@@ -352,11 +485,9 @@ namespace Smuxi.Engine
                 try {
                     server.Port = Int32.Parse(cd.DataArray[3]);
                 } catch (FormatException) {
-                    fm.AddTextToChat(
-                        cd.Chat,
-                        "-!- " + String.Format(
-                                    _("Invalid port: {0}"),
-                                    cd.DataArray[3]));
+                    var builder = CreateMessageBuilder();
+                    builder.AppendText(_("Invalid port: {0}"), cd.DataArray[3]);
+                    fm.AddMessageToChat(cd.Chat, builder.ToMessage());
                     return;
                 }
             } else {
@@ -384,31 +515,88 @@ namespace Smuxi.Engine
 
             Connect(fm, server);
         }
+
+        public void CommandPriority(CommandModel command)
+        {
+            if (command.DataArray.Length < 3) {
+                var builder = CreateMessageBuilder();
+                builder.AppendText(_("Priority for Available is: {0}"), Server.Priorities[PresenceStatus.Online]);
+                command.FrontendManager.AddMessageToChat(command.Chat, builder.ToMessage());
+                builder = CreateMessageBuilder();
+                builder.AppendText(_("Priority for Away is: {0}"), Server.Priorities[PresenceStatus.Away]);
+                command.FrontendManager.AddMessageToChat(command.Chat, builder.ToMessage());
+                return;
+            }
+            string subcmd = command.DataArray[1];
+            int prio;
+            if (!int.TryParse(command.DataArray[2], out prio) || prio < -128 || prio > 127) {
+                var builder = CreateMessageBuilder();
+                builder.AppendText(_("Invalid Priority: {0} (valid priorities are between -128 and 127 inclusive)"), command.DataArray[2]);
+                command.FrontendManager.AddMessageToChat(command.Chat, builder.ToMessage());
+                return;
+            }
+            var me = PresenceManager[JabberClient.JID];
+            JabberClient.Priority = prio;
+            bool change_current_prio = false;
+            switch (subcmd) {
+                case "temp":
+                case "temporary":
+                    change_current_prio = true;
+                    // only set priority
+                    break;
+                case "away":
+                    Server.Priorities[PresenceStatus.Away] = prio;
+                    if (me != null) {
+                        change_current_prio = (me.Type == PresenceType.available) && (me.Show == "away");
+                    }
+                    break;
+                case "online":
+                case "available":
+                    Server.Priorities[PresenceStatus.Online] = prio;
+                    if (me != null) {
+                        change_current_prio = (me.Type == PresenceType.available) && string.IsNullOrEmpty(me.Show);
+                    }
+                    break;
+                default:
+                    return;
+            }
+            if (change_current_prio) {
+                // set priority and keep all other presence info
+                JabberClient.Presence(me.Type, me.Status, me.Show, prio);
+            }
+        }
+
+        private JID GetJidFromNickname(string nickname)
+        {
+            Item it = RosterManager[nickname];
+            if (it != null) {
+                return it.JID;
+            }
+
+            // arg is not a jid in our rostermanager
+            // find a jid to which the nickname belongs
+            foreach (JID j in RosterManager) {
+                Item item = RosterManager[j];
+                if (item.Nickname != null &&
+                    item.Nickname.Replace(" ", "_") == nickname) {
+                    return item.JID;
+                }
+            }
+            // not found in roster, message directly to jid
+            // TODO: check jid for validity
+            return nickname;
+        }
         
         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
-                }
-
+                string arg = cd.DataArray[1];
+                JID jid = GetJidFromNickname(arg);
                 chat = GetChat(jid, ChatType.Person);
                 if (chat == null) {
-                    PersonModel person = new PersonModel(jid, nickname,
-                                                         NetworkID, Protocol,
-                                                         this);
-                    chat = Session.CreatePersonChat(person, jid, nickname, this);
+                    PersonModel person = CreatePerson(jid);
+                    chat = Session.CreatePersonChat(person, jid, person.IdentityName, this);
                     Session.AddChat(chat);
                     Session.SyncChat(chat);
                 }
@@ -432,8 +620,12 @@ namespace Smuxi.Engine
 
             string jid = cd.DataArray[1];
             ChatModel chat = GetChat(jid, ChatType.Group);
+            string nickname = JabberClient.User;
+            if (cd.DataArray.Length > 2) {
+                nickname = cd.DataArray[2];
+            }
             if (chat == null) {
-                _ConferenceManager.GetRoom(jid+"/"+_JabberClient.User).Join();
+                ConferenceManager.GetRoom(jid+"/"+nickname).Join();
             }
         }
 
@@ -446,7 +638,7 @@ namespace Smuxi.Engine
                 jid = cd.Chat.ID;
             ChatModel chat = GetChat(jid, ChatType.Group);
             if (chat != null) {
-                _ConferenceManager.GetRoom(jid+"/"+_JabberClient.User).Leave("Part");
+                ConferenceManager.GetRoom(jid+"/"+JabberClient.User).Leave("Part");
             }
         }
 
@@ -459,6 +651,38 @@ namespace Smuxi.Engine
             }
         }
 
+        public void CommandRoster(CommandModel cd)
+        {
+            bool full = false;
+            if (cd.Parameter == "full") {
+                full = true;
+            }
+
+            MessageBuilder builder = CreateMessageBuilder();
+            builder.AppendHeader("Roster");
+            cd.FrontendManager.AddMessageToChat(cd.Chat, builder.ToMessage());
+
+            foreach (JID j in RosterManager) {
+                string status = "+";
+                if (!PresenceManager.IsAvailable(j)) {
+                    if (!full) continue;
+                    status = "-";
+                }
+                string nick = RosterManager[j].Nickname;
+                string mesg = "";
+                Presence item = PresenceManager[j];
+                if (item != null) {
+                    if (item.Show != null && item.Show.Length != 0) {
+                        status = item.Show;
+                    }
+                    mesg = item.Status;
+                }
+                builder = CreateMessageBuilder();
+                builder.AppendText("{0}\t{1}\t({2}): {3}", status, nick, j, mesg);
+                cd.FrontendManager.AddMessageToChat(cd.Chat, builder.ToMessage());
+            }
+        }
+
         public void CommandSay(CommandModel cd)
         {
             _Say(cd.Chat, cd.Parameter);
@@ -474,45 +698,35 @@ namespace Smuxi.Engine
             if (!chat.IsEnabled) {
                 return;
             }
+            if (chat == ContactChat) {
+                return;
+            }
             
             if (send) {
                 string target = chat.ID;
                 if (chat.ChatType == ChatType.Person) {
-                    _JabberClient.Message(target, text);
+                    JabberClient.Message(target, text);
                 } else if (chat.ChatType == ChatType.Group) {
-                    var room = _ConferenceManager.GetRoom(
+                    var room = ConferenceManager.GetRoom(
                         String.Format(
                             "{0}/{1}",
-                            target, _JabberClient.User
+                            target, JabberClient.User
                         )
                     );
                     room.PublicMessage(text);
                     return; // don't show now. the message will be echoed back if it's sent successfully
                 }
+                if (SupressLocalMessageEcho) {
+                    // don't show, facebook is bugging again
+                    return;
+                }
+                LastSentMessage = text;
             }
 
-            MessageModel msg = new MessageModel();
-            TextMessagePartModel msgPart;
-            
-            msgPart = new TextMessagePartModel();
-            msgPart.Text = "<";
-            msg.MessageParts.Add(msgPart);
-            
-            msgPart = new TextMessagePartModel();
-            msgPart.Text = _JabberClient.User;
-            //msgPart.ForegroundColor = IrcTextColor.Blue;
-            msgPart.ForegroundColor = new TextColor(0x0000FF);
-            msg.MessageParts.Add(msgPart);
-            
-            msgPart = new TextMessagePartModel();
-            msgPart.Text = "> ";
-            msg.MessageParts.Add(msgPart);
-                
-            msgPart = new TextMessagePartModel();
-            msgPart.Text = text;
-            msg.MessageParts.Add(msgPart);
-            
-            this.Session.AddMessageToChat(chat, msg);
+            var builder = CreateMessageBuilder();
+            builder.AppendSenderPrefix(Me);
+            builder.AppendMessage(text);
+            Session.AddMessageToChat(chat, builder.ToMessage());
         }
         
         void OnStreamInit(object sender, ElementStream stream)
@@ -520,6 +734,7 @@ namespace Smuxi.Engine
             Trace.Call(sender, stream);
 
             stream.AddType("own-message", "http://www.facebook.com/xmpp/messages", typeof(OwnMessageQuery));
+            SupressLocalMessageEcho = false;
         }
 
         void OnProtocol(object sender, XmlElement tag)
@@ -578,6 +793,104 @@ namespace Smuxi.Engine
             }
         }
 
+        public void OnRosterItem(object sender, Item ri)
+        {
+            string jid = ri.JID.Bare;
+
+            if (ContactChat == null) return;
+            lock (ContactChat) {
+                PersonModel oldp = ContactChat.GetPerson(jid);
+                if (oldp == null) {
+                    // doesn't exist, don't need to do anything
+                    return;
+                }
+                PersonModel newp = CreatePerson(jid);
+                Session.UpdatePersonInGroupChat(ContactChat, oldp, newp);
+            }
+        }
+
+        void OnPresence(object sender, Presence pres)
+        {
+            JID jid = pres.From;
+            var groupChat = (XmppGroupChatModel) Session.GetChat(jid.Bare, ChatType.Group, this);
+
+            MessageBuilder builder = CreateMessageBuilder();
+            builder.AppendEventPrefix();
+            PersonModel person = null;
+            if (groupChat != null) {
+                string displayName = jid.Resource ?? jid.Bare;
+                person = new PersonModel("", displayName, "", "", this);
+            } else {
+                person = CreatePerson(jid.Bare);
+            }
+            builder.AppendIdendityName(person);
+            if (jid != person.IdentityName) {
+                builder.AppendText(" [{0}]", jid);
+            }
+
+            switch (pres.Type) {
+                case PresenceType.available:
+                    // groupchat is already managed
+                    if (groupChat == null) {
+                        if (ContactChat != null) {
+                            // anyone who is online/away/dnd will be added to the list
+                            lock (ContactChat) {
+                                PersonModel p = ContactChat.GetPerson(jid.Bare);
+                                if (p != null) {
+                                    // p already exists, don't add a new person
+                                    Session.UpdatePersonInGroupChat(ContactChat, p, person);
+                                } else {
+                                    Session.AddPersonToGroupChat(ContactChat, person);
+                                }
+                            }
+                        }
+                    }
+                    if (pres.Show == null) {
+                        builder.AppendText(_(" is now available"));
+                    } else if (pres.Show == "away") {
+                        builder.AppendText(_(" is now away"));
+                    } else if (pres.Show == "dnd") {
+                        builder.AppendText(_(" wishes not to be disturbed"));
+                    } else {
+                        builder.AppendText(_(" set status to {0}"), pres.Show);
+                    }
+                    if (pres.Status == null) break;
+                    if (pres.Status.Length == 0) break;
+                    builder.AppendText(": {0}", pres.Status);
+                    break;
+                case PresenceType.unavailable:
+                    builder.AppendText(_(" is now offline"));
+                    if(groupChat == null) {
+                        if (ContactChat != null) {
+                            lock (ContactChat) {
+                                PersonModel p = ContactChat.GetPerson(jid.Bare);
+                                if (p == null) {
+                                    // doesn't exist, got an offline message w/o a preceding online message?
+                                    return;
+                                }
+                                Session.RemovePersonFromGroupChat(ContactChat, p);
+                            }
+                        }
+                    }
+                    break;
+                case PresenceType.subscribe:
+                    builder.AppendText(_(" wishes to subscribe to you"));
+                    break;
+                case PresenceType.subscribed:
+                    builder.AppendText(_(" allows you to subscribe"));
+                    break;
+            }
+            if (groupChat != null) {
+                Session.AddMessageToChat(groupChat, builder.ToMessage());
+            } else if (ContactChat != null) {
+                Session.AddMessageToChat(ContactChat, builder.ToMessage());
+            }
+            var personChat = Session.GetChat(jid.Bare, ChatType.Person, this);
+            if (personChat != null) {
+                Session.AddMessageToChat(personChat, builder.ToMessage());
+            }
+        }
+
         private void OnMessage(object sender, Message msg)
         {
             if (msg.Body == null) {
@@ -594,20 +907,14 @@ namespace Smuxi.Engine
             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);
+                var sender_jid = msg.From.Bare;
+                var personChat = (PersonChatModel) Session.GetChat(
+                    sender_jid, ChatType.Person, this
+                );
                 if (personChat == null) {
-                    person = new PersonModel(jid, nickname, NetworkID,
-                                             Protocol, this);
+                    person = CreatePerson(msg.From);
                     personChat = Session.CreatePersonChat(
-                        person, jid, nickname, this
+                        person, sender_jid, person.IdentityName, this
                     );
                     Session.AddChat(personChat);
                     Session.SyncChat(personChat);
@@ -618,15 +925,12 @@ namespace Smuxi.Engine
             } 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);
                 }
                 // resource can be empty for room messages
                 var sender_id = msg.From.Resource ?? msg.From.Bare;
@@ -659,7 +963,20 @@ namespace Smuxi.Engine
             if (display) {
                 var builder = CreateMessageBuilder();
                 if (msg.Type != XmppMessageType.error) {
-                    builder.AppendMessage(person, msg.Body);
+                    if (chat is PersonChatModel) {
+                        // private message
+                        builder.AppendSenderPrefix(person, true);
+                        builder.AppendMessage(msg.Body);
+                        builder.MarkHighlights();
+                    } else if (chat is XmppGroupChatModel) {
+                        // public message
+                        builder.AppendMessage(person, msg.Body);
+                        // mark highlights only for received messages
+                        var muc = (XmppGroupChatModel) chat;
+                        if (person.ID != muc.OwnNickname) {
+                            builder.MarkHighlights();
+                        }
+                    }
                 } else {
                     // TODO: nicer formatting
                     builder.AppendMessage(msg.Error.ToString());
@@ -688,23 +1005,18 @@ namespace Smuxi.Engine
                 // we send this message from Smuxi, nothing to do...
                 return;
             }
+            
+            if (!SupressLocalMessageEcho && (query.Body == LastSentMessage)) {
+                SupressLocalMessageEcho = true;
+                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
-                );
+                var person = CreatePerson(query.To);
+                chat = Session.CreatePersonChat(person, this);
                 Session.AddChat(chat);
                 Session.SyncChat(chat);
             }
@@ -732,25 +1044,31 @@ namespace Smuxi.Engine
         private void AddPersonToGroup(Room room, string nickname)
         {
             string jid = room.JID.Bare;
-            var chat = (GroupChatModel) Session.GetChat(jid, ChatType.Group, this);
+            var chat = (XmppGroupChatModel) 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);
+                chat.OwnNickname = room.Nickname;
                 Session.AddChat(chat);
-                Session.SyncChat(chat);
             }
 
-            PersonModel person;
-            lock(chat.UnsafePersons) {
-                person = chat.GetPerson(nickname);
-                if (person != null) {
+            lock (chat) {
+                if (chat.UnsafePersons.ContainsKey(nickname)) {
                     return;
                 }
+                // manual construction is necessary for group chats
+                var person = new PersonModel(nickname, nickname, NetworkID, Protocol, this);
+                if (chat.IsSynced) {
+                    Session.AddPersonToGroupChat(chat, person);
+                } else {
+                    chat.UnsafePersons.Add(nickname, person);
+                }
+            }
 
-                person = new PersonModel(nickname, nickname,
-                                         NetworkID, Protocol, this);
-                chat.UnsafePersons.Add(nickname, person);
-                Session.AddPersonToGroupChat(chat, person);
+            // did I join? then the chat roster is fully received
+            if (!chat.IsSynced && nickname == room.Nickname) {
+                chat.IsSynced = true;
+                Session.SyncChat(chat);
             }
         }
         
@@ -760,14 +1078,12 @@ namespace Smuxi.Engine
             var chat = (GroupChatModel) Session.GetChat(jid, ChatType.Group, this);
             string nickname = roomParticipant.Nick;
 
-            PersonModel person;
-            lock(chat.UnsafePersons) {
-                person = chat.GetPerson(nickname);
+            lock (chat) {
+                var person = chat.GetPerson(nickname);
                 if (person == null) {
                     return;
                 }
 
-                chat.UnsafePersons.Remove(nickname);
                 Session.RemovePersonFromGroupChat(chat, person);
             }
         }
@@ -795,9 +1111,9 @@ namespace Smuxi.Engine
 
             var builder = CreateMessageBuilder();
             builder.AppendEventPrefix();
-            builder.AppendText(_("Error: {0}"), String.Empty);
+            builder.AppendErrorText(_("Error: {0}"), String.Empty);
             builder.AppendMessage(ex.Message);
-            Session.AddMessageToChat(_NetworkChat, builder.ToMessage());
+            Session.AddMessageToChat(NetworkChat, builder.ToMessage());
         }
 
         void OnAuthenticate(object sender)
@@ -806,7 +1122,10 @@ namespace Smuxi.Engine
 
             IsConnected = true;
 
-            Session.AddTextToChat(_NetworkChat, "Authenticated");
+            var builder = CreateMessageBuilder();
+            builder.AppendEventPrefix();
+            builder.AppendText(_("Authenticated"));
+            Session.AddMessageToChat(Chat, builder.ToMessage());
 
             // send initial presence
             SetPresenceStatus(PresenceStatus.Online, null);
@@ -814,37 +1133,40 @@ namespace Smuxi.Engine
             OnConnected(EventArgs.Empty);
         }
 
-        private void ApplyConfig(UserConfig config, ServerModel server)
+        private void ApplyConfig(UserConfig config, XmppServerModel 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;
+                JabberClient.NetworkHost = server.Hostname;
+                JabberClient.User = jid_user;
+                JabberClient.Server = jid_host;
             } else {
-                _JabberClient.Server = server.Hostname;
-                _JabberClient.User = server.Username;
+                JabberClient.Server = server.Hostname;
+                JabberClient.User = server.Username;
             }
-            _JabberClient.Port = server.Port;
-            _JabberClient.Password = server.Password;
+            JabberClient.Port = server.Port;
+            JabberClient.Password = server.Password;
+
+            Me = CreatePerson(
+                String.Format("{0}@{1}",
+                    JabberClient.User,
+                    JabberClient.Server
+                ),
+                JabberClient.User
+            );
+            Me.IdentityNameColored.ForegroundColor = new TextColor(0, 0, 255);
+            Me.IdentityNameColored.BackgroundColor = TextColor.None;
+            Me.IdentityNameColored.Bold = true;
 
             // 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.Resource = server.Resource;
 
-            _JabberClient.OnInvalidCertificate -= ValidateCertificate;
+            JabberClient.OnInvalidCertificate -= ValidateCertificate;
 
-            _JabberClient.AutoStartTLS = server.UseEncryption;
+            JabberClient.AutoStartTLS = server.UseEncryption;
             if (!server.ValidateServerCertificate) {
-                _JabberClient.OnInvalidCertificate += ValidateCertificate;
+                JabberClient.OnInvalidCertificate += ValidateCertificate;
             }
 
             var proxySettings = new ProxySettings();
@@ -854,7 +1176,7 @@ namespace Smuxi.Engine
                                           server.Hostname, server.Port);
             var proxy = proxySettings.GetWebProxy(serverUri);
             if (proxy == null) {
-                _JabberClient.Proxy = XmppProxyType.None;
+                JabberClient.Proxy = XmppProxyType.None;
             } else {
                 var proxyScheme = proxy.Address.Scheme;
                 var xmppProxyType = XmppProxyType.None;
@@ -869,11 +1191,11 @@ namespace Smuxi.Engine
                                   proxyScheme, ex);
 #endif
                 }
-                _JabberClient.Proxy = xmppProxyType;
-                _JabberClient.ProxyHost = proxy.Address.Host;
-                _JabberClient.ProxyPort = proxy.Address.Port;
-                _JabberClient.ProxyUsername = proxySettings.ProxyUsername;
-                _JabberClient.ProxyPassword = proxySettings.ProxyPassword;
+                JabberClient.Proxy = xmppProxyType;
+                JabberClient.ProxyHost = proxy.Address.Host;
+                JabberClient.ProxyPort = proxy.Address.Port;
+                JabberClient.ProxyUsername = proxySettings.ProxyUsername;
+                JabberClient.ProxyPassword = proxySettings.ProxyPassword;
             }
         }
 
@@ -885,6 +1207,26 @@ namespace Smuxi.Engine
             return true;
         }
 
+        PersonModel CreatePerson(JID jid)
+        {
+            if (jid == null) {
+                throw new ArgumentNullException("jid");
+            }
+            var contact = RosterManager[jid.Bare];
+            string nickname = null;
+            if (contact == null || String.IsNullOrEmpty(contact.Nickname)) {
+                nickname = jid.Bare;
+            } else {
+                nickname = contact.Nickname;
+            }
+            return CreatePerson(jid.Bare, nickname);
+        }
+
+        PersonModel CreatePerson(string jid, string nickname)
+        {
+            return new PersonModel(jid, nickname, NetworkID, Protocol, this);
+        }
+
         private static string _(string msg)
         {
             return Mono.Unix.Catalog.GetString(msg);
diff --git a/src/Engine/Chats/ChatModel.cs b/src/Engine/Chats/ChatModel.cs
index 9a861cb..5b273e0 100644
--- a/src/Engine/Chats/ChatModel.cs
+++ b/src/Engine/Chats/ChatModel.cs
@@ -161,7 +161,15 @@ namespace Smuxi.Engine
 
         public string ToTraceString()
         {
-            string nm = (_ProtocolManager != null) ? _ProtocolManager.ToString() : "(null)";  
+            string nm;
+            if (_ProtocolManager == null) {
+                nm = "(null)";
+            } else {
+                nm = String.Format("{0}/{1}",
+                    _ProtocolManager.Protocol,
+                    _ProtocolManager.NetworkID
+                );
+            }
             return  nm + "/" + _Name; 
         }
 
diff --git a/src/Engine/Config/Config.cs b/src/Engine/Config/Config.cs
index 7089987..fa096d0 100644
--- a/src/Engine/Config/Config.cs
+++ b/src/Engine/Config/Config.cs
@@ -314,6 +314,7 @@ namespace Smuxi.Engine
             Get(prefix + "Servers", new string[] {
                 "IRC/irc.oftc.net",
                 "IRC/irc.gimp.org",
+                "IRC/irc.geekshed.net",
                 "IRC/irc.efnet.org",
                 "IRC/irc.ircnet.org",
                 "IRC/irc.freenode.net"
@@ -343,6 +344,15 @@ namespace Smuxi.Engine
             Get(prefix + "UseEncryption", false);
             Get(prefix + "ValidateServerCertificate", false);
 
+            prefix = "Engine/Users/DEFAULT/Servers/IRC/irc.geekshed.net/";
+            Get(prefix + "Hostname", "irc.geekshed.net");
+            Get(prefix + "Port", 6667);
+            Get(prefix + "Network", "GeekShed");
+            Get(prefix + "Username", String.Empty);
+            Get(prefix + "Password", String.Empty);
+            Get(prefix + "UseEncryption", false);
+            Get(prefix + "ValidateServerCertificate", false);
+
             prefix = "Engine/Users/DEFAULT/Servers/IRC/irc.efnet.org/";
             Get(prefix + "Hostname", "irc.efnet.org");
             Get(prefix + "Port", 6667);
@@ -557,6 +567,10 @@ namespace Smuxi.Engine
                     } else {
                         m_Preferences[sprefix + "OnConnectCommands"] = commands;
                     }
+                    // HACK: XMPP specific values
+                    LoadEntry(sprefix+"Resource", null);
+                    LoadEntry(sprefix+"PriorityAvailable", null);
+                    LoadEntry(sprefix+"PriorityAway", null);
                 }
 
                 string[] filters = null;
diff --git a/src/Engine/Config/ServerListController.cs b/src/Engine/Config/ServerListController.cs
index 4b035f1..6cbd0de 100644
--- a/src/Engine/Config/ServerListController.cs
+++ b/src/Engine/Config/ServerListController.cs
@@ -60,11 +60,11 @@ namespace Smuxi.Engine
             foreach (string server in servers) {
                 string[] serverParts = server.Split(new char[] {'/'});
                 string protocol = serverParts[0];
-                string servername = serverParts[1];
-                ServerModel ser = GetServer(protocol, servername);
+                string serverId = serverParts[1];
+                ServerModel ser = GetServer(protocol, serverId);
                 if (ser == null) {
 #if LOG4NET
-                    _Logger.Error("GetServerList(): GetServer(" + protocol + ", " + servername +") returned null! ignoring...");
+                    _Logger.Error("GetServerList(): GetServer(" + protocol + ", " + serverId +") returned null! ignoring...");
 #endif 
                     continue;
                 }
@@ -84,25 +84,12 @@ namespace Smuxi.Engine
                 throw new ArgumentNullException("servername");
             }
             
-            string prefix = "Servers/" + protocol + "/" + servername + "/";
             ServerModel server = new ServerModel();
-            if (_UserConfig[prefix + "Hostname"] == null) {
-                // server does not exist
+            try {
+                server.Load(_UserConfig, protocol, servername);
+            } catch (ArgumentException) {
                 return null;
             }
-            server.Protocol    = protocol;
-            server.Hostname    = (string) _UserConfig[prefix + "Hostname"];
-            server.Port        = (int)    _UserConfig[prefix + "Port"];
-            server.Network     = (string) _UserConfig[prefix + "Network"];
-            server.Username    = (string) _UserConfig[prefix + "Username"];
-            server.Password    = (string) _UserConfig[prefix + "Password"];
-            server.UseEncryption = (bool) _UserConfig[prefix + "UseEncryption"];
-            server.ValidateServerCertificate =
-                (bool) _UserConfig[prefix + "ValidateServerCertificate"];
-            if (_UserConfig[prefix + "OnStartupConnect"] != null) {
-                server.OnStartupConnect = (bool) _UserConfig[prefix + "OnStartupConnect"];
-            }
-            server.OnConnectCommands  = _UserConfig[prefix + "OnConnectCommands"] as IList<string>;
             return server;
         }
         
@@ -153,34 +140,31 @@ namespace Smuxi.Engine
             if (server.Hostname.Contains("\n")) {
                 throw new InvalidOperationException(_("Server hostname contains invalid characters (newline)."));
             }
+            var highestServerId = -1;
             foreach (var s in GetServerList()) {
                 if (s.Protocol == server.Protocol &&
-                    s.Hostname == server.Hostname) {
+                    s.ServerID == server.ServerID) {
                     throw new InvalidOperationException(
-                        String.Format(_("Server '{0}' already exists."),
-                                      server.Hostname)
+                        String.Format(_("Server ID '{0}' already exists."),
+                                      server.ServerID)
                     );
                 }
+                int id;
+                if (Int32.TryParse(s.ServerID, out id) && id > highestServerId) {
+                    highestServerId = id;
+                }
             }
-
-            string prefix = "Servers/" + server.Protocol + "/" + server.Hostname + "/";
-            _UserConfig[prefix + "Hostname"] = server.Hostname;
-            _UserConfig[prefix + "Port"]     = server.Port;
-            _UserConfig[prefix + "Network"]  = server.Network;
-            _UserConfig[prefix + "Username"] = server.Username;
-            _UserConfig[prefix + "Password"] = server.Password;
-            _UserConfig[prefix + "UseEncryption"] = server.UseEncryption;
-            _UserConfig[prefix + "ValidateServerCertificate"] =
-                server.ValidateServerCertificate;
-            _UserConfig[prefix + "OnStartupConnect"] = server.OnStartupConnect;
-            _UserConfig[prefix + "OnConnectCommands"] = server.OnConnectCommands;
+            if (String.IsNullOrEmpty(server.ServerID)) {
+                server.ServerID = (++highestServerId).ToString();
+            }
+            server.Save(_UserConfig);
             
             string[] servers = (string[]) _UserConfig["Servers/Servers"];
             if (servers == null) {
                 servers = new string[] {};
             }
             List<string> serverList = new List<string>(servers);
-            serverList.Add(server.Protocol + "/" + server.Hostname);
+            serverList.Add(server.Protocol + "/" + server.ServerID);
             _UserConfig["Servers/Servers"] = serverList.ToArray();
         }
 
@@ -191,18 +175,7 @@ namespace Smuxi.Engine
             if (server == null) {
                 throw new ArgumentNullException("server");
             }
-            
-            string prefix = "Servers/" + server.Protocol + "/" + server.Hostname + "/";
-            _UserConfig[prefix + "Hostname"] = server.Hostname;
-            _UserConfig[prefix + "Port"]     = server.Port;
-            _UserConfig[prefix + "Network"]  = server.Network;
-            _UserConfig[prefix + "Username"] = server.Username;
-            _UserConfig[prefix + "Password"] = server.Password;
-            _UserConfig[prefix + "UseEncryption"] = server.UseEncryption;
-            _UserConfig[prefix + "ValidateServerCertificate"] =
-                server.ValidateServerCertificate;
-            _UserConfig[prefix + "OnStartupConnect"] = server.OnStartupConnect;
-            _UserConfig[prefix + "OnConnectCommands"] = server.OnConnectCommands;
+            server.Save(_UserConfig);
         }
         
         public void RemoveServer(string protocol, string servername)
diff --git a/src/Engine/Config/ServerModel.cs b/src/Engine/Config/ServerModel.cs
index 4ecc83d..0d6ef65 100644
--- a/src/Engine/Config/ServerModel.cs
+++ b/src/Engine/Config/ServerModel.cs
@@ -21,99 +21,167 @@
  */
 
 using System;
+using System.Runtime.Serialization;
 using System.Collections.Generic;
 using Smuxi.Common;
 
 namespace Smuxi.Engine
 {
     [Serializable]
-    public class ServerModel
+    public class ServerModel : ISerializable
     {
-        private string        _Protocol;
-        private string        _Hostname;
-        private int           _Port;
-        private string        _Network;
-        private string        _Username;
-        private string        _Password;
-        private bool          _OnStartupConnect;
-        private IList<string> _OnConnectCommands;
         public bool UseEncryption { get; set; }
         public bool ValidateServerCertificate { get; set; }
-
-        public string Protocol {
-            get {
-                return _Protocol;
-            }
-            set {
-                _Protocol = value;
-            }
-        }
+        public string Protocol { get; set; }
+        public string Hostname { get; set; }
+        public int Port { get; set; }
+        public string Network { get; set; }
+        public string Username { get; set; }
+        public string Password { get; set; }
+        public bool OnStartupConnect { get; set; }
+        public IList<string> OnConnectCommands { get; set; }
+        public string ServerID { get; set; }
         
-        public string Hostname {
-            get {
-                return _Hostname;
-            }
-            set {
-                _Hostname = value;
-            }
-        }
-
-        public int Port {
+        protected string ConfigKeyPrefix {
             get {
-                return _Port;
-            }
-            set {
-                _Port = value;
+                if (String.IsNullOrEmpty(Protocol)) {
+                    throw new ArgumentNullException("Protocol");
+                }
+                if (String.IsNullOrEmpty(ServerID)) {
+                    throw new ArgumentNullException("ServerID");
+                }
+                return "Servers/" + Protocol + "/" + ServerID + "/";
             }
         }
         
-        public string Network {
-            get {
-                return _Network;
-            }
-            set {
-                _Network = value;
-            }
-        }
-
-        public string Username {
-            get {
-                return _Username;
-            }
-            set {
-                _Username = value;
-            }
+        public ServerModel()
+        {
         }
 
-        public string Password {
-            get {
-                return _Password;
-            }
-            set {
-                _Password = value;
-            }
+        protected ServerModel(SerializationInfo info, StreamingContext ctx)
+        {
+            Protocol = info.GetString("_Protocol");
+            Hostname = info.GetString("_Hostname");
+            Port = info.GetInt32("_Port");
+            Network = info.GetString("_Network");
+            Username = info.GetString("_Username");
+            Password = info.GetString("_Password");
+            OnStartupConnect = info.GetBoolean("_OnStartupConnect");
+            //ServerID = info.GetString("_ServerID");
+            bool foundServerID = false;
+            bool foundEncryption = false;
+            bool foundValidation = false;
+            foreach(SerializationEntry e in info) {
+                switch (e.Name) {
+                    case "_ServerID":
+                        ServerID = (string)e.Value;
+                        foundServerID = true;
+                        break;
+                    // UseEncryption and ValidateServerCertificate were forgotten
+                    // when moving from autoserialization to manual serialization.
+                    // To prevent crashes when git users' updated engines receive a ServerModel
+                    // from an older git frontend, we manually check for the fields' existance
+                    case "<UseEncryption>k__BackingField":
+                        UseEncryption = (bool)e.Value;
+                        foundEncryption = true;
+                        break;
+                    case "<ValidateServerCertificate>k__BackingField":
+                        ValidateServerCertificate = (bool)e.Value;
+                        foundValidation = true;
+                        break;
+                }
+            }
+            if (foundServerID == false) {
+                // this is from an old frontend/engine that doesn't know about ServerID yet
+                ServerID = Hostname;
+            }
+            if (!foundEncryption) {
+                UseEncryption = false;
+            }
+            if (!foundValidation) {
+                ValidateServerCertificate = false;
+            }
+            OnConnectCommands = (IList<string>) info.GetValue(
+                "_OnConnectCommands",
+                typeof(IList<string>)
+            );
         }
 
-        public bool OnStartupConnect {
-            get {
-                return _OnStartupConnect;
-            }
-            set {
-                _OnStartupConnect = value;
-            }
+        public virtual void GetObjectData(SerializationInfo info, StreamingContext ctx) 
+        {
+            info.AddValue("_ServerID", ServerID);
+            info.AddValue("_Protocol", Protocol);
+            info.AddValue("_Hostname", Hostname);
+            info.AddValue("_Port", Port);
+            info.AddValue("_Network", Network);
+            info.AddValue("_Username", Username);
+            info.AddValue("_Password", Password);
+            info.AddValue("_OnStartupConnect", OnStartupConnect);
+            info.AddValue("_OnConnectCommands", OnConnectCommands);
+            // oddball names are necessary because the fields always were auto properties
+            info.AddValue("<UseEncryption>k__BackingField", UseEncryption);
+            info.AddValue("<ValidateServerCertificate>k__BackingField", ValidateServerCertificate);
         }
         
-        public IList<string> OnConnectCommands {
-            get {
-                return _OnConnectCommands;
-            }
-            set {
-                _OnConnectCommands = value;
-            }
+        public virtual void Load(UserConfig config, string protocol, string id)
+        {
+            if (config == null) {
+                throw new ArgumentNullException("config");
+            }
+            if (String.IsNullOrEmpty(protocol)) {
+                throw new ArgumentNullException("protocol");
+            }
+            if (String.IsNullOrEmpty(id)) {
+                throw new ArgumentNullException("id");
+            }
+            // don't use ConfigKeyPrefix, so exception guarantees can be kept
+            string prefix = "Servers/" + protocol + "/" + id + "/";
+            if (config[prefix + "Hostname"] == null) {
+                // server does not exist
+                throw new ArgumentException("ServerID not found in config", id);
+            }
+            ServerID    = id;
+            Protocol    = protocol;
+            // now we have a valid ServerID and Protocol, ConfigKeyPrefix works
+            Hostname    = (string) config[ConfigKeyPrefix + "Hostname"];
+            Port        = (int)    config[ConfigKeyPrefix + "Port"];
+            Network     = (string) config[ConfigKeyPrefix + "Network"];
+            Username    = (string) config[ConfigKeyPrefix + "Username"];
+            Password    = (string) config[ConfigKeyPrefix + "Password"];
+            UseEncryption = (bool) config[ConfigKeyPrefix + "UseEncryption"];
+            ValidateServerCertificate =
+                (bool) config[ConfigKeyPrefix + "ValidateServerCertificate"];
+            if (config[ConfigKeyPrefix + "OnStartupConnect"] != null) {
+                OnStartupConnect = (bool) config[ConfigKeyPrefix + "OnStartupConnect"];
+            }
+            OnConnectCommands  = config[ConfigKeyPrefix + "OnConnectCommands"] as IList<string>;
         }
         
-        public ServerModel()
+        public virtual void Save(UserConfig config)
+        {
+            if (config == null) {
+                throw new ArgumentNullException("config");
+            }
+            config[ConfigKeyPrefix + "Hostname"] = Hostname;
+            config[ConfigKeyPrefix + "Port"]     = Port;
+            config[ConfigKeyPrefix + "Network"]  = Network;
+            config[ConfigKeyPrefix + "Username"] = Username;
+            config[ConfigKeyPrefix + "Password"] = Password;
+            config[ConfigKeyPrefix + "UseEncryption"] = UseEncryption;
+            config[ConfigKeyPrefix + "ValidateServerCertificate"] =
+                ValidateServerCertificate;
+            config[ConfigKeyPrefix + "OnStartupConnect"] = OnStartupConnect;
+            config[ConfigKeyPrefix + "OnConnectCommands"] = OnConnectCommands;
+        }
+
+        public override string ToString()
+        {
+            return String.Format("<{0}>", ToTraceString());
+        }
+
+        public string ToTraceString()
         {
+            return String.Format("{0}/{1}", Protocol, ServerID);
         }
     }
 }
diff --git a/src/Engine/Config/UserConfig.cs b/src/Engine/Config/UserConfig.cs
index 7b77a27..f76a6d9 100644
--- a/src/Engine/Config/UserConfig.cs
+++ b/src/Engine/Config/UserConfig.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, 2010-2011, 2013 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -34,7 +28,7 @@ using Smuxi.Common;
 
 namespace Smuxi.Engine
 {
-    public class UserConfig : PermanentRemoteObject
+    public class UserConfig : PermanentRemoteObject, IEnumerable<KeyValuePair<string, object>>
     {
 #if LOG4NET
         private static readonly log4net.ILog _Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
@@ -195,6 +189,23 @@ namespace Smuxi.Engine
             _Cache = cache;
         }
 
+        IEnumerator IEnumerable.GetEnumerator()
+        {
+            return GetEnumerator();
+        }
+
+        public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
+        {
+            foreach (var entry in _Config.GetAll()) {
+                if (!entry.Key.StartsWith(_UserPrefix)) {
+                    continue;
+                }
+                // remove user prefix from key
+                var userKey = entry.Key.Substring(_UserPrefix.Length);
+                yield return new KeyValuePair<string, object>(userKey, entry.Value);
+            }
+        }
+
         void OnConfigChanged(object sender, ConfigChangedEventArgs e)
         {
             if (Changed == null) {
diff --git a/src/Engine/Engine.cs b/src/Engine/Engine.cs
index 2fa1881..be3a213 100644
--- a/src/Engine/Engine.cs
+++ b/src/Engine/Engine.cs
@@ -7,7 +7,7 @@
  *
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2005-2006 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2005-2013 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -86,9 +86,11 @@ namespace Smuxi.Engine
             }
             _IsInitialized = true;
             
-            Assembly asm = Assembly.GetAssembly(typeof(Engine));
-            AssemblyName asm_name = asm.GetName(false);
-            AssemblyProductAttribute pr = (AssemblyProductAttribute)asm.GetCustomAttributes(typeof(AssemblyProductAttribute), false)[0];
+            var asm = Assembly.GetEntryAssembly();
+            if (asm == null) {
+                asm = Assembly.GetAssembly(typeof(Engine));
+            }
+            var asm_name = asm.GetName(false);
             _Version = asm_name.Version;
             _VersionNumber = asm_name.Version.ToString();
 
@@ -98,7 +100,7 @@ namespace Smuxi.Engine
             }
             _VersionString = String.Format(
                 "{0} {1}{2} - running on {3} {4}",
-                pr.Product,
+                Path.GetFileNameWithoutExtension(asm_name.Name),
                 _Version,
                 distVersion,
                 Platform.OperatingSystem,
diff --git a/src/Engine/FrontendManager.cs b/src/Engine/FrontendManager.cs
index 41ebd21..e5e1d83 100644
--- a/src/Engine/FrontendManager.cs
+++ b/src/Engine/FrontendManager.cs
@@ -248,12 +248,13 @@ namespace Smuxi.Engine
             });
         }
         
+        [Obsolete("This method is deprecated, use AddMessageToChat(cmd.Chat, MessageModel) instead!")]
         public void AddTextToChat(ChatModel chat, string text)
         {
             AddMessageToChat(chat, new MessageModel(text));
         }
 
-        [Obsolete("This method is unsafe, use AddTextToChat(cmd.Chat, text) instead!", true)]
+        [Obsolete("This method is unsafe, use AddMessageToChat(cmd.Chat, MessageModel) instead!", true)]
         public void AddTextToCurrentChat(string text)
         {
             AddTextToChat(CurrentChat, text);
@@ -308,6 +309,13 @@ namespace Smuxi.Engine
             lock (_SyncedChats) {
                 _SyncedChats.Remove(chat);
             }
+
+            // switch to next protocol manager if the current one was closed
+            if (chat is ProtocolChatModel &&
+                chat.ProtocolManager == CurrentProtocolManager) {
+                NextProtocolManager();
+            }
+
             f_TaskQueue.Queue(delegate {
                 _UI.RemoveChat(chat);
             });
diff --git a/src/Engine/Makefile.am b/src/Engine/Makefile.am
index 9d7cfa7..23b9684 100644
--- a/src/Engine/Makefile.am
+++ b/src/Engine/Makefile.am
@@ -113,6 +113,8 @@ REFERENCES =  \
 	System.Runtime.Remoting \
 	System \
 	System.Core \
+	System.Web \
+	System.Xml \
 	Mono.Posix \
 	$(NINI_LIBS) \
 	$(LOG4NET_LIBS) \
diff --git a/src/Engine/Makefile.in b/src/Engine/Makefile.in
index 431da86..5621ca1 100644
--- a/src/Engine/Makefile.in
+++ b/src/Engine/Makefile.in
@@ -60,8 +60,11 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
 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
@@ -152,9 +155,8 @@ 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_CAMPFIRE = @GETTEXT_PACKAGE_ENGINE_CAMPFIRE@
 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@
@@ -166,6 +168,9 @@ 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@
+GIO_SHARP_CFLAGS = @GIO_SHARP_CFLAGS@
+GIO_SHARP_FILES = @GIO_SHARP_FILES@
+GIO_SHARP_LIBS = @GIO_SHARP_LIBS@
 GLADE_SHARP_20_CFLAGS = @GLADE_SHARP_20_CFLAGS@
 GLADE_SHARP_20_LIBS = @GLADE_SHARP_20_LIBS@
 GLIB_SHARP_20_CFLAGS = @GLIB_SHARP_20_CFLAGS@
@@ -212,6 +217,11 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
+MESSAGINGMENU_SHARP_CFLAGS = @MESSAGINGMENU_SHARP_CFLAGS@
+MESSAGINGMENU_SHARP_FILES = @MESSAGINGMENU_SHARP_FILES@
+MESSAGINGMENU_SHARP_LIBS = @MESSAGINGMENU_SHARP_LIBS@
+MESSAGING_MENU_CFLAGS = @MESSAGING_MENU_CFLAGS@
+MESSAGING_MENU_LIBS = @MESSAGING_MENU_LIBS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
 MONO_MODULE_CFLAGS = @MONO_MODULE_CFLAGS@
@@ -219,8 +229,6 @@ 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@
@@ -233,8 +241,6 @@ 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@
@@ -425,6 +431,8 @@ REFERENCES = \
 	System.Runtime.Remoting \
 	System \
 	System.Core \
+	System.Web \
+	System.Xml \
 	Mono.Posix \
 	$(NINI_LIBS) \
 	$(LOG4NET_LIBS) \
diff --git a/src/Engine/Messages/MessageBuilder.cs b/src/Engine/Messages/MessageBuilder.cs
index 9498f31..34d20da 100644
--- a/src/Engine/Messages/MessageBuilder.cs
+++ b/src/Engine/Messages/MessageBuilder.cs
@@ -1,6 +1,7 @@
 // Smuxi - Smart MUltipleXed Irc
 // 
-// Copyright (c) 2010 Mirco Bauer <meebey at meebey.net>
+// Copyright (c) 2010-2012 Mirco Bauer <meebey at meebey.net>
+// Copyright (c) 2013 Oliver Schneider <mail at oli-obk.de>
 // 
 // Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
 // 
@@ -19,16 +20,26 @@
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 
 using System;
+using System.Text.RegularExpressions;
 using System.Collections.Generic;
+using System.IO;
+using System.Xml;
+using System.Web;
 
 namespace Smuxi.Engine
 {
     public class MessageBuilder
     {
+#if LOG4NET
+        private static readonly log4net.ILog f_Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+#endif
         MessageModel Message { get; set; }
         public bool NickColors { get; set; }
         public bool StripFormattings { get; set; }
         public bool StripColors { get; set; }
+        public TextColor HighlightColor { get; set; }
+        public List<string> HighlightWords { get; set; }
+        public PersonModel Me { get; set; }
 
         public MessageType MessageType {
             get {
@@ -77,6 +88,12 @@ namespace Smuxi.Engine
             NickColors = (bool) userConfig["Interface/Notebook/Channel/NickColors"];
             StripColors = (bool) userConfig["Interface/Notebook/StripColors"];
             StripFormattings = (bool) userConfig["Interface/Notebook/StripFormattings"];
+            HighlightColor = TextColor.Parse(
+                (string) userConfig["Interface/Notebook/Tab/HighlightColor"]
+            );
+            HighlightWords = new List<string>(
+                (string[]) userConfig["Interface/Chat/HighlightWords"]
+            );
         }
 
         public virtual MessageBuilder Append(MessagePartModel msgPart)
@@ -369,5 +386,236 @@ namespace Smuxi.Engine
         {
             return AppendSenderPrefix(sender, false);
         }
+
+        public bool ContainsHighlight()
+        {
+            return ContainsHighlight(Message.ToString());
+        }
+
+        public virtual bool ContainsHighlight(string text)
+        {
+            Regex regex;
+            if (Me != null) {
+                // First check to see if our current nick is in there.
+                regex = new Regex(
+                    String.Format(
+                        "(^|\\W){0}($|\\W)",
+                        Regex.Escape(Me.IdentityName)
+                    ),
+                    RegexOptions.IgnoreCase
+                );
+                if (regex.Match(text).Success) {
+                    return true;
+                }
+            }
+
+            // go through the user's custom highlight words and check for them.
+            foreach (string highLightWord in HighlightWords) {
+                if (String.IsNullOrEmpty(highLightWord)) {
+                    continue;
+                }
+
+                if (highLightWord.StartsWith("/") && highLightWord.EndsWith("/")) {
+                    // This is a regex, so just build a regex out of the string.
+                    regex = new Regex(
+                        highLightWord.Substring(1, highLightWord.Length - 2)
+                    );
+                } else {
+                    // Plain text - make a regex that matches the word as long as it's separated properly.
+                    string regex_string = String.Format(
+                        "(^|\\W){0}($|\\W)",
+                        Regex.Escape(highLightWord)
+                    );
+                    regex = new Regex(regex_string, RegexOptions.IgnoreCase);
+                }
+
+                if (regex.Match(text).Success) {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        public virtual void MarkHighlights()
+        {
+            bool containsHighlight = false;
+            foreach (var part in Message.MessageParts) {
+                if (!(part is TextMessagePartModel)) {
+                    continue;
+                }
+
+                var textPart = (TextMessagePartModel) part;
+                if (String.IsNullOrEmpty(textPart.Text)) {
+                    // URLs without a link name don't have text
+                    continue;
+                }
+                if (ContainsHighlight(textPart.Text)) {
+                    containsHighlight = true;
+                }
+            }
+
+            if (!containsHighlight) {
+                // nothing to do
+                return;
+            }
+
+            // colorize the whole message
+            foreach (MessagePartModel msgPart in Message.MessageParts) {
+                if (!(msgPart is TextMessagePartModel)) {
+                    continue;
+                }
+
+                TextMessagePartModel textMsg = (TextMessagePartModel) msgPart;
+                if (textMsg.ForegroundColor != null &&
+                    textMsg.ForegroundColor != TextColor.None) {
+                    // HACK: don't overwrite colors as that would replace
+                    // nick-colors for example
+                    continue;
+                }
+                // HACK: we have to mark all parts as highlight else
+                // ClearHighlights() has no chance to properly undo all
+                // highlights
+                textMsg.IsHighlight = true;
+                textMsg.ForegroundColor = HighlightColor;
+            }
+            return;
+        }
+
+        public virtual void ClearHighlights()
+        {
+            foreach (var msgPart in Message.MessageParts) {
+                if (!msgPart.IsHighlight || !(msgPart is TextMessagePartModel)) {
+                    continue;
+                }
+
+                var textMsg = (TextMessagePartModel) msgPart;
+                textMsg.IsHighlight = false;
+                textMsg.ForegroundColor = null;
+            }
+            return;
+        }
+        
+        void ParseStyle(XmlNode style, TextMessagePartModel submodel)
+        {
+            if (style == null) return;
+            var properties = style.InnerText.Split(';');
+            foreach (string property in properties) {
+                var colonpos = property.IndexOf(':');
+                if (colonpos == -1) continue;
+                string name = property.Substring(0, colonpos).Trim();
+                string value = property.Substring(colonpos+1).Trim();
+                switch (name) {
+                    case "background":
+                        value = value.Split(' ')[0];
+                        submodel.BackgroundColor = TextColor.Parse(value);
+                        break;
+                    case "background-color":
+                        submodel.BackgroundColor = TextColor.Parse(value);
+                        break;
+                    case "color":
+                        submodel.ForegroundColor = TextColor.Parse(value);
+                        break;
+                    case "font-style":
+                        if (value == "normal") {
+                            submodel.Italic = false;
+                        } else if (value == "inherit") {
+                        } else {
+                            submodel.Italic = true;
+                        }
+                        break;
+                    case "font-weight":
+                        if (value == "normal") {
+                            submodel.Bold = false;
+                        } else if (value == "inherit") {
+                        } else {
+                            submodel.Bold = true;
+                        }
+                        break;
+                    case "text-decoration":
+                    {
+                        foreach (string val in value.Split(' ')) {
+                            if (val == "underline") {
+                                submodel.Underline = true;
+                            }
+                        }
+                    }
+                        break;
+                    case "font-family":
+                    case "font-size":
+                    case "text-align":
+                    case "margin-left":
+                    case "margin-right":
+                    default:
+                        // ignore formatting
+                        break;
+                }
+            }
+        }
+        
+        void ParseHtml(XmlNode node, TextMessagePartModel model)
+        {
+            TextMessagePartModel submodel;
+            string nodetype = node.Name.ToLower();
+            if (model is UrlMessagePartModel) {
+                submodel = new UrlMessagePartModel(model);
+            } else if (nodetype == "a") {
+                submodel = new UrlMessagePartModel(model);
+                (submodel as UrlMessagePartModel).Url = node.Attributes.GetNamedItem("href").Value;
+            } else {
+                submodel = new TextMessagePartModel(model);
+            }
+            switch (nodetype) {
+                case "b":
+                case "strong":
+                    submodel.Bold = true;
+                    break;
+                case "i":
+                case "em":
+                    submodel.Italic = true;
+                    break;
+                case "u":
+                    submodel.Underline = true;
+                    break;
+                default:
+                    break;
+            }
+            if (node.Attributes != null) {
+                ParseStyle(node.Attributes.GetNamedItem("style"), submodel);
+            }
+            if (node.HasChildNodes) {
+                foreach (XmlNode child in node.ChildNodes) {
+                    ParseHtml(child, submodel);
+                }
+            } else {
+                // final node
+                if (nodetype == "br") {
+                    AppendText("\n");
+                } else if (nodetype == "img") {
+                    AppendUrl(node.Attributes.GetNamedItem("src").Value, "[image placeholder - UNIMPLEMENTED]");
+                } else {
+                    model.Text = node.Value.Replace("\r", "").Replace("\n", "");
+                    model.Text = HttpUtility.HtmlDecode(model.Text);
+                    AppendText(model);
+                }
+            }
+        }
+
+        public virtual MessageBuilder AppendHtmlMessage(string html)
+        {
+            XmlDocument doc = new XmlDocument();
+            try {
+                // wrap in div to prevent messages beginning with text from failing "to be xml"
+                doc.Load(new StringReader("<html>"+html+"</html>"));
+            } catch (XmlException ex) {
+#if LOG4NET
+                f_Logger.Error("AppendHtmlMessage(): error parsing html: " + html, ex);
+#endif
+                AppendText(html);
+                return this;
+            }
+            ParseHtml(doc, new TextMessagePartModel());
+            return this;
+        }
     }
 }
diff --git a/src/Engine/Messages/MessageModel.cs b/src/Engine/Messages/MessageModel.cs
index f2ba948..081c89d 100644
--- a/src/Engine/Messages/MessageModel.cs
+++ b/src/Engine/Messages/MessageModel.cs
@@ -22,6 +22,7 @@
 
 using System;
 using System.Text;
+using System.Text.RegularExpressions;
 using System.Collections;
 using System.Collections.Generic;
 using System.Runtime.Serialization;
@@ -249,6 +250,21 @@ namespace Smuxi.Engine
             f_MessageParts = parts;
         }
 
+        public string GetNick()
+        {
+            // HACK: MessageModel doesn't contain a Sender/Origin property
+            // yet, thus we have to retrieve the information from the
+            // meesage itself
+            // TODO: extend MessageModel with Origin property
+            var msgText = ToString();
+            var match = Regex.Match(msgText, "^<([^ ]+)>");
+            if (match.Success && match.Groups.Count >= 2) {
+                return match.Groups[1].Value;
+            }
+
+            return null;
+        }
+
         public static bool operator ==(MessageModel a, MessageModel b)
         {
             if (System.Object.ReferenceEquals(a, b)) {
diff --git a/src/Engine/Messages/UrlMessagePartModel.cs b/src/Engine/Messages/UrlMessagePartModel.cs
index 9f97618..5a7d798 100644
--- a/src/Engine/Messages/UrlMessagePartModel.cs
+++ b/src/Engine/Messages/UrlMessagePartModel.cs
@@ -79,6 +79,15 @@ namespace Smuxi.Engine
                               this(url, null)
         {
         }
+        
+        public UrlMessagePartModel(TextMessagePartModel model)
+            : base(model)
+        {
+            if (model is UrlMessagePartModel) {
+                _Protocol = (model as UrlMessagePartModel)._Protocol;
+                _Url = (model as UrlMessagePartModel)._Url;
+            }
+        }
 
         public UrlMessagePartModel(string url, string text):
                               this(url, text, UrlProtocol.None)
diff --git a/src/Engine/Protocols/ProtocolManagerBase.cs b/src/Engine/Protocols/ProtocolManagerBase.cs
index f487ab0..22474f1 100644
--- a/src/Engine/Protocols/ProtocolManagerBase.cs
+++ b/src/Engine/Protocols/ProtocolManagerBase.cs
@@ -40,6 +40,8 @@ namespace Smuxi.Engine
         private bool            _IsConnected;
         private PresenceStatus  _PresenceStatus;
 
+        public PersonModel Me { get; protected set; }
+
         public event EventHandler Connected;
         public event EventHandler Disconnected;
         
@@ -220,37 +222,39 @@ namespace Smuxi.Engine
             return _Session.GetChat(id, chatType, this);
         }
 
-        protected virtual MessageBuilder CreateMessageBuilder()
+        protected virtual T GetPerson<T>(ChatModel chat, string personId) where T : PersonModel
         {
-            var builder = new MessageBuilder();
-            builder.ApplyConfig(Session.UserConfig);
-            return builder;
-        }
+            if (personId == null) {
+                throw new ArgumentNullException("personId");
+            }
 
-        protected virtual bool ContainsHighlight(string msg)
-        {
-            Regex regex;
-            //go through the user's custom highlight words and check for them.
-            foreach (string HighlightString in (string[]) Session.UserConfig["Interface/Chat/HighlightWords"]) {
-                if (String.IsNullOrEmpty(HighlightString)) {
-                    continue;
+            T person = null;
+            if (chat is GroupChatModel) {
+                var groupChat = (GroupChatModel) chat;
+                person = (T) groupChat.GetPerson(personId);
+            } else if (chat is PersonChatModel) {
+                var personChat = (PersonChatModel) chat;
+                if (personId == personChat.Person.ID) {
+                    person = (T) personChat.Person;
+                } else if (personId == Me.ID) {
+                    person = (T) Me;
                 }
+            }
 
-                if (HighlightString.StartsWith("/") && HighlightString.EndsWith("/")) {
-                    // This is a regex, so just build a regex out of the string.
-                    regex = new Regex(HighlightString.Substring(1,HighlightString.Length-2));
-                } else {
-                    // Plain text - make a regex that matches the word as long as it's separated properly.
-                    string regex_string = String.Format("(^|\\W){0}($|\\W)", Regex.Escape(HighlightString));
-                    regex = new Regex(regex_string, RegexOptions.IgnoreCase);
-                }
+            return person;
+        }
 
-                if (regex.Match(msg).Success) {
-                    return true;
-                }
-            }
-            
-            return false;
+        protected MessageBuilder CreateMessageBuilder()
+        {
+            return CreateMessageBuilder<MessageBuilder>();
+        }
+
+        protected virtual T CreateMessageBuilder<T>() where T : MessageBuilder, new()
+        {
+            var builder = new T();
+            builder.Me = Me;
+            builder.ApplyConfig(Session.UserConfig);
+            return builder;
         }
 
         protected virtual void DebugRead(string data)
diff --git a/src/Engine/Protocols/ProtocolManagerFactory.cs b/src/Engine/Protocols/ProtocolManagerFactory.cs
index 1564c8e..f27b478 100644
--- a/src/Engine/Protocols/ProtocolManagerFactory.cs
+++ b/src/Engine/Protocols/ProtocolManagerFactory.cs
@@ -56,7 +56,28 @@ namespace Smuxi.Engine
             Trace.Call(filename);
             
             Assembly asm = Assembly.LoadFile(filename);
-            Type[] types = asm.GetTypes();
+            Type[] types;
+            try {
+                types = asm.GetTypes();
+            } catch (ReflectionTypeLoadException ex) {
+#if LOG4NET
+                _Logger.ErrorFormat(
+                    "LoadProtocolManager(): GetTypes() on {0} threw exceptions",
+                    filename
+                );
+                foreach (var loaderEx in ex.LoaderExceptions) {
+                    _Logger.Error(
+                        "LoadProtocolManager(): LoaderException: ",
+                        loaderEx
+                    );
+                    _Logger.Error(
+                        "LoadProtocolManager(): LoaderException.InnerException: ",
+                        loaderEx.InnerException
+                    );
+                }
+#endif
+                throw;
+            }
             
             foreach (Type type in types) {
                 if (type.IsAbstract) {
diff --git a/src/Engine/Session.cs b/src/Engine/Session.cs
index 1eefb78..e23ca74 100644
--- a/src/Engine/Session.cs
+++ b/src/Engine/Session.cs
@@ -1,7 +1,7 @@
 /*
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2005-2012 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2005-2013 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -212,13 +212,12 @@ namespace Smuxi.Engine
                         isError = true;
                     }
                     if (isError) {
-                        fm.AddTextToChat(
-                            _SessionChat,
-                            String.Format(
-                                _("Automatic connect to {0} failed!"),
-                                server.Hostname + ":" + server.Port
-                            )
+                        var builder = CreateMessageBuilder();
+                        builder.AppendErrorText(
+                            _("Automatic connect to {0} failed!"),
+                            server.Hostname + ":" + server.Port
                         );
+                        fm.AddMessageToChat(_SessionChat, builder.ToMessage());
                         continue;
                     }
                 }
@@ -424,7 +423,9 @@ namespace Smuxi.Engine
                 "network list",
                 "network close [network]",
                 "network switch [network]",
-                "config (save|load)",
+                "config (save|load|list)",
+                "config get key",
+                "config set key=value",
                 "shutdown"
             };
 
@@ -445,7 +446,7 @@ namespace Smuxi.Engine
             }
             
             FrontendManager fm = cd.FrontendManager;
-
+            MessageBuilder builder = null;
             string protocol = null;
             ServerModel server = null;
             // first lookup by network name
@@ -496,10 +497,10 @@ namespace Smuxi.Engine
                         throw;
                     }
                     // this is an unknown protocol error
-                    fm.AddTextToChat(
-                        fm.CurrentChat,
-                        String.Format("-!- {0}", ex.Message)
-                    );
+                    builder = CreateMessageBuilder();
+                    builder.AppendEventPrefix();
+                    builder.AppendErrorText(ex.Message);
+                    fm.AddMessageToChat(cd.Chat, builder.ToMessage());
                     return;
                 }
             }
@@ -536,7 +537,10 @@ namespace Smuxi.Engine
 #if LOG4NET
                     f_Logger.Error("CommandConnect(): ", ex);
 #endif
-                    fm.AddTextToChat(cd.Chat, "-!- " + _("Connect failed!"));
+                    builder = CreateMessageBuilder();
+                    builder.AppendEventPrefix();
+                    builder.AppendErrorText(_("Connect failed!"));
+                    fm.AddMessageToChat(cd.Chat, builder.ToMessage());
                 }
             });
         }
@@ -555,14 +559,13 @@ namespace Smuxi.Engine
                 string server = cd.DataArray[1];
                 victim = GetProtocolManagerByHost(server);
                 if (victim == null) {
-                    fm.AddTextToChat(
-                        cd.Chat,
-                        "-!- " +
-                        String.Format(
-                            _("Disconnect failed - could not find server: {0}"),
-                            server
-                        )
+                    var builder = CreateMessageBuilder();
+                    builder.AppendEventPrefix();
+                    builder.AppendErrorText(
+                        _("Disconnect failed - could not find server: {0}"),
+                        server
                     );
+                    fm.AddMessageToChat(cd.Chat, builder.ToMessage());
                     return;
                 }
             } else {
@@ -597,8 +600,11 @@ namespace Smuxi.Engine
 #if LOG4NET
                     f_Logger.Error("CommandReconnect(): ", ex);
 #endif
-                    cd.FrontendManager.AddTextToChat(cd.Chat, "-!- " +
-                        _("Reconnect failed!"));
+                    var builder = CreateMessageBuilder();
+                    builder.AppendEventPrefix();
+                    builder.AppendErrorText(_("Reconnect failed!"));
+                    cd.FrontendManager.AddMessageToChat(cd.Chat,
+                                                        builder.ToMessage());
                 }
             });
         }
@@ -612,26 +618,91 @@ namespace Smuxi.Engine
             }
             
             FrontendManager fm = cd.FrontendManager;
-            if (cd.DataArray.Length >= 2) {
-                switch (cd.DataArray[1].ToLower()) {
-                    case "load":
-                        _Config.Load();
-                        fm.AddTextToChat(cd.Chat, "-!- " +
-                            _("Configuration reloaded"));
-                        break;
-                    case "save":
-                        _Config.Save();
-                        fm.AddTextToChat(cd.Chat, "-!- " +
-                            _("Configuration saved"));
-                        break;
-                    default:
-                        fm.AddTextToChat(cd.Chat, "-!- " + 
-                            _("Invalid parameter for config; use load or save"));
-                        break;
-                }
-            } else {
+            if (cd.DataArray.Length < 2) {
                 _NotEnoughParameters(cd);
+                return;
+            }
+            var builder = CreateMessageBuilder();
+            builder.AppendEventPrefix();
+            var action = cd.DataArray[1].ToLower();
+            switch (action) {
+                case "load":
+                    _Config.Load();
+                    builder.AppendText(_("Configuration reloaded"));
+                    break;
+                case "save":
+                    _Config.Save();
+                    builder.AppendText(_("Configuration saved"));
+                    break;
+                case "get":
+                case "list":
+                    string key = null;
+                    if (action == "get") {
+                        if (cd.DataArray.Length < 3) {
+                            _NotEnoughParameters(cd);
+                            return;
+                        }
+                        key = cd.DataArray[2];
+                    }
+                    foreach (var entry in _UserConfig.OrderBy(kvp => kvp.Key)) {
+                        if (key != null &&
+                            entry.Key.IndexOf(key, StringComparison.InvariantCultureIgnoreCase) == -1) {
+                            continue;
+                        }
+                        builder = CreateMessageBuilder();
+                        builder.AppendEventPrefix();
+                        builder.AppendText("{0} = {1}", entry.Key, entry.Value);
+                        fm.AddMessageToChat(cd.Chat, builder.ToMessage());
+                    }
+                    return;
+                case "set":
+                    if (cd.DataArray.Length < 3) {
+                        _NotEnoughParameters(cd);
+                        return;
+                    }
+                    string setParam = cd.DataArray[2];
+                    if (!setParam.Contains("=")) {
+                        builder.AppendErrorText(
+                            _("Invalid key/value format.")
+                        );
+                        fm.AddMessageToChat(cd.Chat, builder.ToMessage());
+                        return;
+                    }
+                    string setKey = setParam.Split('=')[0];
+                    string setValue = setParam.Split('=')[1];
+                    object oldValue = _UserConfig[setKey];
+                    if (oldValue == null) {
+                        builder.AppendErrorText(
+                            _("Invalid config key: '{0}'"),
+                            setKey
+                        );
+                    } else {
+                        try {
+                            object newValue = Convert.ChangeType(setValue, oldValue.GetType());
+                            _UserConfig[setKey] = newValue;
+                            builder.AppendText("{0} = {1}", setKey, newValue.ToString());
+                        } catch (InvalidCastException) {
+                            builder.AppendErrorText(
+                                _("Could not convert config value: '{0}' to type: {1}"),
+                                setValue,
+                                oldValue.GetType().Name
+                            );
+                        } catch (FormatException) {
+                            builder.AppendErrorText(
+                                _("Could not convert config value: '{0}' to type: {1}"),
+                                setValue,
+                                oldValue.GetType().Name
+                            );
+                        }
+                    }
+                    break;
+                default:
+                    builder.AppendErrorText(
+                        _("Invalid parameter for config; use load, save, get or set.")
+                    );
+                    break;
             }
+            fm.AddMessageToChat(cd.Chat, builder.ToMessage());
         }
         
         public void CommandShutdown(CommandModel cmd)
@@ -690,8 +761,13 @@ namespace Smuxi.Engine
                         _CommandNetworkClose(cd);
                         break;
                     default:
-                        fm.AddTextToChat(cd.Chat, "-!- " + 
-                            _("Invalid parameter for network; use list, switch, or close"));
+                        var builder = CreateMessageBuilder();
+                        builder.AppendEventPrefix();
+                        builder.AppendText(
+                            _("Invalid parameter for network; use list, " +
+                              "switch, or close")
+                        );
+                        fm.AddMessageToChat(cd.Chat, builder.ToMessage());
                         break;
                 }
             } else {
@@ -768,9 +844,10 @@ namespace Smuxi.Engine
                 string network = cd.DataArray[2];
                 pm = GetProtocolManagerByNetwork(network);
                 if (pm == null) {
-                    fm.AddTextToChat(cd.Chat, "-!- " +
-                        String.Format(_("Network close failed - could not find network: {0}"),
-                                      network));
+                    var builder = CreateMessageBuilder();
+                    builder.AppendText(_("Network close failed - could not " +
+                                         "find network: {0}"), network);
+                    fm.AddMessageToChat(cd.Chat, builder.ToMessage());
                     return;
                 }
             } else if (cd.DataArray.Length >= 2) {
@@ -789,7 +866,6 @@ namespace Smuxi.Engine
                     pm.Dispose();
                     // Dispose() takes care of removing the chat from session (frontends)
                     _ProtocolManagers.Remove(pm);
-                    fm.NextProtocolManager();
                 } catch (Exception ex) {
 #if LOG4NET
                     f_Logger.Error("_CommandNetworkClose(): Exception", ex);
@@ -806,10 +882,10 @@ namespace Smuxi.Engine
                 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));
+                    var builder = CreateMessageBuilder();
+                    builder.AppendText(_("Network switch failed - could not " +
+                                         "find network: {0}"), network);
+                    fm.AddMessageToChat(cd.Chat, builder.ToMessage());
                     return;
                 }
                 fm.CurrentProtocolManager = pm;
@@ -824,25 +900,17 @@ namespace Smuxi.Engine
         
         private void _NotConnected(CommandModel cd)
         {
-            cd.FrontendManager.AddTextToChat(
-                cd.Chat,
-                String.Format("-!- {0}",
-                    _("Not connected to any network")
-                )
-            );
+            var builder = CreateMessageBuilder();
+            builder.AppendText(_("Not connected to any network"));
+            cd.FrontendManager.AddMessageToChat(cd.Chat, builder.ToMessage());
         }
         
         private void _NotEnoughParameters(CommandModel cd)
         {
-            cd.FrontendManager.AddTextToChat(
-                cd.Chat,
-                String.Format("-!- {0}",
-                    String.Format(
-                        _("Not enough parameters for {0} command"),
-                        cd.Command
-                    )
-                )
-            );
+            var builder = CreateMessageBuilder();
+            builder.AppendText(_("Not enough parameters for {0} command"),
+                               cd.Command);
+            cd.FrontendManager.AddMessageToChat(cd.Chat, builder.ToMessage());
         }
         
         public void UpdateNetworkStatus()
@@ -881,6 +949,18 @@ namespace Smuxi.Engine
         }
 
         public PersonChatModel CreatePersonChat(PersonModel person,
+                                                IProtocolManager protocolManager)
+        {
+            Trace.Call(person, protocolManager);
+
+            if (person == null) {
+                throw new ArgumentNullException("person");
+            }
+            return CreatePersonChat(person, person.ID, person.IdentityName,
+                                    protocolManager);
+        }
+
+        public PersonChatModel CreatePersonChat(PersonModel person,
                                                 string id, string name,
                                                 IProtocolManager protocolManager)
         {
@@ -1011,11 +1091,13 @@ namespace Smuxi.Engine
             }
         }
 
+        [Obsolete("This method is deprecated, use AddMessageToChat(ChatModel, MessageModel) instead!")]
         public void AddTextToChat(ChatModel chat, string text)
         {
             AddTextToChat(chat, text, false);
         }
 
+        [Obsolete("This method is deprecated, use AddMessageToChat(ChatModel, MessageModel, bool) instead!")]
         public void AddTextToChat(ChatModel chat, string text, bool ignoreFilters)
         {
             if (chat == null) {
@@ -1103,6 +1185,7 @@ namespace Smuxi.Engine
 #if LOG4NET
             f_Logger.Debug("AddPersonToGroupChat() groupChat.Name: "+groupChat.Name+" person.IdentityName: "+person.IdentityName);
 #endif
+            groupChat.UnsafePersons.Add(person.ID, person);
             lock (_FrontendManagers) {
                 foreach (FrontendManager fm in _FrontendManagers.Values) {
                     fm.AddPersonToGroupChat(groupChat, person);
@@ -1131,8 +1214,8 @@ namespace Smuxi.Engine
             // FIXME: do we have to lock groupChat.UnsafePersons here?
             // probably not, as long as the ProtocolManager who owns this chat
             // is only running one thread
-            groupChat.UnsafePersons.Remove(oldPerson.ID.ToLower());
-            groupChat.UnsafePersons.Add(newPerson.ID.ToLower(), newPerson);
+            groupChat.UnsafePersons.Remove(oldPerson.ID);
+            groupChat.UnsafePersons.Add(newPerson.ID, newPerson);
             lock (_FrontendManagers) {
                 foreach (FrontendManager fm in _FrontendManagers.Values) {
                     fm.UpdatePersonInGroupChat(groupChat, oldPerson, newPerson);
@@ -1172,7 +1255,7 @@ namespace Smuxi.Engine
 #if LOG4NET
             f_Logger.Debug("RemovePersonFromGroupChat() groupChat.Name: " + groupChat.Name + " person.ID: "+person.ID);
 #endif
-            groupChat.UnsafePersons.Remove(person.ID.ToLower());
+            groupChat.UnsafePersons.Remove(person.ID);
             lock (_FrontendManagers) {
                 foreach (FrontendManager fm in _FrontendManagers.Values) {
                     fm.RemovePersonFromGroupChat(groupChat, person);
diff --git a/src/Engine/TextColorTools.cs b/src/Engine/TextColorTools.cs
index df6f542..9d611b9 100644
--- a/src/Engine/TextColorTools.cs
+++ b/src/Engine/TextColorTools.cs
@@ -167,5 +167,87 @@ namespace Smuxi.Engine
                           114d * color2.Blue) / 1000d;
             return Math.Abs(br1 - br2);
         }
+
+        // algorithm ported from JavaScript to C# from:
+        // http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
+        internal static HslColor ToHSL(TextColor color)
+        {
+            var R = color.Red / 255d;
+            var G = color.Green / 255d;
+            var B = color.Blue / 255d;
+            var max = Math.Max(Math.Max(R, G), B);
+            var min = Math.Min(Math.Min(R, G), B);
+
+            double H = 0d, S, L;
+            var range = max + min;
+            L = range / 2d;
+            if (max == min) {
+                S = 0d; // achromatic
+            } else {
+                var diff = max - min;
+                S = L > 0.5d ? diff / (2 - diff) : diff / range;
+                if (max == R) {
+                    H = (G - B) / diff + (G < B ? 6d : 0d);
+                } else if (max == G) {
+                    H = (B - R) / diff + 2;
+                } else if (max == B) {
+                    H = (R - G) / diff + 4;
+                }
+                H /= 6;
+            }
+            return new HslColor(H, S, L);
+        }
+
+        public static TextColor GetNearestColor(TextColor color, IEnumerable<TextColor> palette)
+        {
+            if (palette == null) {
+                throw new ArgumentNullException("palette");
+            }
+
+            var hslColor1 = ToHSL(color);
+            TextColor nearestColor = null;
+            double nearestDifference = Double.MaxValue;
+            foreach (var color2 in palette) {
+                // compute the Euclidean distance between the two HSL colors
+                // without root square as we only compare the values
+                // see http://en.wikipedia.org/wiki/Color_difference#Delta_E
+                var hslColor2 = ToHSL(color2);
+                var H1 = hslColor1.Hue;
+                var S1 = hslColor1.Saturation;
+                var L1 = hslColor1.Lightness;
+                var H2 = hslColor2.Hue;
+                var S2 = hslColor2.Saturation;
+                var L2 = hslColor2.Lightness;
+                var Hdelta = H1 - H2;
+                var Sdelta = S1 - S2;
+                var Ldelta = L1 - L2;
+                var deltaE = (Hdelta * Hdelta) +
+                             (Sdelta * Sdelta) +
+                             (Ldelta * Ldelta);
+                if (deltaE < nearestDifference) {
+                    nearestDifference = deltaE;
+                    nearestColor = color2;
+                }
+                if (deltaE == 0d) {
+                    // found perfect match, can't get better than that
+                    break;
+                }
+            }
+            return nearestColor;
+        }
+
+        internal class HslColor
+        {
+            public double Hue { get; set; }
+            public double Saturation { get; set; }
+            public double Lightness { get; set; }
+
+            public HslColor(double H, double S, double L)
+            {
+                Hue = H;
+                Saturation = S;
+                Lightness = L;
+            }
+        }
     }
 }
diff --git a/src/Frontend-Curses/Makefile.in b/src/Frontend-Curses/Makefile.in
index af95a7f..4d51482 100644
--- a/src/Frontend-Curses/Makefile.in
+++ b/src/Frontend-Curses/Makefile.in
@@ -58,8 +58,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
@@ -150,9 +153,8 @@ 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_CAMPFIRE = @GETTEXT_PACKAGE_ENGINE_CAMPFIRE@
 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@
@@ -164,6 +166,9 @@ 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@
+GIO_SHARP_CFLAGS = @GIO_SHARP_CFLAGS@
+GIO_SHARP_FILES = @GIO_SHARP_FILES@
+GIO_SHARP_LIBS = @GIO_SHARP_LIBS@
 GLADE_SHARP_20_CFLAGS = @GLADE_SHARP_20_CFLAGS@
 GLADE_SHARP_20_LIBS = @GLADE_SHARP_20_LIBS@
 GLIB_SHARP_20_CFLAGS = @GLIB_SHARP_20_CFLAGS@
@@ -210,6 +215,11 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
+MESSAGINGMENU_SHARP_CFLAGS = @MESSAGINGMENU_SHARP_CFLAGS@
+MESSAGINGMENU_SHARP_FILES = @MESSAGINGMENU_SHARP_FILES@
+MESSAGINGMENU_SHARP_LIBS = @MESSAGINGMENU_SHARP_LIBS@
+MESSAGING_MENU_CFLAGS = @MESSAGING_MENU_CFLAGS@
+MESSAGING_MENU_LIBS = @MESSAGING_MENU_LIBS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
 MONO_MODULE_CFLAGS = @MONO_MODULE_CFLAGS@
@@ -217,8 +227,6 @@ 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@
@@ -231,8 +239,6 @@ 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@
diff --git a/src/Frontend-GNOME-IRC/InviteToMenu.cs b/src/Frontend-GNOME-IRC/InviteToMenu.cs
index 94a738e..48ca586 100644
--- a/src/Frontend-GNOME-IRC/InviteToMenu.cs
+++ b/src/Frontend-GNOME-IRC/InviteToMenu.cs
@@ -68,6 +68,15 @@ namespace Smuxi.Frontend.Gnome
                 IsPopulated = true;
                 foreach (var chatView in ChatViewManager.Chats) {
                     if (!(chatView is GroupChatView)) {
+                        // only invite to group chats
+                        continue;
+                    }
+                    if (chatView == ChatViewManager.ActiveChat) {
+                        // don't need to add current chat to invite list
+                        continue;
+                    }
+                    if (chatView.ProtocolManager != ProtocolManager) {
+                        // only add chats from current server
                         continue;
                     }
 
diff --git a/src/Frontend-GNOME-IRC/Makefile.in b/src/Frontend-GNOME-IRC/Makefile.in
index 1b45aa2..84757ef 100644
--- a/src/Frontend-GNOME-IRC/Makefile.in
+++ b/src/Frontend-GNOME-IRC/Makefile.in
@@ -57,8 +57,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
@@ -149,9 +152,8 @@ 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_CAMPFIRE = @GETTEXT_PACKAGE_ENGINE_CAMPFIRE@
 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@
@@ -163,6 +165,9 @@ 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@
+GIO_SHARP_CFLAGS = @GIO_SHARP_CFLAGS@
+GIO_SHARP_FILES = @GIO_SHARP_FILES@
+GIO_SHARP_LIBS = @GIO_SHARP_LIBS@
 GLADE_SHARP_20_CFLAGS = @GLADE_SHARP_20_CFLAGS@
 GLADE_SHARP_20_LIBS = @GLADE_SHARP_20_LIBS@
 GLIB_SHARP_20_CFLAGS = @GLIB_SHARP_20_CFLAGS@
@@ -209,6 +214,11 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
+MESSAGINGMENU_SHARP_CFLAGS = @MESSAGINGMENU_SHARP_CFLAGS@
+MESSAGINGMENU_SHARP_FILES = @MESSAGINGMENU_SHARP_FILES@
+MESSAGINGMENU_SHARP_LIBS = @MESSAGINGMENU_SHARP_LIBS@
+MESSAGING_MENU_CFLAGS = @MESSAGING_MENU_CFLAGS@
+MESSAGING_MENU_LIBS = @MESSAGING_MENU_LIBS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
 MONO_MODULE_CFLAGS = @MONO_MODULE_CFLAGS@
@@ -216,8 +226,6 @@ 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@
@@ -230,8 +238,6 @@ 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@
diff --git a/src/Frontend-GNOME-XMPP/Makefile.in b/src/Frontend-GNOME-XMPP/Makefile.in
index a0bab93..07acb78 100644
--- a/src/Frontend-GNOME-XMPP/Makefile.in
+++ b/src/Frontend-GNOME-XMPP/Makefile.in
@@ -57,8 +57,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
@@ -149,9 +152,8 @@ 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_CAMPFIRE = @GETTEXT_PACKAGE_ENGINE_CAMPFIRE@
 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@
@@ -163,6 +165,9 @@ 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@
+GIO_SHARP_CFLAGS = @GIO_SHARP_CFLAGS@
+GIO_SHARP_FILES = @GIO_SHARP_FILES@
+GIO_SHARP_LIBS = @GIO_SHARP_LIBS@
 GLADE_SHARP_20_CFLAGS = @GLADE_SHARP_20_CFLAGS@
 GLADE_SHARP_20_LIBS = @GLADE_SHARP_20_LIBS@
 GLIB_SHARP_20_CFLAGS = @GLIB_SHARP_20_CFLAGS@
@@ -209,6 +214,11 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
+MESSAGINGMENU_SHARP_CFLAGS = @MESSAGINGMENU_SHARP_CFLAGS@
+MESSAGINGMENU_SHARP_FILES = @MESSAGINGMENU_SHARP_FILES@
+MESSAGINGMENU_SHARP_LIBS = @MESSAGINGMENU_SHARP_LIBS@
+MESSAGING_MENU_CFLAGS = @MESSAGING_MENU_CFLAGS@
+MESSAGING_MENU_LIBS = @MESSAGING_MENU_LIBS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
 MONO_MODULE_CFLAGS = @MONO_MODULE_CFLAGS@
@@ -216,8 +226,6 @@ 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@
@@ -230,8 +238,6 @@ 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@
diff --git a/src/Frontend-GNOME/AboutDialog.cs b/src/Frontend-GNOME/AboutDialog.cs
index d829df8..72c6021 100644
--- a/src/Frontend-GNOME/AboutDialog.cs
+++ b/src/Frontend-GNOME/AboutDialog.cs
@@ -35,7 +35,7 @@ namespace Smuxi.Frontend.Gnome
             }
             
             TransientFor = parent;
-            Name = Frontend.Name;
+            ProgramName = Frontend.Name;
             var version = Frontend.Version.ToString();
             var distVersion = Defines.DistVersion;
             if (!String.IsNullOrEmpty(distVersion)) {
@@ -50,20 +50,27 @@ namespace Smuxi.Frontend.Gnome
                 "Clément Bourgeois <moonpyk 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>"
+                "Bianca Mix <heavydemon at freenet.de>",
+                "Oliver Schneider <mail at oli-obk.de>",
+                "Carlos Martín Nieto <cmn at dwim.me>"
             };
             Artists = new string[] {
                 "Jakub Steiner <jimmac at ximian.com>",
                 "Rodney Dawes <dobey at novell.com>",
                 "Lapo Calamandrei <calamandrei at gmail.com>",
-                "Ahmed Abdellah <a3dman1 at gmail.com>"
+                "Ahmed Abdellah <a3dman1 at gmail.com>",
+                "Matthieu James <matthieu.james at gmail.com>",
+                "George Karavasilev <motorslav at gmail.com>"
             };
             TranslatorCredits = _("translator-credits");
             Logo = Frontend.LoadIcon(
                 Frontend.IconName, 256, "icon_256x256.png"
             );
-            Website = "http://www.smuxi.org/";
-            WebsiteLabel = _("Smuxi Website");
+            // HACK: shows "not implemented" error on OS X
+            if (!Frontend.IsMacOSX) {
+                Website = "http://www.smuxi.org/";
+                WebsiteLabel = _("Smuxi Website");
+            }
         }
         
         private static string _(string msg)
diff --git a/src/Frontend-GNOME/ChatViewManager.cs b/src/Frontend-GNOME/ChatViewManager.cs
index ede6de4..acec410 100644
--- a/src/Frontend-GNOME/ChatViewManager.cs
+++ b/src/Frontend-GNOME/ChatViewManager.cs
@@ -95,7 +95,7 @@ namespace Smuxi.Frontend.Gnome
         public bool IsSensitive {
             set {
                 f_Notebook.Sensitive = value;
-                Frontend.MainWindow.MenuBar.Sensitive = value;
+                Frontend.MainWindow.MenuWidget.Sensitive = value;
                 Frontend.MainWindow.Entry.Sensitive = value;
             }
             get {
@@ -138,6 +138,7 @@ namespace Smuxi.Frontend.Gnome
 
             f_Notebook.RemovePage(f_Notebook.PageNum(chatView));
             f_Chats.Remove(chatView);
+            SyncManager.Remove(chat);
             SyncedChats.Remove(chatView);
 
             if (ChatRemoved != null) {
@@ -227,6 +228,20 @@ namespace Smuxi.Frontend.Gnome
             SyncManager.Clear();
         }
 
+        public void ClearAllActivity()
+        {
+            Trace.Call();
+
+            f_Notebook.ClearAllActivity();
+        }
+
+        public void Minimize()
+        {
+            Trace.Call();
+
+            Frontend.MainWindow.Iconify();
+        }
+
         void OnChatAdded(object sender, ChatViewAddedEventArgs e)
         {
             Trace.Call(sender, e);
@@ -238,6 +253,7 @@ namespace Smuxi.Frontend.Gnome
                 chatView.ID = e.ChatID;
                 chatView.Name = e.ChatID;
                 chatView.Position = e.ChatPosition;
+                chatView.ProtocolManager = e.ProtocolManager;
                 f_Chats.Add(chatView);
 
                 if (f_Config != null) {
diff --git a/src/Frontend-GNOME/Entry.cs b/src/Frontend-GNOME/Entry.cs
index b3537e5..35f912e 100644
--- a/src/Frontend-GNOME/Entry.cs
+++ b/src/Frontend-GNOME/Entry.cs
@@ -1,7 +1,7 @@
 /*
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2005-2012 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2005-2013 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -43,6 +43,8 @@ namespace Smuxi.Frontend.Gnome
         private CommandManager   _CommandManager;
         private new EntrySettings Settings { get; set; }
 
+        private NickCompleter NickCompleter { get; set; }
+
         ChatViewManager ChatViewManager;
         event EventHandler<EventArgs> Activated;
 
@@ -243,8 +245,7 @@ namespace Smuxi.Frontend.Gnome
         
         protected virtual void ProcessKey(Gtk.KeyPressEventArgs e)
         {
-            if (Environment.OSVersion.Platform == PlatformID.Win32NT &&
-                Text.Length == 0) {
+            if (Frontend.IsWindows && String.IsNullOrEmpty(Text)) {
                 // HACK: workaround rendering issue on Windows where the text
                 // cursor and first typed character are not showing up until
                 // a 2nd character is typed, see #810
@@ -282,11 +283,20 @@ namespace Smuxi.Frontend.Gnome
                             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:
+                        // only use copy if something is selected in the entry
+                        if (Buffer.HasSelection) {
+                            e.RetVal = false;
+                            break;
+                        }
+                        // copy selection from main chat window
+                        var buf = ChatViewManager.CurrentChatView.OutputMessageTextView.Buffer;
+                        buf.CopyClipboard(Gtk.Clipboard.Get(Gdk.Selection.Clipboard));
+                        break;
+                    // don't break unicode input
+                    case Gdk.Key.U:
+                    // don't break paste
                     case Gdk.Key.v:
                     case Gdk.Key.V:
                     // don't break select all
@@ -305,6 +315,10 @@ namespace Smuxi.Frontend.Gnome
                     case Gdk.Key.End:
                         ChatViewManager.CurrentChatView.ScrollToEnd();
                         break;
+                    // anything else we let GTK+ handle
+                    default:
+                        e.RetVal = false;
+                        break;
                 }
             }
             
@@ -357,6 +371,30 @@ namespace Smuxi.Frontend.Gnome
                         pagenumber = 19;
                         break;
                 }
+                switch (key) {
+                    case Gdk.Key.h:
+                    case Gdk.Key.H:
+                        if (Frontend.IsMacOSX) {
+                            Frontend.MainWindow.Iconify();
+                            e.RetVal = true;
+                        }
+                        break;
+                    case Gdk.Key.braceleft:
+                    case Gdk.Key.Up:
+                        if (Frontend.IsMacOSX) {
+                            ChatViewManager.CurrentChatNumber--;
+                            e.RetVal = true;
+                        }
+                        break;
+                    case Gdk.Key.braceright:
+                    case Gdk.Key.Down:
+                        if (Frontend.IsMacOSX) {
+                            ChatViewManager.CurrentChatNumber++;
+                            e.RetVal = true;
+                        }
+                        break;
+                }
+
 
                 if (pagenumber != -1) {
                     ChatViewManager.CurrentChatNumber = pagenumber;
@@ -432,8 +470,9 @@ namespace Smuxi.Frontend.Gnome
                 }
                 
                 if (Text.IndexOf("\n") != -1) {
+                    var text = Text.TrimEnd('\n');
                     // seems to be a paste, so let's break it apart
-                    string[] msgParts = Text.Split(new char[] {'\n'});
+                    string[] msgParts = text.Split(new char[] {'\n'});
                     if (msgParts.Length > 3) {
                         string msg = String.Format(_("You are going to paste {0} lines. Do you want to continue?"),
                                                    msgParts.Length);
@@ -450,8 +489,13 @@ namespace Smuxi.Frontend.Gnome
                             return;
                         }
                     }
-                    foreach (string msg in msgParts) {
-                        ExecuteCommand(msg);
+                    if (Frontend.EngineVersion < new Version(0,8,11)) {
+                        foreach (string msg in msgParts) {
+                            ExecuteCommand(msg);
+                        }
+                    } else {
+                        // new engines know how to handle messages containing \n
+                        ExecuteCommand(text);
                     }
                 } else {
                     ExecuteCommand(Text);
@@ -511,10 +555,6 @@ namespace Smuxi.Frontend.Gnome
                         _CommandEcho(cd);
                         handled = true;
                         break;
-                    case "exec":
-                        _CommandExec(cd);
-                        handled = true;
-                        break;
                     case "window":
                         _CommandWindow(cd);
                         handled = true;
@@ -531,6 +571,14 @@ namespace Smuxi.Frontend.Gnome
                         _CommandSync(cd);
                         handled = true;
                         break;
+                    case "gc":
+                        GC.Collect();
+                        handled = true;
+                        break;
+                    case "generate_messages":
+                        CommandGenerateMessages(cd);
+                        handled = true;
+                        break;
                 }
             }
             
@@ -567,7 +615,7 @@ namespace Smuxi.Frontend.Gnome
 
         private void _CommandList(CommandModel cd)
         {
-            Frontend.MainWindow.OpenFindGroupChatWindow(cd.Parameter);
+            Frontend.OpenFindGroupChatWindow(cd.Parameter);
         }
 
         private void _CommandDetach(CommandModel cd)
@@ -577,38 +625,15 @@ namespace Smuxi.Frontend.Gnome
 
         private void _CommandEcho(CommandModel cd)
         {
-            cd.FrontendManager.AddTextToChat(
-                cd.Chat,
-                String.Format("-!- {0}", cd.Parameter)
-            );
-        }
-        
-        private void _CommandExec(CommandModel cd)
-        {
-            if (cd.DataArray.Length >= 2) {
-                string output;
-                System.Diagnostics.Process process = new System.Diagnostics.Process();
-                process.StartInfo.FileName = cd.DataArray[1];
-                if (cd.DataArray.Length >= 3) { 
-                    process.StartInfo.Arguments = String.Join(" ", cd.DataArray,
-                                                    2, cd.DataArray.Length-2);
-                }
-                process.StartInfo.RedirectStandardOutput = true;
-                process.StartInfo.RedirectStandardError = true;
-                process.StartInfo.UseShellExecute = false;
-                
-                try {
-                    process.Start();
-                    output = process.StandardOutput.ReadToEnd();
-                    cd.FrontendManager.AddTextToChat(cd.Chat, output);
-                } catch {
-                }
-            }
+            var msg = new MessageBuilder().
+                AppendEventPrefix().
+                AppendText(cd.Parameter).
+                ToMessage();
+            cd.FrontendManager.AddMessageToChat(cd.Chat, msg);
         }
     
         private void _CommandWindow(CommandModel cd)
         {
-            FrontendManager fm = cd.FrontendManager;
             if (cd.DataArray.Length >= 2) {
                 var currentChat = ChatViewManager.CurrentChatView;
                 if (cd.Parameter.ToLower() == "close") {
@@ -684,150 +709,58 @@ namespace Smuxi.Frontend.Gnome
             ChatViewManager.CurrentChatView.Clear();
         }
 
-        private void _NickCompletion()
+        void CommandGenerateMessages(CommandModel cd)
         {
-            // return if we don't support the current ChatView
-            if (!(ChatViewManager.CurrentChatView is GroupChatView) &&
-                !(ChatViewManager.CurrentChatView is PersonChatView)) {
-                return;
-            }
+            var count = 0;
+            Int32.TryParse(cd.Parameter, out count);
 
-            int position = Position;
-            string text = Text;
-            string word;
-            int previous_space;
-            int next_space;
-
-            // find the current word
-            string temp;
-            temp = text.Substring(0, position);
-            previous_space = temp.LastIndexOf(' ');
-            next_space = text.IndexOf(' ', position);
-
-#if LOG4NET
-            _Logger.Debug("previous_space: "+previous_space);
-            _Logger.Debug("next_space: "+next_space);
-#endif
-
-            if (previous_space != -1 && next_space != -1) {
-                // previous and next space exist
-                word = text.Substring(previous_space + 1, next_space - previous_space - 1);
-            } else if (previous_space != -1) {
-                // previous space exist
-                word = text.Substring(previous_space + 1);
-            } else if (next_space != -1) {
-                // next space exist
-                word = text.Substring(0, next_space);
-            } else {
-                // no spaces
-                word = text;
-            }
-
-            if (word == String.Empty) {
-                return;
-            }
-
-            bool leadingAt = false;
-            // remove leading @ character
-            if (word.StartsWith("@")) {
-                word = word.Substring(1);
-                leadingAt = true;
-            }
-
-            // find the possible nickname
-            bool found = false;
-            bool partial_found = false;
-            string nick = null;
-
-            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
-                    } else if (result.Count == 1) {
-                        found = true;
-                        nick = result[0];
-                    } else if (result.Count >= 2) {
-                        string[] nickArray = new string[result.Count];
-                        result.CopyTo(nickArray, 0);
-                        string nicks = String.Join(" ", nickArray, 1, nickArray.Length - 1);
-                        ChatViewManager.CurrentChatView.AddMessage(
-                            new MessageModel(String.Format("-!- {0}", nicks))
-                        );
-                        found = true;
-                        partial_found = true;
-                        nick = result[0];
-                    }
-                } else {
-                    PersonModel person = cp.PersonLookup(word);
-                    if (person != null) {
-                        found = true;
-                        nick = person.IdentityName;
-                     }
-                }
-            } else {
-                var personChat = (PersonChatView) ChatViewManager.CurrentChatView;
-                var personModel = personChat.PersonModel;
-                if (personModel.IdentityName.StartsWith(word,
-                        StringComparison.InvariantCultureIgnoreCase)) {
-                    found = true;
-                    nick = personModel.IdentityName;
-                }
-            }
+            var chat = ChatViewManager.CurrentChatView;
+            var builder = new MessageBuilder();
+            var sender = new ContactModel("msg-tester", "msg-tester", "test", "test");
+            builder.AppendMessage(sender, "time for a messsage generator command so I can test speed and memory usage");
+            var text = builder.CreateText(" *formatted text* ");
+            text.Bold = true;
+            builder.Append(text);
+            builder.AppendUrl("https://www.smuxi.org/");
+
+            var msgs = new List<MessageModel>(count);
+            for (var i = 0; i < count; i++) {
+                var msg = builder.ToMessage();
+                msgs.Add(msg);
+            }
+
+            DateTime start, stop;
+            start = DateTime.UtcNow;
+            foreach (var msg in msgs) {
+                chat.AddMessage(msg);
+            }
+            stop = DateTime.UtcNow;
+
+            builder = new MessageBuilder();
+            builder.AppendText(
+                "ChatView.AddMessage(): count: {0} took: {1:0} ms avg: {2:0.00} ms",
+                count,
+                (stop - start).TotalMilliseconds,
+                (stop - start).TotalMilliseconds / count
+            );
+            chat.AddMessage(builder.ToMessage());
 
-            string completionChar = Settings.CompletionCharacter;
-            // add leading @ back and supress completion character
-            if (leadingAt) {
-                word = String.Format("@{0}", word);
-                nick = String.Format("@{0}", nick);
-                completionChar = String.Empty;
-            }
+            builder = new MessageBuilder();
+            builder.AppendText(
+                "ChatView.AddMessage(): MessageTextTagTable.Size: {0}",
+                chat.OutputMessageTextView.MessageTextTagTable.Size
+            );
+            chat.AddMessage(builder.ToMessage());
+        }
 
-            if (found) {
-                // put the found nickname in place
-                if (previous_space != -1 && next_space != -1) {
-                    // previous and next space exist
-                    temp = text.Remove(previous_space + 1, word.Length);
-                    temp = temp.Insert(previous_space + 1, nick);
-                    Text = temp;
-                    if (partial_found) {
-                        Position = previous_space + 1 + nick.Length;
-                    } else {
-                        Position = previous_space + 2 + nick.Length;
-                    }
-                } else if (previous_space != -1) {
-                    // only previous space exist
-                    temp = text.Remove(previous_space + 1, word.Length);
-                    temp = temp.Insert(previous_space + 1, nick);
-                    if (partial_found) {
-                        Text = temp;
-                    } else {
-                        Text = temp + " ";
-                    }
-                    Position = previous_space + 2 + nick.Length;
-                } else if (next_space != -1) {
-                    // only next space exist
-                    temp = text.Remove(0, next_space + 1);
-                    if (partial_found) {
-                        Text = nick + " " + temp;
-                        Position = nick.Length;
-                    } else {
-                        Text = String.Format("{0}{1} {2}", nick,
-                                             completionChar, temp);
-                        Position = nick.Length + completionChar.Length + 1;
-                    }
-                } else {
-                    // no spaces
-                    if (partial_found) {
-                        Text = nick;
-                    } else {
-                        Text = String.Format("{0}{1} ", nick, completionChar);
-                    }
-                    Position = -1;
-                }
-            }
+        private void _NickCompletion()
+        {
+            // perform completion
+            string text = Text;
+            int position = Position;
+            NickCompleter.Complete(ref text, ref position, ChatViewManager.CurrentChatView);
+            Text = text;
+            Position = position;
         }
         
         public virtual void ApplyConfig(UserConfig config)
@@ -852,6 +785,16 @@ namespace Smuxi.Frontend.Gnome
             ModifyFont(theme.FontDescription);
 
             Settings.ApplyConfig(config);
+
+            // replace nick completer if needed
+            if (Settings.BashStyleCompletion && !(NickCompleter is LongestPrefixNickCompleter)) {
+                NickCompleter = new LongestPrefixNickCompleter();
+            } else if (!Settings.BashStyleCompletion && !(NickCompleter is TabCycleNickCompleter)) {
+                NickCompleter = new TabCycleNickCompleter();
+            }
+
+            // set the completion character
+            NickCompleter.CompletionChar = Settings.CompletionCharacter;
         }
 
         private void InitCommandManager()
diff --git a/src/Frontend-GNOME/FindGroupChatDialog.cs b/src/Frontend-GNOME/FindGroupChatDialog.cs
index 8784819..49a754f 100644
--- a/src/Frontend-GNOME/FindGroupChatDialog.cs
+++ b/src/Frontend-GNOME/FindGroupChatDialog.cs
@@ -147,7 +147,7 @@ namespace Smuxi.Frontend.Gnome
                                 );
                             }
                         });
-                    } catch (ThreadAbortException ex) {
+                    } catch (ThreadAbortException) {
 #if LOG4NET
                         f_Logger.Debug("FindThread aborted");
 #endif
diff --git a/src/Frontend-GNOME/Frontend.cs b/src/Frontend-GNOME/Frontend.cs
index 6cd2431..2a185df 100644
--- a/src/Frontend-GNOME/Frontend.cs
+++ b/src/Frontend-GNOME/Frontend.cs
@@ -26,6 +26,7 @@ using System.Linq;
 using System.Threading;
 using System.Reflection;
 using SysDiag = System.Diagnostics;
+using MonoDevelop.MacInterop;
 using Smuxi.Engine;
 using Smuxi.Common;
 
@@ -41,14 +42,10 @@ namespace Smuxi.Frontend.Gnome
         private static readonly string    _UIName = "GNOME";
         private static int                _UIThreadID;
         private static Version            _Version;
-        private static string             _VersionNumber;
         private static string             _VersionString;
         private static Version            _EngineVersion;
         private static SplashScreenWindow _SplashScreenWindow;
         private static MainWindow         _MainWindow;
-#if GTK_SHARP_2_10
-        private static StatusIconManager  _StatusIconManager;
-#endif
         private static FrontendConfig     _FrontendConfig;
         private static Session            _LocalSession;
         private static Session            _Session;
@@ -64,6 +61,9 @@ namespace Smuxi.Frontend.Gnome
         public static bool HadSession { get; private set; }
         public static bool IsGtkInitialized { get; private set; }
         public static bool InGtkApplicationRun { get; private set; }
+        public static bool IsWindows { get; private set; }
+        public static bool IsUnity { get; private set; }
+        public static bool IsMacOSX { get; private set; }
 
         public static event EventHandler  SessionPropertyChanged;
 
@@ -174,6 +174,19 @@ namespace Smuxi.Frontend.Gnome
             }
         }
 
+        static Frontend()
+        {
+            IsWindows = Environment.OSVersion.Platform == PlatformID.Win32NT;
+            IsMacOSX = Platform.OperatingSystem == "Darwin";
+            var desktop = Environment.GetEnvironmentVariable("XDG_CURRENT_DESKTOP");
+            if (!String.IsNullOrEmpty(desktop) && desktop.ToLower().Contains("unity")) {
+#if LOG4NET
+                _Logger.Debug("Frontend(): Detected Unity desktop envrionment");
+#endif
+                IsUnity = true;
+            }
+        }
+
         public static void Init(string[] args)
         {
             System.Threading.Thread.CurrentThread.Name = "Main";
@@ -183,7 +196,6 @@ namespace Smuxi.Frontend.Gnome
             AssemblyProductAttribute pr = (AssemblyProductAttribute)asm.
                 GetCustomAttributes(typeof(AssemblyProductAttribute), false)[0];
             _Version = asm_name.Version;
-            _VersionNumber = asm_name.Version.ToString();
             _VersionString = pr.Product + " - " + _UIName + " frontend " + _Version;
 
 #if LOG4NET
@@ -235,6 +247,35 @@ namespace Smuxi.Frontend.Gnome
                 _SplashScreenWindow.Destroy();
             }
 
+            if (IsMacOSX) {
+                ApplicationEvents.Quit += delegate(object sender, ApplicationQuitEventArgs e) {
+                    Quit();
+                    e.Handled = true;
+                };
+
+                ApplicationEvents.Reopen += delegate(object sender, ApplicationEventArgs e) {
+                    MainWindow.Deiconify();
+                    MainWindow.Visible = true;
+                    e.Handled = true;
+                };
+
+                ApplicationEvents.OpenUrls += delegate(object sender, ApplicationUrlEventArgs e) {
+                    e.Handled = true;
+                    if (e.Urls == null || e.Urls.Count == 0) {
+                        return;
+                    }
+                    foreach (var url in e.Urls) {
+                        try {
+                            OpenChatLink(new Uri(url));
+                        } catch (Exception ex) {
+#if LOG4NET
+                            _Logger.Error("ApplicationEvents.OpenUrls() Exception", ex);
+#endif
+                        }
+                    }
+                };
+            }
+
             InGtkApplicationRun = true;
             Gtk.Application.Run();
             InGtkApplicationRun = false;
@@ -714,10 +755,15 @@ namespace Smuxi.Frontend.Gnome
 
         public static void OpenChatLink(Uri link)
         {
+            TryOpenChatLink(link);
+        }
+
+        public static bool TryOpenChatLink(Uri link)
+        {
             Trace.Call(link);
 
             if (Session == null) {
-                return;
+                return false;
             }
 
             // supported:
@@ -781,6 +827,15 @@ namespace Smuxi.Frontend.Gnome
             }
 
             if (manager == null) {
+                // only irc may autoconnect to a server
+                switch (linkProtocol) {
+                    case "irc":
+                    case "ircs":
+                    case "smuxi":
+                        break;
+                    default:
+                        return false;
+                }
                 ServerModel server = null;
                 if (!String.IsNullOrEmpty(linkNetwork)) {
                     // try to find a server with this network name and connect to it
@@ -801,7 +856,7 @@ namespace Smuxi.Frontend.Gnome
             }
 
             if (String.IsNullOrEmpty(linkChat)) {
-                return;
+                return true;
             }
 
             // switch to existing chat
@@ -811,7 +866,7 @@ namespace Smuxi.Frontend.Gnome
                 }
                 if (String.Compare(chatView.ID, linkChat, true) == 0) {
                     MainWindow.ChatViewManager.CurrentChatView = chatView;
-                    return;
+                    return true;
                 }
             }
 
@@ -826,6 +881,81 @@ namespace Smuxi.Frontend.Gnome
                     }
                 });
             }
+            return true;
+        }
+
+        public static void OpenLink(Uri link)
+        {
+            Trace.Call(link);
+
+            if (link == null) {
+                throw new ArgumentNullException("link");
+            }
+
+            if (TryOpenChatLink(link)) {
+                return;
+            }
+
+            // hopefully MS .NET / Mono finds some way to handle the URL
+            ThreadPool.QueueUserWorkItem(delegate {
+                try {
+                    var url = link.ToString();
+                    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);
+#endif
+                }
+            });
+        }
+
+        public static void OpenFindGroupChatWindow()
+        {
+            OpenFindGroupChatWindow(null);
+        }
+
+        public static void OpenFindGroupChatWindow(string searchKey)
+        {
+            var chatView = MainWindow.ChatViewManager.CurrentChatView;
+            if (chatView == null) {
+                return;
+            }
+
+            var manager = chatView.ProtocolManager;
+            if (manager == null) {
+                return;
+            }
+
+            var dialog = new FindGroupChatDialog(
+                MainWindow, manager
+            );
+            if (!String.IsNullOrEmpty(searchKey)) {
+                dialog.NameEntry.Text = searchKey;
+                dialog.FindButton.Click();
+            }
+            var res = dialog.Run();
+            var 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(null, ex);
+                }
+            });
         }
 
 #if GTK_SHARP_2_10
@@ -918,6 +1048,7 @@ namespace Smuxi.Frontend.Gnome
             var iconPath = Path.Combine(Defines.InstallPrefix, "share");
             iconPath = Path.Combine(iconPath, "icons");
             var theme = Gtk.IconTheme.Default;
+            var settings = Gtk.Settings.Default;
             var iconInfo = theme.LookupIcon(IconName, -1, 0);
             HasSystemIconTheme = iconInfo != null &&
                                  iconInfo.Filename != null &&
@@ -927,6 +1058,44 @@ namespace Smuxi.Frontend.Gnome
                                 HasSystemIconTheme ? "system" : "built-in");
 #endif
 
+            var unityWithLightIcons = false;
+            if (Frontend.IsUnity) {
+                var sysGtkTheme = settings.ThemeName ?? String.Empty;
+                var sysIconTheme = GetGtkIconThemeName() ?? String.Empty;
+#if LOG4NET
+                _Logger.DebugFormat("InitGtk(): Detected GTK+ theme: {0} " +
+                                    "icon theme: {1}", sysGtkTheme,
+                                    sysIconTheme);
+#endif
+                if (sysGtkTheme.StartsWith("Ambiance") &&
+                    sysIconTheme != "ubuntu-mono-dark") {
+#if LOG4NET
+                    _Logger.Debug("InitGtk(): Detected Ambiance theme with "+
+                                  "light icons");
+#endif
+                    unityWithLightIcons = true;
+                }
+            }
+            var appIconDir = Path.Combine(appDir, "icons");
+            if (Directory.Exists(appIconDir) &&
+                (Frontend.IsMacOSX ||
+                 Frontend.IsWindows ||
+                 unityWithLightIcons)) {
+                var iconTheme = "Faenza-Smuxi";
+#if LOG4NET
+                _Logger.InfoFormat("InitGtk(): Setting icon theme to: {0}",
+                                    iconTheme);
+#endif
+                settings.SetStringProperty(
+                    "gtk-icon-theme-name", iconTheme, Assembly.GetExecutingAssembly().FullName
+                );
+#if LOG4NET
+                _Logger.InfoFormat("InitGtk(): Prepending {0} to icon search path",
+                                    appIconDir);
+#endif
+                theme.PrependSearchPath(appIconDir);
+            }
+
             if (HasSystemIconTheme) {
                 Gtk.Window.DefaultIconName = "smuxi-frontend-gnome";
             } else {
@@ -1000,6 +1169,26 @@ namespace Smuxi.Frontend.Gnome
             }
         }
 
+        static string GetGtkIconThemeName()
+        {
+            // HACK: Gtk.IconTheme is not exposing gtk-icon-theme-name
+            var method = typeof(Gtk.Settings).GetMethod(
+                "GetProperty",
+                BindingFlags.Instance | BindingFlags.NonPublic
+            );
+            if (method == null) {
+#if LOG4NET
+                _Logger.Warn("GetGtkIconThemeName(): method is null!");
+#endif
+                return String.Empty;
+            }
+            var value = (string)(GLib.Value) method.Invoke(
+                Gtk.Settings.Default,
+                new object[] {"gtk-icon-theme-name"}
+            );
+            return value;
+        }
+
         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 2101f74..ecd32d2 100644
--- a/src/Frontend-GNOME/GnomeUI.cs
+++ b/src/Frontend-GNOME/GnomeUI.cs
@@ -80,11 +80,13 @@ namespace Smuxi.Frontend.Gnome
                 return;
             }
             
+#if LOG4NET && MSG_DEBUG
             DateTime start, stop;
             start = DateTime.UtcNow;
+#endif
             chatView.AddMessage(msg);
-            stop = DateTime.UtcNow;
 #if LOG4NET && MSG_DEBUG
+            stop = DateTime.UtcNow;
             _Logger.Debug(
                 String.Format(
                     "_AddMessageToChat(): chatView.AddMessage() took: {0:0.00} ms",
diff --git a/src/Frontend-GNOME/IndicateManager.cs b/src/Frontend-GNOME/IndicateManager.cs
index 18c016d..6f89b0c 100644
--- a/src/Frontend-GNOME/IndicateManager.cs
+++ b/src/Frontend-GNOME/IndicateManager.cs
@@ -18,13 +18,17 @@
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 
-#if INDICATE_SHARP
+#if INDICATE_SHARP || MESSAGING_MENU_SHARP
 using System;
 using System.IO;
 using System.Text.RegularExpressions;
 using System.Collections.Generic;
 using System.Runtime.InteropServices;
+#if INDICATE_SHARP
 using Indicate;
+#elif MESSAGING_MENU_SHARP
+using MessagingMenu;
+#endif
 #if IPC_DBUS
     #if DBUS_SHARP
 using DBus;
@@ -44,13 +48,18 @@ namespace Smuxi.Frontend.Gnome
         private static readonly log4net.ILog Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
 #endif
         const string BusName = "com.canonical.indicator.session";
-        private static DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0);
         private static string PersonChatIconBase64 { get; set; }
         private static string GroupChatIconBase64  { get; set; }
+#if INDICATE_SHARP
         Server Server { get; set; }
+        Dictionary<ChatView, Indicator> Indicators { get; set; }
+#elif MESSAGING_MENU_SHARP
+        private static DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0);
+        App App { get; set; }
+        Dictionary<ChatView, string> Sources { get; set; }
+#endif
         MainWindow MainWindow { get; set; }
         ChatViewManager ChatViewManager { get; set; }
-        Dictionary<ChatView, Indicator> Indicators { get; set; }
         Dictionary<ChatView, MessageTextViewMessageHighlightedEventHandler> HighlightEventHandlers { get; set; }
         bool IsInitialized { get; set; }
         bool IsEnabled { get; set; }
@@ -80,7 +89,11 @@ namespace Smuxi.Frontend.Gnome
 
             MainWindow = mainWindow;
             ChatViewManager = chatViewManager;
+#if INDICATE_SHARP
             Indicators = new Dictionary<ChatView, Indicator>();
+#elif MESSAGING_MENU_SHARP
+            Sources = new Dictionary<ChatView, string>();
+#endif
             HighlightEventHandlers = new Dictionary
                 <ChatView,
                  MessageTextViewMessageHighlightedEventHandler>();
@@ -104,8 +117,12 @@ namespace Smuxi.Frontend.Gnome
             ChatViewManager.ChatAdded   -= OnChatViewManagerChatAdded;
             ChatViewManager.ChatRemoved -= OnChatViewManagerChatRemoved;
 
+#if INDICATE_SHARP
             Server.Hide();
-            Server.Dispose();
+#elif MESSAGING_MENU_SHARP
+            App.Unregister();
+            App.Dispose();
+#endif
         }
 
         public void ApplyConfig(UserConfig userConfig)
@@ -145,7 +162,11 @@ namespace Smuxi.Frontend.Gnome
                 path = Path.Combine(path, "smuxi-frontend-gnome");
                 File.WriteAllText(path, DesktopFile + "\n");
 
+#if INDICATE_SHARP
                 Server.Show();
+#elif MESSAGING_MENU_SHARP
+                App.Register();
+#endif
                 IsEnabled = true;
             } else {
                 // non-persistent in menu using the blacklist as per
@@ -153,70 +174,13 @@ namespace Smuxi.Frontend.Gnome
                 // https://wiki.ubuntu.com/MessagingMenu/#Registration
                 File.WriteAllText(blacklistPath, DesktopFile + "\n");
 
+#if INDICATE_SHARP
                 Server.Hide();
-                IsEnabled = false;
-            }
-        }
-
-        void Init()
-        {
-            Trace.Call();
-
-#if IPC_DBUS
-            if (!Bus.Session.NameHasOwner(BusName)) {
-    #if LOG4NET
-                Logger.Info("Init(): no DBus provider for messaging menu found, " +
-                            "disabling...");
-    #endif
-                return;
-            }
+#elif MESSAGING_MENU_SHARP
+                App.Unregister();
 #endif
-
-            Server = Server.RefDefault();
-            if (Server == null) {
-                // just in case
-                return;
-            }
-            // all checks return false for some reason
-            /*
-            if (!Server.CheckInterest(Interests.ServerDisplay)) {
-#if LOG4NET
-                Logger.Info("Init() the indicate server is not interested in " +
-                            "us, thus no messaging menu :/");
-#endif
-                return;
-            }
-            */
-
-            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);
-            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;
+                IsEnabled = false;
             }
-
-            Server.SetType("message.im");
-            Server.DesktopFile(DesktopFile);
-            Server.ServerDisplay += OnServerServerDisplay;
-
-            MainWindow.FocusInEvent += OnMainWindowFocusInEvent;
-            MainWindow.Notebook.SwitchPage += OnMainWindowNotebookSwitchPage;
-
-            ChatViewManager.ChatAdded   += OnChatViewManagerChatAdded;
-            ChatViewManager.ChatRemoved += OnChatViewManagerChatRemoved;
-
-            IsInitialized = true;
         }
 
         void OnMainWindowFocusInEvent(object sender, Gtk.FocusInEventArgs e)
@@ -229,7 +193,11 @@ namespace Smuxi.Frontend.Gnome
             if (currentChatView == null) {
                 return;
             }
+#if INDICATE_SHARP
             DisposeIndicator(currentChatView);
+#elif MESSAGING_MENU_SHARP
+            DisposeSource(currentChatView);
+#endif
         }
 
         void OnMainWindowNotebookSwitchPage(object sender, Gtk.SwitchPageArgs e)
@@ -242,14 +210,11 @@ namespace Smuxi.Frontend.Gnome
             if (currentChatView == null) {
                 return;
             }
+#if INDICATE_SHARP
             DisposeIndicator(currentChatView);
-        }
-
-        void OnServerServerDisplay(object sender, ServerDisplayArgs e)
-        {
-            Trace.Call(sender, e);
-
-            MainWindow.PresentWithTime(e.Timestamp);
+#elif MESSAGING_MENU_SHARP
+            DisposeSource(currentChatView);
+#endif
         }
 
         void OnChatViewManagerChatAdded(object sender, ChatViewManagerChatAddedEventArgs e)
@@ -282,7 +247,11 @@ namespace Smuxi.Frontend.Gnome
             HighlightEventHandlers.Remove(e.ChatView);
 
             // close possibly active indicator
+#if INDICATE_SHARP
             DisposeIndicator(e.ChatView);
+#elif MESSAGING_MENU_SHARP
+            DisposeSource(e.ChatView);
+#endif
         }
 
         void OnChatViewMessageHighlighted(object sender,
@@ -295,16 +264,87 @@ namespace Smuxi.Frontend.Gnome
                 return;
             }
 
+#if INDICATE_SHARP
+            ShowIndicator(chatView, e.Message);
+#elif MESSAGING_MENU_SHARP
+            ShowSource(chatView, e.Message);
+#endif
+        }
+
+#if INDICATE_SHARP
+        void Init()
+        {
+            Trace.Call();
+
+#if IPC_DBUS
+            if (!Bus.Session.NameHasOwner(BusName)) {
+    #if LOG4NET
+                Logger.Info("Init(): no DBus provider for messaging menu found, " +
+                            "disabling...");
+    #endif
+                return;
+            }
+#endif
+
+            Server = Server.RefDefault();
+            if (Server == null) {
+                // just in case
+                return;
+            }
+            // all checks return false for some reason
+            /*
+            if (!Server.CheckInterest(Interests.ServerDisplay)) {
+#if LOG4NET
+                Logger.Info("Init() the indicate server is not interested in " +
+                            "us, thus no messaging menu :/");
+#endif
+                return;
+            }
+            */
+
+            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);
+            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);
+            Server.ServerDisplay += OnServerServerDisplay;
+
+            MainWindow.FocusInEvent += OnMainWindowFocusInEvent;
+            MainWindow.Notebook.SwitchPage += OnMainWindowNotebookSwitchPage;
+
+            ChatViewManager.ChatAdded   += OnChatViewManagerChatAdded;
+            ChatViewManager.ChatRemoved += OnChatViewManagerChatRemoved;
+
+            IsInitialized = true;
+        }
+
+        void ShowIndicator(ChatView chatView, MessageModel msg)
+        {
             Indicator indicator;
             if (Indicators.TryGetValue(chatView, out indicator)) {
                 // update time of existing indicator
                 indicator.SetProperty(
                     "time",
-                    e.Message.TimeStamp.ToLocalTime().ToString("s")
+                    msg.TimeStamp.ToLocalTime().ToString("s")
                 );
                 return;
             }
-            
+
             indicator = new Indicator();
             indicator.SetProperty("subtype", "im");
             if (chatView is PersonChatView) {
@@ -313,7 +353,7 @@ namespace Smuxi.Frontend.Gnome
             }
             if (chatView is GroupChatView) {
                 indicator.SetProperty("icon", GroupChatIconBase64);
-                var nick = GetNick(e.Message);
+                var nick = GetNick(msg);
                 if (nick == null) {
                     indicator.SetProperty("sender", chatView.Name);
                 } else {
@@ -327,7 +367,7 @@ namespace Smuxi.Frontend.Gnome
             }
             indicator.SetProperty(
                 "time",
-                e.Message.TimeStamp.ToLocalTime().ToString("s")
+                msg.TimeStamp.ToLocalTime().ToString("s")
             );
             indicator.SetPropertyBool("draw-attention", true);
             indicator.UserDisplay += delegate {
@@ -377,6 +417,134 @@ namespace Smuxi.Frontend.Gnome
             }
         }
 
+        void OnServerServerDisplay(object sender, ServerDisplayArgs e)
+        {
+            Trace.Call(sender, e);
+
+            MainWindow.PresentWithTime(e.Timestamp);
+        }
+
+#elif MESSAGING_MENU_SHARP
+        void Init()
+        {
+            Trace.Call();
+
+#if IPC_DBUS
+            if (!Bus.Session.NameHasOwner(BusName)) {
+    #if LOG4NET
+                Logger.Info("Init(): no DBus provider for messaging menu found, " +
+                            "disabling...");
+    #endif
+                return;
+            }
+#endif
+
+            App = new App("smuxi-frontend-gnome.desktop");
+            App.ActivateSource += OnAppActivateSource;
+
+            MainWindow.FocusInEvent += OnMainWindowFocusInEvent;
+            MainWindow.Notebook.SwitchPage += OnMainWindowNotebookSwitchPage;
+
+            ChatViewManager.ChatAdded   += OnChatViewManagerChatAdded;
+            ChatViewManager.ChatRemoved += OnChatViewManagerChatRemoved;
+
+            IsInitialized = true;
+        }
+
+        void ShowSource(ChatView chatView, MessageModel msg)
+        {
+            Trace.Call(chatView, msg);
+
+            string sourceId;
+            var time = (Int64) ((msg.TimeStamp - UnixEpoch).TotalMilliseconds * 1000L);
+            if (Sources.TryGetValue(chatView, out sourceId)) {
+                // update time of existing source
+                App.SetSourceTime(sourceId, time);
+                return;
+            }
+
+            // TODO: TEST ME!
+            sourceId = chatView.ID;
+            string iconName = null;
+            string label = null;
+            if (chatView is PersonChatView) {
+                iconName = "smuxi-person-chat";
+                label = chatView.Name;
+            } else if (chatView is GroupChatView) {
+                iconName = "smuxi-group-chat";
+                var nick = GetNick(msg);
+                if (nick == null) {
+                    label = chatView.Name;
+                } else {
+                    label = String.Format("{0} ({1})", chatView.Name, nick);
+                }
+            }
+
+            var theme = Gtk.IconTheme.Default;
+            GLib.Icon icon = null;
+            if (Frontend.HasSystemIconTheme &&
+                iconName != null && theme.HasIcon(iconName)) {
+                icon = new GLib.ThemedIcon(iconName);
+            } else if (iconName != null && theme.HasIcon(iconName)) {
+                // icon wasn't in the system icon theme
+                var iconInfo = theme.LookupIcon(iconName, 256, Gtk.IconLookupFlags.UseBuiltin);
+                if (!String.IsNullOrEmpty(iconInfo.Filename) &&
+                    File.Exists(iconInfo.Filename)) {
+                    icon = new GLib.FileIcon(
+                        GLib.FileFactory.NewForPath(iconInfo.Filename)
+                    );
+                }
+            }
+            App.AppendSource(sourceId, icon, label);
+            App.SetSourceTime(sourceId, time);
+            App.DrawAttention(sourceId);
+            Sources.Add(chatView, sourceId);
+        }
+
+        void DisposeSource(ChatView chatView)
+        {
+            Trace.Call(chatView);
+
+            try {
+                string sourceId;
+                if (!Sources.TryGetValue(chatView, out sourceId)) {
+                    return;
+                }
+
+                App.RemoveSource(sourceId);
+            } finally {
+                Sources.Remove(chatView);
+            }
+        }
+
+        void OnAppActivateSource(object sender, ActivateSourceArgs e)
+        {
+            Trace.Call(sender, e);
+
+            try {
+                MainWindow.PresentWithServerTime();
+
+                ChatView chatView = null;
+                foreach (var kvp in Sources) {
+                    if (kvp.Value != e.SourceId) {
+                        continue;
+                    }
+                    chatView = kvp.Key;
+                }
+                if (chatView == null) {
+                    return;
+                }
+
+                MainWindow.Notebook.CurrentChatView = chatView;
+                DisposeSource(chatView);
+            } catch (Exception ex) {
+#if LOG4NET
+                Logger.Error("OnAppActivateSource(): Exception", ex);
+#endif
+            }
+        }
+#endif
+
         string GetNick(MessageModel msg)
         {
             // HACK: try to obtain the nickname from the message
diff --git a/src/Frontend-GNOME/MainWindow.cs b/src/Frontend-GNOME/MainWindow.cs
index 8ba1bcc..376e1a3 100644
--- a/src/Frontend-GNOME/MainWindow.cs
+++ b/src/Frontend-GNOME/MainWindow.cs
@@ -37,90 +37,67 @@ namespace Smuxi.Frontend.Gnome
 #if LOG4NET
         private static readonly log4net.ILog f_Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
 #endif
-        private Gtk.Statusbar    _NetworkStatusbar;
-        private Gtk.Statusbar    _Statusbar;
-        private Gtk.ProgressBar  _ProgressBar;
-        private Entry            _Entry;
-        private Notebook         _Notebook;
-        private bool             _CaretMode;
-        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;
+        private bool             _IsFullscreen;
+
+        Gtk.Statusbar NetworkStatusbar { get; set; }
+        Gtk.Statusbar Statusbar { get; set; }
+        public Gtk.ProgressBar ProgressBar { get; private set; }
+        Gtk.HBox StatusHBox { get; set; }
+        public MenuWidget MenuWidget { get; private set; }
+
+        public IFrontendUI UI { get; private set; }
+        public Entry Entry { get; private set; }
+        public Notebook Notebook { get; private set; }
+        public ChatViewManager ChatViewManager { get; private set; }
+        public EngineManager EngineManager { get; private set; }
 #if GTK_SHARP_2_10
-        private StatusIconManager _StatusIconManager;
+        StatusIconManager StatusIconManager { get; set; }
 #endif
-#if INDICATE_SHARP
-        private IndicateManager  _IndicateManager;
+#if INDICATE_SHARP || MESSAGING_MENU_SHARP
+        IndicateManager IndicateManager { get; set; }
 #endif
 #if NOTIFY_SHARP
-        private NotifyManager    _NotifyManager;
+        NotifyManager NotifyManager { get; set; }
 #endif
 #if IPC_DBUS
-        private NetworkManager   _NetworkManager;
+        NetworkManager NetworkManager { get; set; }
 #endif
-        private bool             _IsMinimized;
-        private bool             _IsMaximized;
-        private bool             _IsFullscreen;
-
-        public Gtk.MenuBar MenuBar { get; private set; }
-        Gtk.HBox MenuHBox { get; set; }
-        Gtk.HBox StatusHBox { get; set; }
-        JoinWidget JoinWidget { get; set; }
-        Gtk.CheckMenuItem ShowQuickJoinMenuItem { get; set; }
-        Gtk.CheckMenuItem ShowMenuBarMenuItem  { get; set; }
-        Gtk.CheckMenuItem ShowStatusBarMenuItem  { get; set; }
 
-        public bool ShowMenuBar {
-            get {
-                return MenuBar.Visible;
-            }
-            set {
-                ShowMenuBarMenuItem.Active = value;
-            }
-        }
+        public NotificationAreaIconMode NotificationAreaIconMode { get; set; }
+        public bool IsMinimized { get; private set; }
+        public bool IsMaximized { get; private set; }
 
         public bool CaretMode {
             get {
-                return _CaretMode;
+                return MenuWidget.CaretMode;
             }
         }
-        
-        public Notebook Notebook {
+
+        public bool ShowMenuBar {
             get {
-                return _Notebook;
+                return MenuWidget.MenuBar.Visible;
             }
-        }
-        
-        public IFrontendUI UI {
-            get {
-                return _UI;
+            set {
+                MenuWidget.ShowMenubarAction.Active = value;
             }
         }
-        
-        public EngineManager EngineManager {
+
+        public bool ShowStatusbar {
             get {
-                return _EngineManager;
+                return StatusHBox.Visible;
             }
-        }
-        
-        public ChatViewManager ChatViewManager {
-            get {
-                return _ChatViewManager;
+            set {
+                StatusHBox.Visible = value;
             }
         }
-        
+
         public string NetworkStatus {
             set {
                 if (value == null) {
                     value = String.Empty;
                 }
-                _NetworkStatusbar.Pop(0);
-                _NetworkStatusbar.Push(0, value);
+                NetworkStatusbar.Pop(0);
+                NetworkStatusbar.Push(0, value);
             }
         } 
 
@@ -129,32 +106,8 @@ namespace Smuxi.Frontend.Gnome
                 if (value == null) {
                     value = String.Empty;
                 }
-                _Statusbar.Pop(0);
-                _Statusbar.Push(0, value);
-            }
-        }
-
-        public Gtk.ProgressBar ProgressBar {
-            get {
-                return _ProgressBar;
-            }
-        }
-        
-        public Entry Entry {
-            get {
-                return _Entry;
-            }
-        }
-        
-        public bool IsMaximized {
-            get {
-                return _IsMaximized;
-            }
-        }
-        
-        public bool IsMinimized {
-            get {
-                return _IsMinimized;
+                Statusbar.Pop(0);
+                Statusbar.Push(0, value);
             }
         }
 
@@ -172,15 +125,6 @@ namespace Smuxi.Frontend.Gnome
             }
         }
 
-        public NotificationAreaIconMode NotificationAreaIconMode {
-            get {
-                return _NotificationAreaIconMode;
-            }
-            set {
-                _NotificationAreaIconMode = value;
-            }
-        }
-
         public EventHandler Minimized;
         public EventHandler Unminimized;
 
@@ -238,351 +182,106 @@ namespace Smuxi.Frontend.Gnome
             FocusOutEvent += OnFocusOutEvent;
             WindowStateEvent += OnWindowStateEvent;
 
-            Gtk.AccelGroup agrp = new Gtk.AccelGroup();
-            Gtk.AccelKey   akey;
-            AddAccelGroup(agrp);
-            
-            // Menu
-            MenuBar = new Gtk.MenuBar();
-            Gtk.Menu menu;
-            Gtk.MenuItem item;
-            Gtk.ImageMenuItem image_item;
-            
-            // Menu - File
-            menu = new Gtk.Menu();
-            item = new Gtk.MenuItem(_("_File"));
-            item.Submenu = menu;
-            MenuBar.Append(item);
-
-            item = new Gtk.ImageMenuItem(Gtk.Stock.Preferences, agrp);
-            item.Activated += new EventHandler(_OnPreferencesButtonClicked);
-            item.AccelCanActivate += AccelCanActivateSensitive;
-            menu.Append(item);
-            
-            menu.Append(new Gtk.SeparatorMenuItem());
-            
-            item = new Gtk.ImageMenuItem(Gtk.Stock.Quit, agrp);
-            item.Activated += new EventHandler(_OnQuitButtonClicked);
-            item.AccelCanActivate += AccelCanActivateSensitive;
-            menu.Append(item);
-            
-            // Menu - Server
-            menu = new Gtk.Menu();
-            item = new Gtk.MenuItem(_("_Server"));
-            item.Submenu = menu;
-            MenuBar.Append(item);
-            
-            image_item = new Gtk.ImageMenuItem(_("_Quick Connect"));
-            image_item.Image = new Gtk.Image(Gtk.Stock.Connect, Gtk.IconSize.Menu);
-            image_item.Activated += OnServerQuickConnectButtonClicked;
-            menu.Append(image_item);
-            
-            menu.Append(new Gtk.SeparatorMenuItem());
-                    
-            image_item = new Gtk.ImageMenuItem(Gtk.Stock.Add, agrp);
-            image_item.Activated += OnServerAddButtonClicked;
-            menu.Append(image_item);
-            
-            image_item = new Gtk.ImageMenuItem(_("_Manage"));
-            image_item.Image = new Gtk.Image(Gtk.Stock.Edit, Gtk.IconSize.Menu);
-            image_item.Activated += OnServerManageServersButtonClicked;
-            menu.Append(image_item);
-            
-            // Menu - Chat
-            menu = new Gtk.Menu();
-            item = new Gtk.MenuItem(_("_Chat"));
-            item.Submenu = menu;
-            MenuBar.Append(item);
-            
-            _OpenChatMenuItem = new Gtk.ImageMenuItem(_("Open / Join Chat"));
-            _OpenChatMenuItem.Image = new Gtk.Image(Gtk.Stock.Open, Gtk.IconSize.Menu);
-            _OpenChatMenuItem.Activated += OnOpenChatMenuItemActivated;
-            akey = new Gtk.AccelKey();
-            akey.AccelFlags = Gtk.AccelFlags.Visible;
-            akey.AccelMods = Gdk.ModifierType.ControlMask;
-            akey.Key = Gdk.Key.L;
-            _OpenChatMenuItem.AddAccelerator("activate", agrp, akey);
-            _OpenChatMenuItem.AccelCanActivate += AccelCanActivateSensitive;
-            menu.Append(_OpenChatMenuItem);
-                    
-            _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);
-            image_item.Activated += OnChatClearAllActivityButtonClicked;
-            menu.Append(image_item);
-            
-            menu.Append(new Gtk.SeparatorMenuItem());
-                    
-            image_item = new Gtk.ImageMenuItem(_("_Next Chat"));
-            image_item.Image = new Gtk.Image(Gtk.Stock.GoForward, Gtk.IconSize.Menu);
-            image_item.Activated += OnNextChatMenuItemActivated;
-            akey = new Gtk.AccelKey();
-            akey.AccelFlags = Gtk.AccelFlags.Visible;
-            akey.AccelMods = Gdk.ModifierType.ControlMask;
-            akey.Key = Gdk.Key.Page_Down;
-            image_item.AddAccelerator("activate", agrp, akey);
-            image_item.AccelCanActivate += AccelCanActivateSensitive;
-            menu.Append(image_item);
-            
-            image_item = new Gtk.ImageMenuItem(_("_Previous Chat"));
-            image_item.Image = new Gtk.Image(Gtk.Stock.GoBack, Gtk.IconSize.Menu);
-            image_item.Activated += OnPreviousChatMenuItemActivated;
-            akey = new Gtk.AccelKey();
-            akey.AccelFlags = Gtk.AccelFlags.Visible;
-            akey.AccelMods = Gdk.ModifierType.ControlMask;
-            akey.Key = Gdk.Key.Page_Up;
-            image_item.AddAccelerator("activate", agrp, akey);
-            image_item.AccelCanActivate += AccelCanActivateSensitive;
-            menu.Append(image_item);
-            
-            menu.Append(new Gtk.SeparatorMenuItem());
-                    
-            /*
-            // TODO: make a radio item for each chat hotkey
-            Gtk.RadioMenuItem radio_item;
-            radio_item = new Gtk.RadioMenuItem();
-            radio_item = new Gtk.RadioMenuItem(radio_item);
-            radio_item = new Gtk.RadioMenuItem(radio_item);
-                    
-            menu.Append(new Gtk.SeparatorMenuItem());
-            */
-            
-            /*
-            image_item = new Gtk.ImageMenuItem(Gtk.Stock.Find, agrp);
-            image_item.Activated += OnFindChatMenuItemActivated;
-            menu.Append(image_item);
-            
-            item = new Gtk.MenuItem(_("Find _Next"));
-            item.Activated += OnFindNextChatMenuItemActivated;
-            akey = new Gtk.AccelKey();
-            akey.AccelFlags = Gtk.AccelFlags.Visible;
-            akey.AccelMods = Gdk.ModifierType.ControlMask;
-            akey.Key = Gdk.Key.G;
-            item.AddAccelerator("activate", agrp, akey);
-            menu.Append(item);
-            
-            item = new Gtk.MenuItem(_("Find _Previous"));
-            item.Activated += OnFindPreviousChatMenuItemActivated;
-            akey = new Gtk.AccelKey();
-            akey.AccelFlags = Gtk.AccelFlags.Visible;
-            akey.AccelMods = Gdk.ModifierType.ControlMask | Gdk.ModifierType.ShiftMask;
-            akey.Key = Gdk.Key.G;
-            item.AddAccelerator("activate", agrp, akey);
-            menu.Append(item);
-            */
-
-            // ROFL: the empty code statement below is needed to keep stupid
-            // gettext away from using all the commented code from above as
-            // translator comment
-            ;
-            _OpenLogChatMenuItem = new Gtk.ImageMenuItem(_("Open Log"));
-            _OpenLogChatMenuItem.Image = new Gtk.Image(Gtk.Stock.Open,
-                                                       Gtk.IconSize.Menu);
-            _OpenLogChatMenuItem.Activated += OnOpenLogChatMenuItemActivated;
-            _OpenLogChatMenuItem.Sensitive = false;
-            _OpenLogChatMenuItem.NoShowAll = true;
-            menu.Append(_OpenLogChatMenuItem);
-
-            _CloseChatMenuItem = new Gtk.ImageMenuItem(Gtk.Stock.Close, agrp);
-            _CloseChatMenuItem.Activated += OnCloseChatMenuItemActivated;
-            _CloseChatMenuItem.AccelCanActivate += AccelCanActivateSensitive;
-            menu.Append(_CloseChatMenuItem);
-
-            // Menu - Engine
-            menu = new Gtk.Menu();
-            item = new Gtk.MenuItem(_("_Engine"));
-            item.Submenu = menu;
-            MenuBar.Append(item);
-
-            item = new Gtk.MenuItem(_("_Use Local Engine"));
-            item.Activated += new EventHandler(_OnUseLocalEngineButtonClicked);
-            menu.Append(item);
-            
-            menu.Append(new Gtk.SeparatorMenuItem());
-                    
-            image_item = new Gtk.ImageMenuItem(_("_Add Remote Engine"));
-            image_item.Image = new Gtk.Image(Gtk.Stock.Add, Gtk.IconSize.Menu);
-            image_item.Activated += new EventHandler(_OnAddRemoteEngineButtonClicked);
-            menu.Append(image_item);
-            
-            image_item = new Gtk.ImageMenuItem(_("_Switch Remote Engine"));
-            image_item.Image = new Gtk.Image(Gtk.Stock.Refresh, Gtk.IconSize.Menu);
-            image_item.Activated += new EventHandler(_OnSwitchRemoteEngineButtonClicked);
-            menu.Append(image_item);
-            
-            // Menu - View
-            menu = new Gtk.Menu();
-            item = new Gtk.MenuItem(_("_View"));
-            item.Submenu = menu;
-            MenuBar.Append(item);
-            
-            item = new Gtk.CheckMenuItem(_("_Caret Mode"));
-            item.Activated += new EventHandler(_OnCaretModeButtonClicked);
-            akey = new Gtk.AccelKey();
-            akey.AccelFlags = Gtk.AccelFlags.Visible;
-            akey.Key = Gdk.Key.F7;
-            item.AddAccelerator("activate", agrp, akey);
-            item.AccelCanActivate += AccelCanActivateSensitive;
-            menu.Append(item);
-            
-            item = new Gtk.CheckMenuItem(_("_Browse Mode"));
-            item.Activated += delegate {
-                try {
-                    _Notebook.IsBrowseModeEnabled = !_Notebook.IsBrowseModeEnabled;
-                } catch (Exception ex) {
-                    Frontend.ShowException(this, ex);
-                }
-            };
-            akey = new Gtk.AccelKey();
-            akey.AccelFlags = Gtk.AccelFlags.Visible;
-            akey.Key = Gdk.Key.F8;
-            item.AddAccelerator("activate", agrp, akey);
-            item.AccelCanActivate += AccelCanActivateSensitive;
-            menu.Append(item);
-
-            ShowMenuBarMenuItem = new Gtk.CheckMenuItem(_("Show _Menubar"));
-            ShowMenuBarMenuItem.Active = (bool) Frontend.FrontendConfig["ShowMenuBar"];
-            ShowMenuBarMenuItem.Activated += OnShowMenuBarMenuItemActivated;
-            menu.Append(ShowMenuBarMenuItem);
-
-            ShowStatusBarMenuItem = new Gtk.CheckMenuItem(_("Show _Status Bar"));
-            ShowStatusBarMenuItem.Active = (bool) Frontend.FrontendConfig["ShowStatusBar"];
-            ShowStatusBarMenuItem.Activated += OnShowStatusBarMenuItemActivated;
-            menu.Append(ShowStatusBarMenuItem);
-
-            JoinWidget = new JoinWidget();
-            JoinWidget.NoShowAll = true;
-            JoinWidget.Visible = (bool) Frontend.FrontendConfig["ShowQuickJoin"];
-            JoinWidget.Activated += OnJoinWidgetActivated;
-
-            ShowQuickJoinMenuItem = new Gtk.CheckMenuItem(_("Show _Quick Join"));
-            ShowQuickJoinMenuItem.Active = JoinWidget.Visible;
-            ShowQuickJoinMenuItem.Activated += OnShowQuickJoinMenuItemActivated;
-            menu.Append(ShowQuickJoinMenuItem);
-
-            item = new Gtk.ImageMenuItem(Gtk.Stock.Fullscreen, agrp);
-            item.Activated += delegate {
-                try {
-                    IsFullscreen = !IsFullscreen;
-                } catch (Exception ex) {
-                    Frontend.ShowException(this, ex);
-                }
-            };
-            akey = new Gtk.AccelKey();
-            akey.AccelFlags = Gtk.AccelFlags.Visible;
-            akey.Key = Gdk.Key.F11;
-            item.AddAccelerator("activate", agrp, akey);
-            item.AccelCanActivate += AccelCanActivateSensitive;
-            menu.Append(item);
-
-            // Menu - Help
-            menu = new Gtk.Menu();
-            item = new Gtk.MenuItem(_("_Help"));
-            item.Submenu = menu;
-            MenuBar.Append(item);
-            
-            image_item = new Gtk.ImageMenuItem(Gtk.Stock.About, agrp);
-            image_item.Activated += new EventHandler(_OnAboutButtonClicked);
-            menu.Append(image_item);
-
-            MenuBar.ShowAll();
-            MenuBar.NoShowAll = true;
-            MenuBar.Visible = ShowMenuBarMenuItem.Active;
-
             // TODO: network treeview
-            _Notebook = new Notebook();
-            _Notebook.SwitchPage += OnNotebookSwitchPage;
-            _Notebook.FocusInEvent += OnNotebookFocusInEvent;
+            Notebook = new Notebook();
+            Notebook.SwitchPage += OnNotebookSwitchPage;
+            Notebook.FocusInEvent += OnNotebookFocusInEvent;
 
-            _ChatViewManager = new ChatViewManager(_Notebook, null);
+            ChatViewManager = new ChatViewManager(Notebook, null);
             Assembly asm = Assembly.GetExecutingAssembly();
-            _ChatViewManager.Load(asm);
-            _ChatViewManager.LoadAll(System.IO.Path.GetDirectoryName(asm.Location),
+            ChatViewManager.Load(asm);
+            ChatViewManager.LoadAll(System.IO.Path.GetDirectoryName(asm.Location),
                                      "smuxi-frontend-gnome-*.dll");
-            _ChatViewManager.ChatAdded += OnChatViewManagerChatAdded;
-            _ChatViewManager.ChatSynced += OnChatViewManagerChatSynced;
-            _ChatViewManager.ChatRemoved += OnChatViewManagerChatRemoved;
+            ChatViewManager.ChatAdded += OnChatViewManagerChatAdded;
+            ChatViewManager.ChatSynced += OnChatViewManagerChatSynced;
+            ChatViewManager.ChatRemoved += OnChatViewManagerChatRemoved;
             
 #if GTK_SHARP_2_10
-            _StatusIconManager = new StatusIconManager(this, _ChatViewManager);
+            StatusIconManager = new StatusIconManager(this, ChatViewManager);
 #endif
-#if INDICATE_SHARP
-            _IndicateManager = new IndicateManager(this, _ChatViewManager);
+#if INDICATE_SHARP || MESSAGING_MENU_SHARP
+            IndicateManager = new IndicateManager(this, ChatViewManager);
 #endif
 #if NOTIFY_SHARP
-            _NotifyManager = new NotifyManager(this, _ChatViewManager);
+            NotifyManager = new NotifyManager(this, ChatViewManager);
 #endif
 #if IPC_DBUS
-            _NetworkManager = new NetworkManager(_ChatViewManager);
+            NetworkManager = new NetworkManager(ChatViewManager);
 #endif
 
-            _UI = new GnomeUI(_ChatViewManager);
+            UI = new GnomeUI(ChatViewManager);
             
             // HACK: Frontend.FrontendConfig out of scope
-            _EngineManager = new EngineManager(Frontend.FrontendConfig, _UI);
+            EngineManager = new EngineManager(Frontend.FrontendConfig, UI);
 
-            _Entry = new Entry(_ChatViewManager);
+            Entry = new Entry(ChatViewManager);
             var entryScrolledWindow = new Gtk.ScrolledWindow();
             entryScrolledWindow.ShadowType = Gtk.ShadowType.EtchedIn;
             entryScrolledWindow.HscrollbarPolicy = Gtk.PolicyType.Never;
             entryScrolledWindow.SizeRequested += delegate(object o, Gtk.SizeRequestedArgs args) {
                 // predict and set useful heigth
-                var layout = _Entry.CreatePangoLayout("Qp");
                 int lineWidth, lineHeigth;
-                layout.GetPixelSize(out lineHeigth, out lineHeigth);
-                var text = Entry.Text;
-                var newLines = text.Count(f => f == '\n');
-                // cap to 1-3 lines
-                if (text.Length > 0) {
+                using (var layout = Entry.CreatePangoLayout("Qp")) {
+                    layout.GetPixelSize(out lineHeigth, out lineHeigth);
+                }
+                var it = Entry.Buffer.StartIter;
+                int newLines = 1;
+                // move to end of next visual line
+                while (Entry.ForwardDisplayLineEnd(ref it)) {
                     newLines++;
-                    newLines = Math.Max(newLines, 1);
-                    newLines = Math.Min(newLines, 3);
-                } else {
-                    newLines = 1;
+                    // calling ForwardDisplayLineEnd repeatedly stays on the same position
+                    // therefor we move one cursor position further
+                    it.ForwardCursorPosition();
                 }
+                newLines = Math.Min(newLines, 3);
                 // use text heigth + a bit extra
                 var bestSize = new Gtk.Requisition() {
                     Height = (lineHeigth * newLines) + 5
                 };
                 args.Requisition = bestSize;
             };
-            entryScrolledWindow.Add(_Entry);
+            entryScrolledWindow.Add(Entry);
+
+            ProgressBar = new Gtk.ProgressBar();
+            StatusHBox = new Gtk.HBox();
 
-            _ProgressBar = new Gtk.ProgressBar();
-            _ProgressBar.BarStyle = Gtk.ProgressBarStyle.Continuous;
+            MenuWidget = new MenuWidget(this, ChatViewManager);
 
-            MenuHBox = new Gtk.HBox();
-            MenuHBox.PackStart(MenuBar, true, true, 0);
-            MenuHBox.PackEnd(JoinWidget, false, false, 0);
+            Gtk.VPaned vpane = new Gtk.VPaned();
+            vpane.ButtonPressEvent += (sender, e) => {;
+                // reset entry size on double click
+                if (e.Event.Type == Gdk.EventType.TwoButtonPress &&
+                    e.Event.Button == 1) {
+                    GLib.Timeout.Add(100, delegate {
+                        vpane.Position = -1;
+                        return false;
+                    });
+                }
+            };
+            vpane.Pack1(Notebook, true, false);
+            vpane.Pack2(entryScrolledWindow, false, false);
 
             Gtk.VBox vbox = new Gtk.VBox();
-            vbox.PackStart(MenuHBox, false, false, 0);
-            vbox.PackStart(_Notebook, true, true, 0);
-            vbox.PackStart(entryScrolledWindow, false, false, 0);
+            vbox.PackStart(MenuWidget, false, false, 0);
+            vbox.PackStart(vpane, true, true, 0);
 
-            _NetworkStatusbar = new Gtk.Statusbar();
-            _NetworkStatusbar.WidthRequest = 300;
-            _NetworkStatusbar.HasResizeGrip = false;
+            NetworkStatusbar = new Gtk.Statusbar();
+            NetworkStatusbar.WidthRequest = 300;
+            NetworkStatusbar.HasResizeGrip = false;
             
-            _Statusbar = new Gtk.Statusbar();
-            _Statusbar.HasResizeGrip = false;
+            Statusbar = new Gtk.Statusbar();
+            Statusbar.HasResizeGrip = false;
             
             Gtk.HBox status_bar_hbox = new Gtk.HBox();
             status_bar_hbox.Homogeneous = true;
-            status_bar_hbox.PackStart(_NetworkStatusbar, false, true, 0);
-            status_bar_hbox.PackStart(_Statusbar, true, true, 0);
+            status_bar_hbox.PackStart(NetworkStatusbar, false, true, 0);
+            status_bar_hbox.PackStart(Statusbar, true, true, 0);
 
-            StatusHBox = new Gtk.HBox();
             StatusHBox.PackStart(status_bar_hbox);
-            StatusHBox.PackStart(_ProgressBar, false, false, 0);
+            StatusHBox.PackStart(ProgressBar, false, false, 0);
             StatusHBox.ShowAll();
             StatusHBox.NoShowAll = true;
-            StatusHBox.Visible = ShowStatusBarMenuItem.Active;
+            StatusHBox.Visible = (bool) Frontend.FrontendConfig["ShowStatusBar"];
 
             vbox.PackStart(StatusHBox, false, false, 0);
             Add(vbox);
@@ -601,23 +300,23 @@ namespace Smuxi.Frontend.Gnome
                 typeof(NotificationAreaIconMode),
                 modeStr
             );
-            _NotificationAreaIconMode = mode;
+            NotificationAreaIconMode = mode;
 
-            _OpenLogChatMenuItem.Visible = Frontend.IsLocalEngine;
+            MenuWidget.OpenLogAction.Visible = Frontend.IsLocalEngine;
 
 #if GTK_SHARP_2_10
-            _StatusIconManager.ApplyConfig(userConfig);
+            StatusIconManager.ApplyConfig(userConfig);
 #endif
-#if INDICATE_SHARP
-            _IndicateManager.ApplyConfig(userConfig);
+#if INDICATE_SHARP || MESSAGING_MENU_SHARP
+            IndicateManager.ApplyConfig(userConfig);
 #endif
 #if NOTIFY_SHARP
-            _NotifyManager.ApplyConfig(userConfig);
+            NotifyManager.ApplyConfig(userConfig);
 #endif
-            _Entry.ApplyConfig(userConfig);
-            _Notebook.ApplyConfig(userConfig);
-            _ChatViewManager.ApplyConfig(userConfig);
-            JoinWidget.ApplyConfig(userConfig);
+            Entry.ApplyConfig(userConfig);
+            Notebook.ApplyConfig(userConfig);
+            ChatViewManager.ApplyConfig(userConfig);
+            MenuWidget.JoinWidget.ApplyConfig(userConfig);
         }
 
         public void UpdateTitle()
@@ -654,23 +353,12 @@ namespace Smuxi.Frontend.Gnome
             Title = title;
         }
 
-        private void _OnQuitButtonClicked(object obj, EventArgs args)
-        {
-            Trace.Call(obj, args);
-            
-            try {
-                Frontend.Quit();
-            } catch (Exception ex) {
-                Frontend.ShowException(this, ex);
-            }
-        }
-
         protected virtual void OnDeleteEvent(object sender, Gtk.DeleteEventArgs e)
         {
             Trace.Call(sender, e);
             
             try {
-                if (_NotificationAreaIconMode == NotificationAreaIconMode.Closed) {
+                if (NotificationAreaIconMode == NotificationAreaIconMode.Closed) {
                     // showing the tray icon is handled in OnWindowStateEvent
                     Hide();
                     
@@ -691,11 +379,24 @@ namespace Smuxi.Frontend.Gnome
             
             try {
                 UrgencyHint = false;
-                if (_Notebook.IsBrowseModeEnabled) {
+
+                // HACK: users sometimes click into the person list by accident
+                // when they try to bring the focus back to the Smuxi window.
+                // We try to be nice and do what they probably meant and move
+                // the focus to the input entry instead.
+                // HACK: we have to use a timeout here as the ButtonPressEvent
+                // is directly raised _after_ the FocusInEvent. The idle loop
+                // turned out to be too racy and works only sometimes.
+                GLib.Timeout.Add(10, delegate {
+                    Entry.GrabFocus();
+                    return false;
+                });
+
+                if (Notebook.IsBrowseModeEnabled) {
                     return;
                 }
 
-                ChatView chatView = _Notebook.CurrentChatView;
+                ChatView chatView = Notebook.CurrentChatView;
                 if (chatView != null) {
                     // clear activity and highlight
                     chatView.HasHighlight = false;
@@ -726,11 +427,11 @@ namespace Smuxi.Frontend.Gnome
             Trace.Call(sender, e);
 
             try {
-                if (_Notebook.IsBrowseModeEnabled) {
+                if (Notebook.IsBrowseModeEnabled) {
                     return;
                 }
 
-                var chatView = _Notebook.CurrentChatView;
+                var chatView = Notebook.CurrentChatView;
                 if (chatView == null) {
                     return;
                 }
@@ -741,222 +442,6 @@ namespace Smuxi.Frontend.Gnome
             }
         }
 
-        protected virtual void OnServerQuickConnectButtonClicked(object sender, EventArgs e)
-        {
-            Trace.Call(sender, e);
-            
-            try {
-                QuickConnectDialog dialog = new QuickConnectDialog(this);
-                dialog.Load();
-                int res = dialog.Run();
-                ServerModel server = dialog.Server;
-                dialog.Destroy();
-                if (res != (int) Gtk.ResponseType.Ok) {
-                    return;
-                }
-                if (server == null) {
-#if LOG4NET
-                    f_Logger.Error("OnServerQuickConnectButtonClicked(): server is null!");
-                    return;
-#endif
-                }
-                
-                // do connect as background task as it might take a while
-                ThreadPool.QueueUserWorkItem(delegate {
-                    try {
-                        Frontend.Session.Connect(server, Frontend.FrontendManager);
-                    } catch (Exception ex) {
-                        Frontend.ShowException(this, ex);
-                    }
-                });
-            } catch (Exception ex) {
-                Frontend.ShowException(this, ex);
-            }
-        }
-
-#region Item Event Handlers
-        protected virtual void OnServerAddButtonClicked(object sender, EventArgs e)
-        {
-            Trace.Call(sender, e);
-            
-            ServerDialog dialog = null;
-            try {
-                ServerListController controller = new ServerListController(Frontend.UserConfig);
-                dialog = new ServerDialog(this, null,
-                                          Frontend.Session.GetSupportedProtocols(),
-                                          controller.GetNetworks());
-                int res = dialog.Run();
-                ServerModel server = dialog.GetServer();
-                if (res != (int) Gtk.ResponseType.Ok) {
-                    return;
-                }
-                
-                controller.AddServer(server);
-                controller.Save();
-            } catch (InvalidOperationException ex) {
-                Frontend.ShowError(this, _("Unable to add server: "), ex);
-            } catch (Exception ex) {
-                Frontend.ShowException(this, ex);
-            } finally {
-                if (dialog != null) {
-                    dialog.Destroy();
-                }
-            }
-        }
-
-        protected virtual void OnServerManageServersButtonClicked(object sender, EventArgs e)
-        {
-            Trace.Call(sender, e);
-            
-            try {
-                PreferencesDialog dialog = new PreferencesDialog(this);
-                dialog.CurrentPage = PreferencesDialog.Page.Servers;
-            } catch (Exception ex) {
-                Frontend.ShowException(this, ex);
-            }
-        }
-
-        protected virtual void OnChatFindGroupChatButtonClicked(object sender, EventArgs e)
-        {
-            Trace.Call(sender, e);
-            try {
-                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;
-            }
-
-            var manager = chatView.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)
-        {
-            Trace.Call(sender, e);
-            
-            try {
-                _Notebook.ClearAllActivity();
-            } catch (Exception ex) {
-                Frontend.ShowException(this, ex);
-            }
-        }
-        
-        protected virtual void OnFindChatMenuItemActivated(object sender, EventArgs e)
-        {
-            Trace.Call(sender, e);
-            
-            try {
-            } catch (Exception ex) {
-                Frontend.ShowException(this, ex);
-            }
-        }
-        
-        protected virtual void OnFindNextChatMenuItemActivated(object sender, EventArgs e)
-        {
-            Trace.Call(sender, e);
-            
-            try {
-            } catch (Exception ex) {
-                Frontend.ShowException(this, ex);
-            }
-        }
-        
-        protected virtual void OnFindPreviousChatMenuItemActivated(object sender, EventArgs e)
-        {
-            Trace.Call(sender, e);
-            
-            try {
-            } catch (Exception ex) {
-                Frontend.ShowException(this, ex);
-            }
-        }
-        
-        protected virtual void OnCloseChatMenuItemActivated(object sender, EventArgs e)
-        {
-            Trace.Call(sender, e);
-            
-            try {
-                _Notebook.CurrentChatView.Close();
-            } catch (Exception ex) {
-                Frontend.ShowException(this, ex);
-            }
-        }
-
-        protected virtual void OnOpenLogChatMenuItemActivated(object sender, EventArgs e)
-        {
-            Trace.Call(sender, e);
-
-            try {
-                ThreadPool.QueueUserWorkItem(delegate {
-                    try {
-                        SysDiag.Process.Start(_Notebook.CurrentChatView.ChatModel.LogFile);
-                    } catch (Exception ex) {
-                        Frontend.ShowError(this, ex);
-                    }
-                });
-            } catch (Exception ex) {
-                Frontend.ShowException(this, ex);
-            }
-        }
-
-        protected virtual void OnNextChatMenuItemActivated(object sender, EventArgs e)
-        {
-            Trace.Call(sender, e);
-            
-            try {
-                ChatViewManager.CurrentChatNumber++;
-            } catch (Exception ex) {
-                Frontend.ShowException(this, ex);
-            }
-        }
-        
-        protected virtual void OnPreviousChatMenuItemActivated(object sender, EventArgs e)
-        {
-            Trace.Call(sender, e);
-            
-            try {
-                ChatViewManager.CurrentChatNumber--;
-            } catch (Exception ex) {
-                Frontend.ShowException(this, ex);
-            }
-        }
-                
         protected virtual void OnWindowStateEvent(object sender, Gtk.WindowStateEventArgs e)
         {
             Trace.Call(sender, e);
@@ -964,9 +449,9 @@ namespace Smuxi.Frontend.Gnome
             try {
                 // handle minimize / un-minimize
                 if ((e.Event.ChangedMask & Gdk.WindowState.Iconified) != 0) {
-                    _IsMinimized = (e.Event.NewWindowState & Gdk.WindowState.Iconified) != 0;
+                    IsMinimized = (e.Event.NewWindowState & Gdk.WindowState.Iconified) != 0;
 #if LOG4NET
-                    f_Logger.Debug("OnWindowStateEvent(): _IsMinimized: " + _IsMinimized);
+                    f_Logger.Debug("OnWindowStateEvent(): IsMinimized: " + IsMinimized);
 #endif
                     #if DISABLED
                     // BUG: metacity is not allowing us to use the minimize state
@@ -976,7 +461,7 @@ namespace Smuxi.Frontend.Gnome
                     // http://projects.qnetp.net/issues/show/158
                     Hide();
                     #endif
-                    if (_IsMinimized) {
+                    if (IsMinimized) {
                         if (Minimized != null) {
                             Minimized(this, EventArgs.Empty);
                         }
@@ -989,9 +474,9 @@ namespace Smuxi.Frontend.Gnome
 
                 // handle maximize / un-maximize
                 if ((e.Event.ChangedMask & Gdk.WindowState.Maximized) != 0) {
-                    _IsMaximized = (e.Event.NewWindowState & Gdk.WindowState.Maximized) != 0;
+                    IsMaximized = (e.Event.NewWindowState & Gdk.WindowState.Maximized) != 0;
 #if LOG4NET
-                    f_Logger.Debug("OnWindowStateEvent(): _IsMaximized: " + _IsMaximized);
+                    f_Logger.Debug("OnWindowStateEvent(): IsMaximized: " + IsMaximized);
 #endif
                 }
             } catch (Exception ex) {
@@ -1007,13 +492,28 @@ namespace Smuxi.Frontend.Gnome
                     return;
                 }
 
-                _CloseChatMenuItem.Sensitive = !(chatView is SessionChatView);
-                _FindGroupChatMenuItem.Sensitive = !(chatView is SessionChatView);
+                if (!Frontend.IsMacOSX) {
+                    MenuWidget.CloseChatAction.Sensitive = !(chatView is SessionChatView);
+                }
+                MenuWidget.FindGroupChatAction.Sensitive = !(chatView is SessionChatView);
                 if (Frontend.IsLocalEngine) {
-                    _OpenLogChatMenuItem.Sensitive =
+                    MenuWidget.OpenLogAction.Sensitive =
                         File.Exists(chatView.ChatModel.LogFile);
                 }
 
+                // find protocol chat parent and update join bar
+                foreach (var view in ChatViewManager.Chats) {
+                    if (!(view is ProtocolChatView) ||
+                        view.ProtocolManager == null) {
+                        continue;
+                    }
+                    if (chatView.ProtocolManager == view.ProtocolManager) {
+                        var pView = (ProtocolChatView) view;
+                        MenuWidget.JoinWidget.ActiveNetwork = pView.NetworkID;
+                        break;
+                    }
+                }
+
                 // HACK: Gtk.Notebook moves the focus to the child after the
                 // page has been switched, so move the focus back to the entry
                 GLib.Idle.Add(delegate {
@@ -1032,200 +532,6 @@ namespace Smuxi.Frontend.Gnome
             Entry.GrabFocus();
         }
 
-        protected virtual void OnJoinWidgetActivated(object sender, EventArgs e)
-        {
-            Trace.Call(sender, e);
-
-            try {
-                var chatLink = JoinWidget.GetChatLink();
-                Frontend.OpenChatLink(chatLink);
-                JoinWidget.Clear();
-            } catch (Exception ex) {
-                Frontend.ShowException(this, ex);
-            }
-        }
-
-        protected virtual void OnShowQuickJoinMenuItemActivated(object sender, EventArgs e)
-        {
-            Trace.Call(sender, e);
-
-            try {
-                JoinWidget.Visible = !JoinWidget.Visible;
-                Frontend.FrontendConfig["ShowQuickJoin"] = JoinWidget.Visible;
-                Frontend.FrontendConfig.Save();
-            } catch (Exception ex) {
-                Frontend.ShowException(this, ex);
-            }
-        }
-
-        protected virtual void OnShowMenuBarMenuItemActivated(object sender, EventArgs e)
-        {
-            Trace.Call(sender, e);
-
-            try {
-                MenuBar.Visible = ShowMenuBarMenuItem.Active;
-                Frontend.FrontendConfig["ShowMenuBar"] = MenuBar.Visible;
-                Frontend.FrontendConfig.Save();
-            } catch (Exception ex) {
-                Frontend.ShowException(this, ex);
-            }
-        }
-
-        protected virtual void OnShowStatusBarMenuItemActivated(object sender, EventArgs e)
-        {
-            Trace.Call(sender, e);
-
-            try {
-                StatusHBox.Visible = ShowStatusBarMenuItem.Active;
-                Frontend.FrontendConfig["ShowStatusBar"] = StatusHBox.Visible;
-                Frontend.FrontendConfig.Save();
-            } catch (Exception ex) {
-                Frontend.ShowException(this, ex);
-            }
-        }
-
-        protected virtual void OnOpenChatMenuItemActivated(object sender, EventArgs e)
-        {
-            Trace.Call(sender, e);
-
-            try {
-                if (!ShowQuickJoinMenuItem.Active) {
-                    ShowQuickJoinMenuItem.Activate();
-                }
-                JoinWidget.HasFocus = true;
-            } catch (Exception ex) {
-                Frontend.ShowException(this, ex);
-            }
-        }
-
-        protected static void AccelCanActivateSensitive(object sender, Gtk.AccelCanActivateArgs e)
-        {
-            var widget = sender as Gtk.Widget;
-            if (widget != null && !widget.Sensitive) {
-                e.RetVal = false;
-                return;
-            }
-
-            // allow the accelerator to be used even when the menu bar is hidden
-            e.RetVal = true;
-        }
-
-        private void _OnAboutButtonClicked(object obj, EventArgs args)
-        {
-            Trace.Call(obj, args);
-            
-            try {
-                AboutDialog ad = new AboutDialog(this);
-                ad.Run();
-                ad.Destroy();
-            } catch (Exception ex) {
-                Frontend.ShowException(this, ex);
-            }
-        }
-        
-        private void _OnPreferencesButtonClicked(object obj, EventArgs args)
-        {
-            Trace.Call(obj, args);
-            
-            try {
-                new PreferencesDialog(this);
-                /*
-                SteticPreferencesDialog dialog = new SteticPreferencesDialog();
-                dialog.Run();
-                */
-            } catch (Exception e) {
-#if LOG4NET
-                f_Logger.Error(e);
-#endif
-                Frontend.ShowException(this, e);
-            }
-        }
-        
-        private void _OnUseLocalEngineButtonClicked(object obj, EventArgs args)
-        {
-            Trace.Call(obj, args);
-            
-            try {
-                Gtk.MessageDialog md = new Gtk.MessageDialog(null, Gtk.DialogFlags.Modal,
-                    Gtk.MessageType.Warning, Gtk.ButtonsType.YesNo,
-                    _("Switching to local engine will disconnect you from the current engine!\n"+
-                      "Are you sure you want to do this?"));
-                int result = md.Run();
-                md.Destroy();
-                if ((Gtk.ResponseType)result == Gtk.ResponseType.Yes) {
-                    Frontend.DisconnectEngineFromGUI();
-                    Frontend.InitLocalEngine();
-                    Frontend.ConnectEngineToGUI();
-                }
-            } catch (Exception ex) {
-                Frontend.ShowException(this, ex);
-            }
-        }
-        
-        private void _OnAddRemoteEngineButtonClicked(object obj, EventArgs args)
-        {
-            Trace.Call(obj, args);
-            
-            try {
-                EngineAssistant assistant = new EngineAssistant(
-                    this,
-                    Frontend.FrontendConfig
-                );
-                assistant.Cancel += delegate {
-                    assistant.Destroy();
-                };
-                assistant.Close += delegate {
-                    assistant.Destroy();
-                };
-                assistant.ShowAll();
-            } catch (Exception ex) {
-                Frontend.ShowException(this, ex);
-            }
-        }
-        
-        private void _OnSwitchRemoteEngineButtonClicked(object obj, EventArgs args)
-        {
-            Trace.Call(obj, args);
-            
-            try {
-                Gtk.MessageDialog md = new Gtk.MessageDialog(null, Gtk.DialogFlags.Modal,
-                    Gtk.MessageType.Warning, Gtk.ButtonsType.YesNo,
-                    _("Switching the remote engine will disconnect you from the current engine!\n"+
-                      "Are you sure you want to do this?"));
-                int result = md.Run();
-                md.Destroy();
-                if ((Gtk.ResponseType)result == Gtk.ResponseType.Yes) {
-                    Frontend.DisconnectEngineFromGUI();
-                    Frontend.ShowEngineManagerDialog();
-                }
-            } catch (Exception ex) {
-                Frontend.ShowException(this, ex);
-            }
-        }
-
-        private void _OnCaretModeButtonClicked(object obj, EventArgs args)
-        {
-            Trace.Call(obj, args);
-            
-            try {
-                _CaretMode = !_CaretMode;
-                
-                for (int i = 0; i < _Notebook.NPages; i++) {
-                    ChatView chatView = _Notebook.GetChat(i);
-                    chatView.OutputMessageTextView.CursorVisible = _CaretMode;
-                }
-                
-                if (_CaretMode) {
-                    _Notebook.CurrentChatView.OutputMessageTextView.HasFocus = true;
-                } else {
-                    _Entry.HasFocus = true;
-                }
-            } catch (Exception ex) {
-                Frontend.ShowException(this, ex);
-            }
-        }
-#endregion
-        
         protected void OnChatViewManagerChatAdded(object sender, ChatViewManagerChatAddedEventArgs e)
         {
             Trace.Call(sender, e);
@@ -1267,16 +573,16 @@ namespace Smuxi.Frontend.Gnome
 
         public void UpdateProgressBar()
         {
-            var totalChatCount = _ChatViewManager.Chats.Count;
-            var syncedChatCount =  _ChatViewManager.SyncedChats.Count;
-            _ProgressBar.Fraction = (double)syncedChatCount / totalChatCount;
-            _ProgressBar.Text = String.Format("{0} / {1}",
+            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();
+                ProgressBar.Hide();
             } else {
-                _ProgressBar.Show();
+                ProgressBar.Show();
             }
         }
 
diff --git a/src/Frontend-GNOME/Makefile.am b/src/Frontend-GNOME/Makefile.am
index f2df75a..bad9e01 100644
--- a/src/Frontend-GNOME/Makefile.am
+++ b/src/Frontend-GNOME/Makefile.am
@@ -1,4 +1,4 @@
-
+TARGET_DIR = $(top_builddir)/bin/$(PROFILE)
 EXTRA_DIST = $(WIN_ICON) $(DESKTOP_FILE).in
 
 ICON_NAME = smuxi-frontend-gnome
@@ -121,7 +121,6 @@ FILES = \
 	GnomeUI.cs \
 	Gtk.WindowExtensions.cs \
 	IndicateManager.cs \
-	LinkTag.cs \
 	Main.cs \
 	MainWindow.cs \
 	NetworkManager.cs \
@@ -136,6 +135,7 @@ FILES = \
 	Preferences/ServerListView.cs \
 	Preferences/PreferencesDialog.cs \
 	Views/JoinWidget.cs \
+	Views/MenuWidget.cs \
 	Views/MessageTextView.cs \
 	Views/ServerWidget.cs \
 	Views/ServerDialog.cs \
@@ -150,6 +150,8 @@ FILES = \
 	Views/Assistants/Engine/EngineAssistantConnectionWidget.cs \
 	Views/Assistants/Engine/EngineAssistantIntroWidget.cs \
 	Views/Assistants/Engine/EngineAssistant.cs \
+	Views/Tags/LinkTag.cs \
+	Views/Tags/PersonTag.cs \
 	QuickConnectDialog.cs \
 	SteticPreferencesDialog.cs \
 	FindGroupChatDialog.cs \
@@ -163,6 +165,7 @@ FILES = \
 	gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantIntroWidget.cs \
 	gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs \
 	gtk-gui/Smuxi.Frontend.Gnome.JoinWidget.cs \
+	gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs \
 	gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs \
 	gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs \
 	gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs \
@@ -171,8 +174,13 @@ FILES = \
 	gtk-gui/Smuxi.Frontend.Gnome.ChatTypeWidget.cs \
 	gtk-gui/Smuxi.Frontend.Gnome.ServerDialog.cs \
 	gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs \
-	gtk-gui/Smuxi.Frontend.Gnome.FilterListWidget.cs
-	
+	gtk-gui/Smuxi.Frontend.Gnome.FilterListWidget.cs \
+	osx/AppleEvent.cs \
+	osx/ApplicationEvents.cs \
+	osx/Carbon.cs \
+	osx/CoreFoundation.cs \
+	osx/IgeMacMenu.cs
+
 DATA_FILES = \
 	$(DESKTOP_FILE) \
 	$(ICON_SVG) \
@@ -205,12 +213,15 @@ REFERENCES =  \
 	$(GLIB_SHARP_20_LIBS) \
 	$(GLADE_SHARP_20_LIBS) \
 	$(GTK_SHARP_20_LIBS) \
+	$(GIO_SHARP_LIBS) \
 	$(LOG4NET_LIBS) \
 	$(INDICATE_SHARP_LIBS) \
+	$(MESSAGINGMENU_SHARP_LIBS) \
+	$(MESSAGINGMENU_SHARP_INCLUDED_LIBS) \
 	$(NOTIFY_SHARP_LIBS) \
 	$(DBUS_LIBS)
 
-DLL_REFERENCES = 
+DLL_REFERENCES = $(MESSAGINGMENU_SHARP_INCLUDED_LIBS) 
 
 CLEANFILES = $(LINUX_DESKTOPAPPLICATIONS) $(PROGRAMFILES) $(BINARIES) \
 	$(top_builddir)/images/256/$(GROUP_CHAT_ICON_NAME).png \
@@ -224,6 +235,28 @@ FRONTEND_GNOME_DESKTOP = $(BUILD_DIR)/$(DESKTOP_FILE)
 SMUXI_FRONTEND_DLL = $(BUILD_DIR)/smuxi-frontend.dll
 SMUXI_COMMON_DLL = $(BUILD_DIR)/smuxi-common.dll
 
+if WITH_MESSAGINGMENU_SHARP_INCLUDED
+MESSAGINGMENU_SHARP_DLL = $(TARGET_DIR)/messagingmenu-sharp.dll
+MESSAGINGMENU_SHARP_DLL_SOURCE = $(top_builddir)/lib/messagingmenu-sharp/messagingmenu-sharp.dll
+MESSAGINGMENU_SHARP_DLL_CONFIG = $(MESSAGINGMENU_SHARP_DLL).config
+MESSAGINGMENU_SHARP_DLL_CONFIG_SOURCE = $(MESSAGINGMENU_SHARP_DLL_SOURCE).config
+$(eval $(call emit-deploy-target,MESSAGINGMENU_SHARP_DLL))
+$(eval $(call emit-deploy-target,MESSAGINGMENU_SHARP_DLL_CONFIG))
+
+MESSAGINGMENU_SHARP_INCLUDED_LIBS := $(foreach file, $(MESSAGINGMENU_SHARP_FILES), $(TARGET_DIR)/$(file))
+PROGRAMFILES += $(MESSAGINGMENU_SHARP_INCLUDED_LIBS) $(MESSAGINGMENU_SHARP_INCLUDED_LIBS).config
+
+GIO_SHARP_DLL = $(TARGET_DIR)/gio-sharp.dll
+GIO_SHARP_DLL_SOURCE =  $(GIO_SHARP_LIBS)
+GIO_SHARP_DLL_CONFIG = $(TARGET_DIR)/gio-sharp.dll.config
+GIO_SHARP_DLL_CONFIG_SOURCE = $(GIO_SHARP_LIBS).config
+$(eval $(call emit-deploy-target,GIO_SHARP_DLL))
+$(eval $(call emit-deploy-target,GIO_SHARP_DLL_CONFIG))
+
+GIO_SHARP_PROGRAM_FILES := $(foreach file, $(GIO_SHARP_FILES), $(shell file=$(TARGET_DIR)/$(file); echo $$file; config_file=$${file}.config; if [ -f "$$config_file" ]; then echo $$config_file; fi))
+PROGRAMFILES += $(GIO_SHARP_DLL) $(GIO_SHARP_DLL_CONFIG)
+endif
+
 $(eval $(call emit-deploy-wrapper,FRONTEND_GNOME,smuxi-frontend-gnome,x))
 $(eval $(call emit-deploy-target,FRONTEND_GNOME_DESKTOP))
 $(eval $(call emit-deploy-target,FRONTEND_GNOME_EXE_CONFIG))
diff --git a/src/Frontend-GNOME/Makefile.in b/src/Frontend-GNOME/Makefile.in
index 8f4ad24..4690296 100644
--- a/src/Frontend-GNOME/Makefile.in
+++ b/src/Frontend-GNOME/Makefile.in
@@ -55,11 +55,18 @@ host_triplet = @host@
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
 	$(srcdir)/smuxi-frontend-gnome.in \
 	$(top_srcdir)/Makefile.include ChangeLog
+ at WITH_MESSAGINGMENU_SHARP_INCLUDED_TRUE@am__append_1 = $(MESSAGINGMENU_SHARP_INCLUDED_LIBS) \
+ at WITH_MESSAGINGMENU_SHARP_INCLUDED_TRUE@	$(MESSAGINGMENU_SHARP_INCLUDED_LIBS).config \
+ at WITH_MESSAGINGMENU_SHARP_INCLUDED_TRUE@	$(GIO_SHARP_DLL) \
+ at WITH_MESSAGINGMENU_SHARP_INCLUDED_TRUE@	$(GIO_SHARP_DLL_CONFIG)
 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
@@ -156,9 +163,8 @@ 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_CAMPFIRE = @GETTEXT_PACKAGE_ENGINE_CAMPFIRE@
 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@
@@ -170,6 +176,9 @@ 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@
+GIO_SHARP_CFLAGS = @GIO_SHARP_CFLAGS@
+GIO_SHARP_FILES = @GIO_SHARP_FILES@
+GIO_SHARP_LIBS = @GIO_SHARP_LIBS@
 GLADE_SHARP_20_CFLAGS = @GLADE_SHARP_20_CFLAGS@
 GLADE_SHARP_20_LIBS = @GLADE_SHARP_20_LIBS@
 GLIB_SHARP_20_CFLAGS = @GLIB_SHARP_20_CFLAGS@
@@ -216,6 +225,11 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
+MESSAGINGMENU_SHARP_CFLAGS = @MESSAGINGMENU_SHARP_CFLAGS@
+MESSAGINGMENU_SHARP_FILES = @MESSAGINGMENU_SHARP_FILES@
+MESSAGINGMENU_SHARP_LIBS = @MESSAGINGMENU_SHARP_LIBS@
+MESSAGING_MENU_CFLAGS = @MESSAGING_MENU_CFLAGS@
+MESSAGING_MENU_LIBS = @MESSAGING_MENU_LIBS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
 MONO_MODULE_CFLAGS = @MONO_MODULE_CFLAGS@
@@ -223,8 +237,6 @@ 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@
@@ -237,8 +249,6 @@ 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@
@@ -330,6 +340,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 = $(WIN_ICON) $(DESKTOP_FILE).in $(build_sources) \
 	$(build_resx_files) $(build_others_files) \
 	$(ASSEMBLY_WRAPPER_IN) $(EXTRAS) $(DATA_FILES) \
@@ -398,14 +409,10 @@ 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 = \
-	$(SMUXI_ENGINE_DLL_MDB) \
-	$(SMUXI_ENGINE_DLL) \
-	$(SMUXI_FRONTEND_DLL_MDB) \
-	$(SMUXI_FRONTEND_DLL) \
-	$(SMUXI_COMMON_DLL)  \
-	$(FRONTEND_GNOME_EXE_CONFIG)
-
+PROGRAMFILES = $(SMUXI_ENGINE_DLL_MDB) $(SMUXI_ENGINE_DLL) \
+	$(SMUXI_FRONTEND_DLL_MDB) $(SMUXI_FRONTEND_DLL) \
+	$(SMUXI_COMMON_DLL) $(FRONTEND_GNOME_EXE_CONFIG) \
+	$(am__append_1)
 LINUX_DESKTOPAPPLICATIONS = \
 	$(FRONTEND_GNOME_DESKTOP_DESKTOP)  
 
@@ -423,7 +430,6 @@ FILES = \
 	GnomeUI.cs \
 	Gtk.WindowExtensions.cs \
 	IndicateManager.cs \
-	LinkTag.cs \
 	Main.cs \
 	MainWindow.cs \
 	NetworkManager.cs \
@@ -438,6 +444,7 @@ FILES = \
 	Preferences/ServerListView.cs \
 	Preferences/PreferencesDialog.cs \
 	Views/JoinWidget.cs \
+	Views/MenuWidget.cs \
 	Views/MessageTextView.cs \
 	Views/ServerWidget.cs \
 	Views/ServerDialog.cs \
@@ -452,6 +459,8 @@ FILES = \
 	Views/Assistants/Engine/EngineAssistantConnectionWidget.cs \
 	Views/Assistants/Engine/EngineAssistantIntroWidget.cs \
 	Views/Assistants/Engine/EngineAssistant.cs \
+	Views/Tags/LinkTag.cs \
+	Views/Tags/PersonTag.cs \
 	QuickConnectDialog.cs \
 	SteticPreferencesDialog.cs \
 	FindGroupChatDialog.cs \
@@ -465,6 +474,7 @@ FILES = \
 	gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantIntroWidget.cs \
 	gtk-gui/Smuxi.Frontend.Gnome.EngineAssistantNameWidget.cs \
 	gtk-gui/Smuxi.Frontend.Gnome.JoinWidget.cs \
+	gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs \
 	gtk-gui/Smuxi.Frontend.Gnome.OpenChatDialog.cs \
 	gtk-gui/Smuxi.Frontend.Gnome.SteticPreferencesDialog.cs \
 	gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs \
@@ -473,7 +483,12 @@ FILES = \
 	gtk-gui/Smuxi.Frontend.Gnome.ChatTypeWidget.cs \
 	gtk-gui/Smuxi.Frontend.Gnome.ServerDialog.cs \
 	gtk-gui/Smuxi.Frontend.Gnome.ServerWidget.cs \
-	gtk-gui/Smuxi.Frontend.Gnome.FilterListWidget.cs
+	gtk-gui/Smuxi.Frontend.Gnome.FilterListWidget.cs \
+	osx/AppleEvent.cs \
+	osx/ApplicationEvents.cs \
+	osx/Carbon.cs \
+	osx/CoreFoundation.cs \
+	osx/IgeMacMenu.cs
 
 DATA_FILES = \
 	$(DESKTOP_FILE) \
@@ -507,12 +522,15 @@ REFERENCES = \
 	$(GLIB_SHARP_20_LIBS) \
 	$(GLADE_SHARP_20_LIBS) \
 	$(GTK_SHARP_20_LIBS) \
+	$(GIO_SHARP_LIBS) \
 	$(LOG4NET_LIBS) \
 	$(INDICATE_SHARP_LIBS) \
+	$(MESSAGINGMENU_SHARP_LIBS) \
+	$(MESSAGINGMENU_SHARP_INCLUDED_LIBS) \
 	$(NOTIFY_SHARP_LIBS) \
 	$(DBUS_LIBS)
 
-DLL_REFERENCES = 
+DLL_REFERENCES = $(MESSAGINGMENU_SHARP_INCLUDED_LIBS) 
 CLEANFILES = $(LINUX_DESKTOPAPPLICATIONS) $(PROGRAMFILES) $(BINARIES) \
 	$(top_builddir)/images/256/$(GROUP_CHAT_ICON_NAME).png \
 	$(top_builddir)/images/256/$(PERSON_CHAT_ICON_NAME).png \
@@ -572,6 +590,16 @@ FRONTEND_GNOME = $(BUILD_DIR)/smuxi-frontend-gnome
 FRONTEND_GNOME_DESKTOP = $(BUILD_DIR)/$(DESKTOP_FILE)
 SMUXI_FRONTEND_DLL = $(BUILD_DIR)/smuxi-frontend.dll
 SMUXI_COMMON_DLL = $(BUILD_DIR)/smuxi-common.dll
+ at WITH_MESSAGINGMENU_SHARP_INCLUDED_TRUE@MESSAGINGMENU_SHARP_DLL = $(TARGET_DIR)/messagingmenu-sharp.dll
+ at WITH_MESSAGINGMENU_SHARP_INCLUDED_TRUE@MESSAGINGMENU_SHARP_DLL_SOURCE = $(top_builddir)/lib/messagingmenu-sharp/messagingmenu-sharp.dll
+ at WITH_MESSAGINGMENU_SHARP_INCLUDED_TRUE@MESSAGINGMENU_SHARP_DLL_CONFIG = $(MESSAGINGMENU_SHARP_DLL).config
+ at WITH_MESSAGINGMENU_SHARP_INCLUDED_TRUE@MESSAGINGMENU_SHARP_DLL_CONFIG_SOURCE = $(MESSAGINGMENU_SHARP_DLL_SOURCE).config
+ at WITH_MESSAGINGMENU_SHARP_INCLUDED_TRUE@MESSAGINGMENU_SHARP_INCLUDED_LIBS := $(foreach file, $(MESSAGINGMENU_SHARP_FILES), $(TARGET_DIR)/$(file))
+ at WITH_MESSAGINGMENU_SHARP_INCLUDED_TRUE@GIO_SHARP_DLL = $(TARGET_DIR)/gio-sharp.dll
+ at WITH_MESSAGINGMENU_SHARP_INCLUDED_TRUE@GIO_SHARP_DLL_SOURCE = $(GIO_SHARP_LIBS)
+ at WITH_MESSAGINGMENU_SHARP_INCLUDED_TRUE@GIO_SHARP_DLL_CONFIG = $(TARGET_DIR)/gio-sharp.dll.config
+ at WITH_MESSAGINGMENU_SHARP_INCLUDED_TRUE@GIO_SHARP_DLL_CONFIG_SOURCE = $(GIO_SHARP_LIBS).config
+ at WITH_MESSAGINGMENU_SHARP_INCLUDED_TRUE@GIO_SHARP_PROGRAM_FILES := $(foreach file, $(GIO_SHARP_FILES), $(shell file=$(TARGET_DIR)/$(file); echo $$file; config_file=$${file}.config; if [ -f "$$config_file" ]; then echo $$config_file; fi))
 all: all-am
 
 .SUFFIXES:
@@ -1191,6 +1219,10 @@ $(eval $(foreach res, $(culture_resources), $(eval $(call culture_resource_comma
 $(build_satellite_assembly_list): $(BUILD_DIR)/%/$(SATELLITE_ASSEMBLY_NAME):
 	mkdir -p '$(@D)'
 	$(AL) -out:'$@' -culture:$* -t:lib $(cmd_line_satellite_$*)
+ at WITH_MESSAGINGMENU_SHARP_INCLUDED_TRUE@$(eval $(call emit-deploy-target,MESSAGINGMENU_SHARP_DLL))
+ at WITH_MESSAGINGMENU_SHARP_INCLUDED_TRUE@$(eval $(call emit-deploy-target,MESSAGINGMENU_SHARP_DLL_CONFIG))
+ at WITH_MESSAGINGMENU_SHARP_INCLUDED_TRUE@$(eval $(call emit-deploy-target,GIO_SHARP_DLL))
+ at WITH_MESSAGINGMENU_SHARP_INCLUDED_TRUE@$(eval $(call emit-deploy-target,GIO_SHARP_DLL_CONFIG))
 
 $(eval $(call emit-deploy-wrapper,FRONTEND_GNOME,smuxi-frontend-gnome,x))
 $(eval $(call emit-deploy-target,FRONTEND_GNOME_DESKTOP))
diff --git a/src/Frontend-GNOME/Preferences/PreferencesDialog.cs b/src/Frontend-GNOME/Preferences/PreferencesDialog.cs
index 4ed0137..855f42f 100644
--- a/src/Frontend-GNOME/Preferences/PreferencesDialog.cs
+++ b/src/Frontend-GNOME/Preferences/PreferencesDialog.cs
@@ -118,6 +118,12 @@ namespace Smuxi.Frontend.Gnome
             _Glade.Autoconnect(this);
             _Dialog = (Gtk.Dialog)_Glade["PreferencesDialog"];
             _Dialog.TransientFor = parent;
+            if (Frontend.IsMacOSX) {
+                // HACK: center on parent is not working for this dialog
+                _Dialog.SetPosition(Gtk.WindowPosition.CenterAlways);
+            } else {
+                _Dialog.SetPosition(Gtk.WindowPosition.CenterOnParent);
+            }
             
             ((Gtk.Button)_Glade["OKButton"]).Clicked += new EventHandler(_OnOKButtonClicked);
             ((Gtk.Button)_Glade["ApplyButton"]).Clicked += new EventHandler(_OnApplyButtonClicked);
@@ -277,7 +283,12 @@ namespace Smuxi.Frontend.Gnome
 
             _Load();
         }
-        
+
+        public void Show()
+        {
+            _Dialog.Show();
+        }
+
         private void _Load()
         {
             Trace.Call();
@@ -839,7 +850,7 @@ namespace Smuxi.Frontend.Gnome
             foreach (string word in highlight_words) {
                 if (word.StartsWith("/") && word.EndsWith("/")) {
                     try {
-                        Regex regex = new Regex(word.Substring(1, word.Length - 2));
+                        new Regex(word.Substring(1, word.Length - 2));
                     } catch (ArgumentException ex) {
                         throw new ApplicationException(
                             String.Format(
diff --git a/src/Frontend-GNOME/Preferences/ServerListView.cs b/src/Frontend-GNOME/Preferences/ServerListView.cs
index d17b339..f49ad95 100644
--- a/src/Frontend-GNOME/Preferences/ServerListView.cs
+++ b/src/Frontend-GNOME/Preferences/ServerListView.cs
@@ -74,6 +74,8 @@ namespace Smuxi.Frontend.Gnome
                                            typeof(string), // protocol
                                            typeof(string) // hostname
                                            );
+            _TreeStore.SetSortColumnId(0, Gtk.SortType.Ascending);
+            _TreeStore.SetSortFunc(0, SortTreeStore);
             _TreeView.RowActivated += OnTreeViewRowActivated;
             _TreeView.Selection.Changed += OnTreeViewSelectionChanged;
             _TreeView.Model = _TreeStore;
@@ -191,7 +193,7 @@ namespace Smuxi.Frontend.Gnome
                 return;
             }
             
-            _Controller.RemoveServer(server.Protocol, server.Hostname);
+            _Controller.RemoveServer(server.Protocol, server.ServerID);
             _Controller.Save();
             
             // refresh the view
@@ -279,7 +281,32 @@ namespace Smuxi.Frontend.Gnome
                 Frontend.ShowException(ex);
             }
         }
-        
+
+        protected virtual int SortTreeStore(Gtk.TreeModel model,
+                                            Gtk.TreeIter iter1,
+                                            Gtk.TreeIter iter2)
+        {
+            var server1 = (ServerModel) model.GetValue(iter1, 0);
+            var server2 = (ServerModel) model.GetValue(iter2, 0);
+            // protocol nodes don't have a ServerModel
+            if (server1 == null && server2 == null) {
+                return 0;
+            }
+            if (server2 == null) {
+                return 1;
+            }
+            if (server1 == null) {
+                return -1;
+            }
+            var s1 = String.Format("{0}/{1}:{2} ({3})",
+                                   server1.Protocol, server1.Hostname,
+                                   server1.Port, server1.ServerID);
+            var s2 = String.Format("{0}/{1}:{2} ({3})",
+                                   server2.Protocol, server2.Hostname,
+                                   server2.Port, server2.ServerID);
+            return s1.CompareTo(s2);
+        }
+
         private static string _(string msg)
         {
             return Mono.Unix.Catalog.GetString(msg);
diff --git a/src/Frontend-GNOME/QuickConnectDialog.cs b/src/Frontend-GNOME/QuickConnectDialog.cs
index 07a967f..a3cd11c 100644
--- a/src/Frontend-GNOME/QuickConnectDialog.cs
+++ b/src/Frontend-GNOME/QuickConnectDialog.cs
@@ -39,7 +39,9 @@ namespace Smuxi.Frontend.Gnome
             }
         }
         
-        public QuickConnectDialog(Gtk.Window parent)
+        public QuickConnectDialog(Gtk.Window parent) :
+                             base(null, parent,
+                                  Gtk.DialogFlags.DestroyWithParent)
         {
             Trace.Call(parent);
 
diff --git a/src/Frontend-GNOME/ThemeSettings.cs b/src/Frontend-GNOME/ThemeSettings.cs
index 662cc44..7807b16 100644
--- a/src/Frontend-GNOME/ThemeSettings.cs
+++ b/src/Frontend-GNOME/ThemeSettings.cs
@@ -147,10 +147,13 @@ namespace Smuxi.Frontend.Gnome
                 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) {
+                    var hasConsolas = false;
+                    using (var context = Frontend.MainWindow.CreatePangoContext()) {
+                        hasConsolas = context.Families.Any(
+                            family => family.Name == "Consolas"
+                        );
+                    }
+                    if (hasConsolas && !isWinXp) {
                         // this system has Consolas available and is not WinXP,
                         // let's use it!
                         fontDescription.Family = "Consolas, monospace";
@@ -166,6 +169,20 @@ namespace Smuxi.Frontend.Gnome
                         fontDescription.Weight = Pango.Weight.Bold;
                         fontDescription.Style = Pango.Style.Normal;
                     }
+                } else if (Frontend.IsMacOSX) {
+                    // HACK: family font description with font fallbacks is not
+                    // working on OS X, thus we have to probe and decide ourself
+                    var ctx = Frontend.MainWindow.CreatePangoContext();
+                    var families = ctx.Families;
+                    if (families.Any(family =>
+                                     family.Name == "Menlo")) {
+                        fontDescription.Family = "Menlo";
+                    } else if (families.Any(family =>
+                                            family.Name == "Monaco")) {
+                        fontDescription.Family = "Monaco";
+                    } else {
+                        fontDescription.Family = "monospace";
+                    }
                 } else {
                     // use Monospace and Bold by default
                     fontDescription.Family = "monospace";
diff --git a/src/Frontend-GNOME/Views/Chats/ChatView.cs b/src/Frontend-GNOME/Views/Chats/ChatView.cs
index cdbec66..2917306 100644
--- a/src/Frontend-GNOME/Views/Chats/ChatView.cs
+++ b/src/Frontend-GNOME/Views/Chats/ChatView.cs
@@ -21,6 +21,7 @@
  */
 
 using System;
+using System.Text.RegularExpressions;
 using System.Threading;
 using System.Collections.Generic;
 using Smuxi.Common;
@@ -215,6 +216,13 @@ namespace Smuxi.Frontend.Gnome
             }
         }
 
+        // by default: no participants
+        public virtual IList<PersonModel> Participants {
+            get {
+                return new List<PersonModel>();
+            }
+        }
+
         public Gtk.Widget LabelWidget {
             get {
                 return _TabEventBox;
@@ -239,6 +247,12 @@ namespace Smuxi.Frontend.Gnome
             }
         }
 
+        protected Gtk.Menu TabMenu {
+            get {
+                return _TabMenu;
+            }
+        }
+
         protected ThemeSettings ThemeSettings {
             get {
                 return _ThemeSettings;
@@ -271,6 +285,7 @@ namespace Smuxi.Frontend.Gnome
             tv.SizeRequested += delegate {
                 AutoScroll();
             };
+            tv.PersonClicked += OnMessageTextViewPersonClicked;
             _OutputMessageTextView = tv;
 
             Gtk.ScrolledWindow sw = new Gtk.ScrolledWindow();
@@ -469,8 +484,6 @@ namespace Smuxi.Frontend.Gnome
 
             // REMOTING CALL
             SyncedName = _ChatModel.Name;
-            // REMOTING CALL
-            ProtocolManager = _ChatModel.ProtocolManager;
 
             if (!Frontend.IsLocalEngine && Frontend.UseLowBandwidthMode) {
                 // FIXME: set TabImage back to normal
@@ -747,6 +760,22 @@ namespace Smuxi.Frontend.Gnome
             popup.ShowAll();
         }
 
+        protected virtual void OnMessageTextViewPersonClicked(object sender, MessageTextViewPersonClickedEventArgs e)
+        {
+            Trace.Call(sender, e);
+
+            var entry = Frontend.MainWindow.Entry;
+            var text = entry.Text;
+            var match = Regex.Match(text, "^[^ ]+: ");
+            if (match.Success) {
+                // removing existing nick
+                text = text.Substring(match.Length);
+            }
+            text = String.Format("{0}: {1}", e.IdentityName, text);
+            entry.Text = text;
+            entry.HasFocus = true;
+        }
+
         protected virtual void OnLastSeenHighlightQueueExceptionEvent(object sender, TaskQueueExceptionEventArgs e)
         {
             Trace.Call(sender, e);
diff --git a/src/Frontend-GNOME/Views/Chats/GroupChatView.cs b/src/Frontend-GNOME/Views/Chats/GroupChatView.cs
index 521d336..be4df9c 100644
--- a/src/Frontend-GNOME/Views/Chats/GroupChatView.cs
+++ b/src/Frontend-GNOME/Views/Chats/GroupChatView.cs
@@ -39,7 +39,6 @@ namespace Smuxi.Frontend.Gnome
         public static Gdk.Pixbuf   IconPixbuf { get; private set; }
         private bool               NickColors { get; set; }
         private GroupChatModel     _GroupChatModel;
-        private Gtk.ScrolledWindow _PersonScrolledWindow;
         private Gtk.TreeView       _PersonTreeView;
         private Gtk.ListStore      _PersonListStore;
         private Gtk.Menu           _PersonMenu;
@@ -83,6 +82,20 @@ namespace Smuxi.Frontend.Gnome
             }
         }
 
+        public override IList<PersonModel> Participants {
+            get {
+                var participants = new List<PersonModel>();
+                if (_PersonListStore == null) {
+                    return participants;
+                }
+                foreach (object[] row in _PersonListStore) {
+                    var person = (PersonModel) row[0];
+                    participants.Add(person);
+                }
+                return participants;
+            }
+        }
+
         protected Gtk.TreeView PersonTreeView {
             get {
                 return _PersonTreeView;
@@ -124,7 +137,6 @@ namespace Smuxi.Frontend.Gnome
             _OutputHPaned = new Gtk.HPaned();
             
             Gtk.ScrolledWindow sw = new Gtk.ScrolledWindow();
-            _PersonScrolledWindow = sw;
             //sw.WidthRequest = 150;
             sw.HscrollbarPolicy = Gtk.PolicyType.Never;
             
@@ -154,6 +166,17 @@ namespace Smuxi.Frontend.Gnome
             _PersonListStore = liststore;
             
             tv.Model = liststore;
+            tv.SearchColumn = 0;
+            tv.SearchEqualFunc = (model, col, key, iter) => {
+                var person = (PersonModel) model.GetValue(iter, col);
+                // Ladies and gentlemen welcome to C
+                // 0 means it matched but 0 as bool is false. So if it matches
+                // we have to return false. Still not clear? true is false and
+                // false is true, weirdo! If you think this is retarded,
+                // yes it is.
+                return !person.IdentityName.StartsWith(key, StringComparison.InvariantCultureIgnoreCase);
+            };
+            tv.EnableSearch = true;
             tv.RowActivated += new Gtk.RowActivatedHandler(OnPersonsRowActivated);
             tv.FocusOutEvent += OnPersonTreeViewFocusOutEvent;
             
@@ -180,9 +203,7 @@ namespace Smuxi.Frontend.Gnome
             _TopicTextView.WrapMode = Gtk.WrapMode.WordChar;
             _TopicScrolledWindow = new Gtk.ScrolledWindow();
             _TopicScrolledWindow.ShadowType = Gtk.ShadowType.In;
-            // when using PolicyType.Never, it will try to grow but never shrinks!
-            _TopicScrolledWindow.HscrollbarPolicy = Gtk.PolicyType.Automatic;
-            _TopicScrolledWindow.VscrollbarPolicy = Gtk.PolicyType.Automatic;
+            _TopicScrolledWindow.HscrollbarPolicy = Gtk.PolicyType.Never;
             _TopicScrolledWindow.Add(_TopicTextView);
             // make sure the topic is invisible and remains by default and
             // visible when a topic gets set
@@ -191,14 +212,22 @@ namespace Smuxi.Frontend.Gnome
             _TopicScrolledWindow.NoShowAll = true;
             _TopicScrolledWindow.SizeRequested += delegate(object o, Gtk.SizeRequestedArgs args) {
                 // predict and set useful topic heigth
-                Pango.Layout layout = _TopicTextView.CreatePangoLayout("Test Topic");
                 int lineWidth, lineHeigth;
-                layout.GetPixelSize(out lineWidth, out lineHeigth);
+                using (var layout = _TopicTextView.CreatePangoLayout("Test Topic")) {
+                    layout.GetPixelSize(out lineWidth, out lineHeigth);
+                }
                 var lineSpacing = _TopicTextView.PixelsAboveLines +
                                   _TopicTextView.PixelsBelowLines;
-                var text = Topic != null ? Topic.ToString() : String.Empty;
-                // hardcoded to 2 lines for now
-                var newLines = text.Length > 0 ? 2 : 0;
+                var it = _TopicTextView.Buffer.StartIter;
+                int newLines = 1;
+                // move to end of next visual line
+                while (_TopicTextView.ForwardDisplayLineEnd(ref it)) {
+                    newLines++;
+                    // calling ForwardDisplayLineEnd repeatedly stays on the same position
+                    // therefor we move one cursor position further
+                    it.ForwardCursorPosition();
+                }
+                newLines = Math.Min(newLines, 3);
                 var bestSize = new Gtk.Requisition() {
                     Height = ((lineHeigth + lineSpacing) * newLines) + 2
                 };
@@ -220,6 +249,7 @@ namespace Smuxi.Frontend.Gnome
             // these callbacks for some reason and thus leaks :(
             // release ListStore.SetSortFunc() callback
             // gtk_list_store_finalize() -> _gtk_tree_data_list_header_free() -> destroy(user_data);
+            _TopicTextView.Dispose();
             _PersonListStore.Dispose();
             // release TreeViewColumn.SetCellDataFunc() callback
             // gtk_tree_view_column_finalize -> GtkTreeViewColumnCellInfo -> info->destroy(info->func_data)
@@ -295,6 +325,7 @@ namespace Smuxi.Frontend.Gnome
                 // BUG? TreeView doesn't seem to recognize existing values in the model?!?
                 // see: http://www.smuxi.org/issues/show/132
                 _PersonTreeView.Model = ls;
+                _PersonTreeView.SearchColumn = 0;
                 
                 /*
                 // predict and set useful width
@@ -311,6 +342,7 @@ namespace Smuxi.Frontend.Gnome
                 status += String.Format(" {0}", _("done."));
                 Frontend.MainWindow.Status = status;
             }
+            SyncedPersons = null;
 
             Topic = SyncedTopic;
 
@@ -393,90 +425,6 @@ namespace Smuxi.Frontend.Gnome
             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)
         {
             Trace.Call(config);
diff --git a/src/Frontend-GNOME/Views/Chats/PersonChatView.cs b/src/Frontend-GNOME/Views/Chats/PersonChatView.cs
index 68a3746..c1e2a89 100644
--- a/src/Frontend-GNOME/Views/Chats/PersonChatView.cs
+++ b/src/Frontend-GNOME/Views/Chats/PersonChatView.cs
@@ -27,6 +27,7 @@
  */
 
 using System;
+using System.Collections.Generic;
 using Smuxi.Engine;
 using Smuxi.Common;
 
@@ -62,6 +63,15 @@ namespace Smuxi.Frontend.Gnome
             ShowAll();
         }
 
+        public override IList<PersonModel> Participants
+        {
+            get {
+                var ret = new List<PersonModel>();
+                ret.Add(PersonChatModel.Person);
+                return ret;
+            }
+        }
+
         public override void Sync()
         {
             Trace.Call();
diff --git a/src/Frontend-GNOME/Views/Chats/ProtocolChatView.cs b/src/Frontend-GNOME/Views/Chats/ProtocolChatView.cs
index a15d7f7..d1cb278 100644
--- a/src/Frontend-GNOME/Views/Chats/ProtocolChatView.cs
+++ b/src/Frontend-GNOME/Views/Chats/ProtocolChatView.cs
@@ -1,7 +1,7 @@
 /*
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2005-2006, 2009-2011 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2005-2006, 2009-2013 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -49,6 +49,7 @@ namespace Smuxi.Frontend.Gnome
         public string Host { get; private set; }
         public int Port { get; private set; }
         public string NetworkID { get; private set; }
+        Gtk.ImageMenuItem  ReconnectItem { get; set; }
 
         protected override Gtk.Image DefaultTabImage {
             get {
@@ -81,6 +82,7 @@ namespace Smuxi.Frontend.Gnome
             NetworkWebsiteUrls.Add("GSDnet", "http://www.gsd-software.net/");
             NetworkWebsiteUrls.Add("ustream", "http://www.ustream.tv/");
             NetworkWebsiteUrls.Add("Infinity-IRC", "http://www.infinityirc.com/");
+            NetworkWebsiteUrls.Add("GeekShed", "http://www.geekshed.net/");
 
             // Twitter
             NetworkWebsiteUrls.Add("Twitter", "http://www.twitter.com/");
@@ -88,6 +90,12 @@ namespace Smuxi.Frontend.Gnome
             // XMPP
             NetworkWebsiteUrls.Add("talk.google.com", "http://www.google.com/talk/");
             NetworkWebsiteUrls.Add("chat.facebook.com", "http://www.facebook.com/");
+
+            // JabbR
+            NetworkWebsiteUrls.Add("jabbr.net", "http://jabbr.net/");
+
+            // Campfire
+            NetworkWebsiteUrls.Add("Campfire", "http://campfirenow.com");
         }
 
         public ProtocolChatView(ChatModel chat) : base(chat)
@@ -97,6 +105,13 @@ namespace Smuxi.Frontend.Gnome
             ProxySettings = new ProxySettings();
 
             Add(OutputScrolledWindow);
+
+            ReconnectItem = new Gtk.ImageMenuItem(_("Reconnect"));
+            ReconnectItem.Image = new Gtk.Image(Gtk.Stock.Refresh, Gtk.IconSize.Menu);
+            ReconnectItem.Activated += new EventHandler(OnTabMenuReconnectActivated);
+            TabMenu.Prepend(ReconnectItem);
+            TabMenu.ShowAll();
+
             ShowAll();
         }
 
@@ -197,8 +212,9 @@ namespace Smuxi.Frontend.Gnome
 
             string websiteUrl = null;
             lock (NetworkWebsiteUrls) {
-                if (!NetworkWebsiteUrls.TryGetValue(ID, out websiteUrl)) {
-                    // unknown network, nothing to download
+                if (!NetworkWebsiteUrls.TryGetValue(ID, out websiteUrl) &&
+                    !NetworkWebsiteUrls.TryGetValue(protocol, out websiteUrl)) {
+                    // unknown network and protocol, nothing to download
                     return;
                 }
                 // download in background so Sync() doesn't get slowed down
@@ -328,6 +344,28 @@ namespace Smuxi.Frontend.Gnome
             });
         }
 
+        protected virtual void OnTabMenuReconnectActivated(object sender, EventArgs e)
+        {
+            Trace.Call(sender, e);
+
+            try {
+                var pm = ProtocolManager;
+                if (pm == null) {
+                    return;
+                }
+
+                ThreadPool.QueueUserWorkItem(delegate {
+                    try {
+                        pm.Reconnect(Frontend.FrontendManager);
+                    } catch (Exception ex) {
+                        Frontend.ShowException(ex);
+                    }
+                });
+            } catch (Exception ex) {
+                Frontend.ShowException(ex);
+            }
+        }
+
         static bool ValidateCertificate(object sender,
                                         X509Certificate certificate,
                                         X509Chain chain,
diff --git a/src/Frontend-GNOME/Views/FilterListWidget.cs b/src/Frontend-GNOME/Views/FilterListWidget.cs
index 56617c3..e0dec63 100644
--- a/src/Frontend-GNOME/Views/FilterListWidget.cs
+++ b/src/Frontend-GNOME/Views/FilterListWidget.cs
@@ -28,9 +28,6 @@ namespace Smuxi.Frontend.Gnome
     [System.ComponentModel.ToolboxItem(true)]
     public partial class FilterListWidget : Gtk.Bin
     {
-#if LOG4NET
-        private static readonly log4net.ILog f_Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
-#endif
         Gtk.Window           f_Parent { get; set; }
         Gtk.ListStore        f_ListStore { get; set; }
         FilterListController f_Controller { get; set; }
@@ -223,11 +220,9 @@ namespace Smuxi.Frontend.Gnome
                 typeof(string) // tool tip
             );
             f_TreeView.Model = f_ListStore;
-            int i = 1;
             Gtk.TreeViewColumn column;
             Gtk.CellRendererText textCellr;
             Gtk.CellRendererCombo comboCellr;
-            Gtk.CellRendererToggle toggleCellr;
 
             comboCellr = new Gtk.CellRendererCombo();
             comboCellr.Model = f_ProtocolListStore;
@@ -263,7 +258,6 @@ namespace Smuxi.Frontend.Gnome
                     return;
                 }
                 FilterModel filter = (FilterModel) f_ListStore.GetValue(iter, 0);
-                int key = (int) f_ListStore.GetValue(iter, 1);
                 filter.ChatID = e.NewText;
                 f_ListStore.EmitRowChanged(new Gtk.TreePath(e.Path), iter);
                 OnChanged(EventArgs.Empty);
@@ -313,7 +307,6 @@ namespace Smuxi.Frontend.Gnome
                     return;
                 }
                 FilterModel filter = (FilterModel) f_ListStore.GetValue(iter, 0);
-                int key = (int) f_ListStore.GetValue(iter, 1);
                 filter.MessagePattern = e.NewText;
                 f_ListStore.EmitRowChanged(new Gtk.TreePath(e.Path), iter);
                 OnChanged(EventArgs.Empty);
@@ -348,7 +341,6 @@ namespace Smuxi.Frontend.Gnome
                 return;
             }
             FilterModel filter = (FilterModel) f_ListStore.GetValue(iter, 0);
-            int key = (int) f_ListStore.GetValue(iter, 1);
             filter.Protocol = e.NewText;
 
             f_ListStore.EmitRowChanged(new Gtk.TreePath(e.Path), iter);
@@ -376,7 +368,6 @@ namespace Smuxi.Frontend.Gnome
                 return;
             }
             FilterModel filter = (FilterModel) f_ListStore.GetValue(iter, 0);
-            int key = (int) f_ListStore.GetValue(iter, 1);
             // HACK: lame GTK+ 2.12 is not exposing the combo box neither
             // the iterator of the selected row inside the combo box thus
             // we have lookup the value in the list store using the text :/
@@ -416,7 +407,6 @@ namespace Smuxi.Frontend.Gnome
                 return;
             }
             FilterModel filter = (FilterModel) f_ListStore.GetValue(iter, 0);
-            int key = (int) f_ListStore.GetValue(iter, 1);
             // HACK: lame GTK+ 2.12 is not exposing the combo box neither
             // the iterator of the selected row inside the combo box thus
             // we have lookup the value in the list store using the text :/
diff --git a/src/Frontend-GNOME/Views/JoinWidget.cs b/src/Frontend-GNOME/Views/JoinWidget.cs
index 4e2e5a7..f78fbc5 100644
--- a/src/Frontend-GNOME/Views/JoinWidget.cs
+++ b/src/Frontend-GNOME/Views/JoinWidget.cs
@@ -1,6 +1,6 @@
 // Smuxi - Smart MUltipleXed Irc
 //
-// Copyright (c) 2012 Mirco Bauer <meebey at meebey.net>
+// Copyright (c) 2012-2013 Mirco Bauer <meebey at meebey.net>
 //
 // Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
 //
@@ -21,15 +21,21 @@ using System;
 using System.Collections.Generic;
 using Smuxi.Common;
 using Smuxi.Engine;
+using System.Runtime.InteropServices;
 
 namespace Smuxi.Frontend.Gnome
 {
     [System.ComponentModel.ToolboxItem(true)]
     public partial class JoinWidget : Gtk.Bin
     {
+#if LOG4NET
+        private static readonly log4net.ILog f_Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+#endif
+        private const string ActiveNetworkConfigKey = "GNOME/JoinBar/ActiveNetwork";
+
         public EventHandler<EventArgs> Activated;
 
-        public bool HasFocus {
+        public new bool HasFocus {
             get {
                 return f_ChatEntry.HasFocus;
             }
@@ -38,13 +44,70 @@ namespace Smuxi.Frontend.Gnome
             }
         }
 
+        public string ActiveNetwork {
+            get {
+                return f_NetworkComboBox.ActiveText;
+            }
+            set {
+                var store = (Gtk.ListStore) f_NetworkComboBox.Model;
+                var idx = 0;
+                foreach (object[] row in store) {
+                    if ((string) row[0] == value) {
+                        f_NetworkComboBox.Active = idx;
+                        break;
+                    }
+                    idx++;
+                }
+            }
+        }
+
+        [DllImport("libgtk-win32-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
+        static extern void gtk_entry_set_icon_from_pixbuf(IntPtr entry, int pos, IntPtr pixbuf);
+
+        // Since: 2.16
+        // void gtk_entry_set_icon_tooltip_text(GtkEntry *entry, GtkEntryIconPosition icon_pos, const gchar *tooltip)
+        [DllImport("libgtk-win32-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
+        static extern void gtk_entry_set_icon_tooltip_text(IntPtr entry, int pos, IntPtr tooltip);
+
+        // Since: 3.2
+        // void gtk_entry_set_placeholder_text (GtkEntry *entry, const gchar *text)
+        [DllImport("libgtk-win32-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
+        static extern void gtk_entry_set_placeholder_text(IntPtr entry, string text);
+
         public JoinWidget()
         {
             Build();
 
+            try {
+                gtk_entry_set_icon_from_pixbuf(f_ChatEntry.Handle, 0, GroupChatView.IconPixbuf.Handle);
+            } catch (Exception ex) {
+#if LOG4NET
+                f_Logger.Error("JoinWidget(): gtk_entry_set_icon_from_pixbuf() failed!", ex);
+#endif
+            }
+            try {
+                var text = _("Enter which chat to join");
+                IntPtr textPtr = GLib.Marshaller.StringToPtrGStrdup(text);
+                gtk_entry_set_icon_tooltip_text(f_ChatEntry.Handle, 0, textPtr);
+                GLib.Marshaller.Free(textPtr);
+            } catch (Exception ex) {
+#if LOG4NET
+                f_Logger.Error("JoinWidget(): gtk_entry_set_icon_tooltip_text() failed!", ex);
+#endif
+            }
+            try {
+                //gtk_entry_set_placeholder_text(f_ChatEntry.Handle, "Enter chat name...");
+            } catch (Exception ex) {
+#if LOG4NET
+                f_Logger.Error("JoinWidget(): gtk_entry_set_placeholder_text() failed!", ex);
+#endif
+            }
+
             f_ChatEntry.Activated += delegate {
                 OnActivated(EventArgs.Empty);
             };
+            f_ChatEntry.KeyPressEvent += OnChatEntryKeyPressEvent;
+
             f_JoinButton.Clicked += delegate {
                 OnActivated(EventArgs.Empty);
             };
@@ -72,7 +135,16 @@ namespace Smuxi.Frontend.Gnome
             }
             store.SetSortColumnId(0, Gtk.SortType.Ascending);
             f_NetworkComboBox.Model = store;
-            f_NetworkComboBox.Active = 0;
+            var activeNetwork = (string) Frontend.FrontendConfig[ActiveNetworkConfigKey];
+            if (String.IsNullOrEmpty(activeNetwork)) {
+                f_NetworkComboBox.Active = 0;
+            } else {
+                ActiveNetwork = activeNetwork;
+            }
+            f_NetworkComboBox.Changed += (sender, e) => {
+                Frontend.FrontendConfig[ActiveNetworkConfigKey] = ActiveNetwork;
+                Frontend.FrontendConfig.Save();
+            };
         }
 
         public void ApplyConfig(UserConfig config)
@@ -105,5 +177,31 @@ namespace Smuxi.Frontend.Gnome
                 Activated(this, e);
             }
         }
+
+        [GLib.ConnectBefore]
+        protected void OnChatEntryKeyPressEvent(object o, Gtk.KeyPressEventArgs e)
+        {
+            var key = e.Event.Key;
+            if ((e.Event.State & Gdk.ModifierType.ControlMask) != 0) {
+                switch (key) {
+                    case Gdk.Key.x:
+                    case Gdk.Key.X:
+                        // ctrl + x is pressed
+                        e.RetVal = true;
+                        if (f_NetworkComboBox.Active ==
+                            f_NetworkComboBox.Model.IterNChildren() - 1) {
+                            f_NetworkComboBox.Active = 0;
+                        } else {
+                            f_NetworkComboBox.Active++;
+                        }
+                        break;
+                }
+            }
+        }
+
+        private static string _(string msg)
+        {
+            return Mono.Unix.Catalog.GetString(msg);
+        }
     }
 }
diff --git a/src/Frontend-GNOME/Views/MenuWidget.cs b/src/Frontend-GNOME/Views/MenuWidget.cs
new file mode 100644
index 0000000..8486a52
--- /dev/null
+++ b/src/Frontend-GNOME/Views/MenuWidget.cs
@@ -0,0 +1,531 @@
+// Smuxi - Smart MUltipleXed Irc
+//
+// Copyright (c) 2012 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 SysDiag = System.Diagnostics;
+using IgeMacIntegration;
+using Smuxi.Common;
+using Smuxi.Engine;
+
+namespace Smuxi.Frontend.Gnome
+{
+    [System.ComponentModel.ToolboxItem(true)]
+    public partial class MenuWidget : Gtk.Bin
+    {
+#if LOG4NET
+        private static readonly log4net.ILog f_Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+#endif
+        new Gtk.Window Parent { get; set; }
+        MainWindow MainWindow { get; set; }
+        public JoinWidget JoinWidget { get; private set; }
+        ChatViewManager ChatViewManager { get; set; }
+
+        public bool CaretMode {
+            get {
+                return f_CaretModeAction.Active;
+            }
+        }
+
+        public Gtk.MenuBar MenuBar {
+            get {
+                return f_MenuBar;
+            }
+        }
+
+        public Gtk.ToggleAction ShowMenubarAction {
+            get {
+                return f_ShowMenubarAction;
+            }
+        }
+
+        public Gtk.Action OpenLogAction {
+            get {
+                return f_OpenLogAction;
+            }
+        }
+
+        public Gtk.Action CloseChatAction {
+            get {
+                return f_CloseChatAction;
+            }
+        }
+
+        public Gtk.Action FindGroupChatAction {
+            get {
+                return f_FindGroupChatAction;
+            }
+        }
+
+        public MenuWidget(Gtk.Window parent, ChatViewManager chatViewManager)
+        {
+            if (parent == null) {
+                throw new ArgumentNullException("parent");
+            }
+            if (chatViewManager == null) {
+                throw new ArgumentNullException("chatViewManager");
+            }
+
+            Parent = parent;
+            MainWindow = parent as MainWindow;
+            ChatViewManager = chatViewManager;
+
+            Build();
+
+            // Smuxi Menu
+            f_QuitAction.IconName = Gtk.Stock.Quit;
+
+            // Chat
+            f_JoinChatAction.IconName = Gtk.Stock.Open;
+            f_FindGroupChatAction.IconName = Gtk.Stock.Find;
+            f_OpenLogAction.IconName = Gtk.Stock.Open;
+            f_CloseChatAction.IconName = Gtk.Stock.Close;
+
+            // Engine
+            f_AddRemoteEngineAction.IconName = Gtk.Stock.Add;
+            f_SwitchRemoteEngineAction.IconName = Gtk.Stock.Refresh;
+
+            // Toolbar
+            f_ConnectToolAction.IconName = Gtk.Stock.Network;
+            f_OpenLogToolAction.IconName = Gtk.Stock.Open;
+            f_FindGroupChatToolAction.IconName = Gtk.Stock.Find;
+
+            f_MenuBar.ShowAll();
+            f_MenuBar.NoShowAll = true;
+            f_MenuBar.Visible = (bool) Frontend.FrontendConfig["ShowMenuBar"];
+
+            JoinWidget = new JoinWidget();
+            JoinWidget.NoShowAll = true;
+            JoinWidget.Visible = (bool) Frontend.FrontendConfig["ShowQuickJoin"];
+            JoinWidget.Activated += OnJoinWidgetActivated;
+
+            var joinToolItem = new Gtk.ToolItem();
+            joinToolItem.Add(JoinWidget);
+            f_JoinToolbar.Add(joinToolItem);
+            f_JoinToolbar.ShowAll();
+
+            f_ShowMenubarAction.Active = (bool) Frontend.FrontendConfig["ShowMenuBar"];
+            f_ShowStatusbarAction.Active = (bool) Frontend.FrontendConfig["ShowStatusBar"];
+            f_ShowJoinBarAction.Active = JoinWidget.Visible;
+
+            if (Frontend.IsMacOSX) {
+                // Smuxi menu is already shown as app menu
+                f_SmuxiAction.Visible = false;
+                // About item is already shown in app menu
+                f_AboutAction.Visible = false;
+
+                IgeMacMenu.GlobalKeyHandlerEnabled = true;
+                IgeMacMenu.MenuBar = f_MenuBar;
+                f_ShowMenubarAction.Active = false;
+
+                var appGroup = IgeMacMenu.AddAppMenuGroup();
+                appGroup.AddMenuItem(
+                    (Gtk.MenuItem) f_AboutAction.CreateMenuItem(),
+                    _("About Smuxi")
+                );
+                var prefItem = (Gtk.MenuItem) f_PreferencesAction.CreateMenuItem();
+                // TODO: add cmd+, accelerator
+                appGroup.AddMenuItem(prefItem, _("Preferences"));
+                IgeMacMenu.QuitMenuItem = (Gtk.MenuItem)
+                    f_QuitAction.CreateMenuItem();
+            }
+        }
+
+        protected void OnAboutActionActivated(object sender, EventArgs e)
+        {
+            Trace.Call(sender, e);
+            
+            try {
+                var dialog = new AboutDialog(Parent);
+                dialog.Run();
+                dialog.Destroy();
+            } catch (Exception ex) {
+                Frontend.ShowException(Parent, ex);
+            }
+        }
+
+        protected void OnPreferencesActionActivated(object sender, EventArgs e)
+        {
+            Trace.Call(sender, e);
+            
+            try {
+                var dialog = new PreferencesDialog(Parent);
+                dialog.Show();
+            } catch (Exception ex) {
+                Frontend.ShowException(Parent, ex);
+            }
+        }
+
+        protected void OnQuitActionActivated(object sender, EventArgs e)
+        {
+            Trace.Call(sender, e);
+
+            try {
+                Frontend.Quit();
+            } catch (Exception ex) {
+                Frontend.ShowException(Parent, ex);
+            }
+        }
+
+        protected void OnConnectActionActivated(object sender, EventArgs e)
+        {
+            Trace.Call(sender, e);
+            
+            try {
+                var dialog = new QuickConnectDialog(Parent);
+                dialog.Load();
+                int res = dialog.Run();
+                var server = dialog.Server;
+                dialog.Destroy();
+                if (res != (int) Gtk.ResponseType.Ok) {
+                    return;
+                }
+                if (server == null) {
+#if LOG4NET
+                    f_Logger.Error("OnServerConnectButtonClicked(): server is null!");
+                    return;
+#endif
+                }
+                
+                // do connect as background task as it might take a while
+                ThreadPool.QueueUserWorkItem(delegate {
+                    try {
+                        Frontend.Session.Connect(server, Frontend.FrontendManager);
+                    } catch (Exception ex) {
+                        Frontend.ShowException(Parent, ex);
+                    }
+                });
+            } catch (Exception ex) {
+                Frontend.ShowException(Parent, ex);
+            }
+        }
+
+        protected void OnAddServerActionActivated(object sender, EventArgs e)
+        {
+            Trace.Call(sender, e);
+            
+            ServerDialog dialog = null;
+            try {
+                var controller = new ServerListController(Frontend.UserConfig);
+                dialog = new ServerDialog(Parent, null,
+                                          Frontend.Session.GetSupportedProtocols(),
+                                          controller.GetNetworks());
+                int res = dialog.Run();
+                ServerModel server = dialog.GetServer();
+                if (res != (int) Gtk.ResponseType.Ok) {
+                    return;
+                }
+                
+                controller.AddServer(server);
+                controller.Save();
+            } catch (InvalidOperationException ex) {
+                Frontend.ShowError(Parent, _("Unable to add server: "), ex);
+            } catch (Exception ex) {
+                Frontend.ShowException(Parent, ex);
+            } finally {
+                if (dialog != null) {
+                    dialog.Destroy();
+                }
+            }
+        }
+
+        protected void OnManageServerActionActivated(object sender, EventArgs e)
+        {
+            Trace.Call(sender, e);
+            
+            try {
+                var dialog = new PreferencesDialog(Parent);
+                dialog.CurrentPage = PreferencesDialog.Page.Servers;
+            } catch (Exception ex) {
+                Frontend.ShowException(Parent, ex);
+            }
+        }
+
+        protected void OnJoinChatActionActivated(object sender, EventArgs e)
+        {
+            Trace.Call(sender, e);
+
+            try {
+                if (!f_ShowJoinBarAction.Active) {
+                    f_ShowJoinBarAction.Activate();
+                }
+                JoinWidget.HasFocus = true;
+            } catch (Exception ex) {
+                Frontend.ShowException(Parent, ex);
+            }
+        }
+
+        protected void OnFindGroupChatActionActivated(object sender, EventArgs e)
+        {
+            Trace.Call(sender, e);
+
+            try {
+                Frontend.OpenFindGroupChatWindow();
+            } catch (Exception ex) {
+                Frontend.ShowException(Parent, ex);
+            }
+        }
+
+        protected void OnClearAllActivityActionActivated(object sender, EventArgs e)
+        {
+            Trace.Call(sender, e);
+            
+            try {
+                ChatViewManager.ClearAllActivity();
+            } catch (Exception ex) {
+                Frontend.ShowException(Parent, ex);
+            }
+        }
+
+        protected void OnNextChatActionActivated(object sender, EventArgs e)
+        {
+            Trace.Call(sender, e);
+            
+            try {
+                ChatViewManager.CurrentChatNumber++;
+            } catch (Exception ex) {
+                Frontend.ShowException(Parent, ex);
+            }
+        }
+
+        protected void OnPreviousChatActionActivated(object sender, EventArgs e)
+        {
+            Trace.Call(sender, e);
+            
+            try {
+                ChatViewManager.CurrentChatNumber--;
+            } catch (Exception ex) {
+                Frontend.ShowException(Parent, ex);
+            }
+        }
+
+        protected void OnOpenLogActionActivated(object sender, EventArgs e)
+        {
+            Trace.Call(sender, e);
+
+            try {
+                ThreadPool.QueueUserWorkItem(delegate {
+                    try {
+                        SysDiag.Process.Start(
+                            ChatViewManager.CurrentChatView.ChatModel.LogFile
+                        );
+                    } catch (Exception ex) {
+                        Frontend.ShowError(Parent, ex);
+                    }
+                });
+            } catch (Exception ex) {
+                Frontend.ShowException(Parent, ex);
+            }
+        }
+
+        protected void OnCloseChatActionActivated(object sender, EventArgs e)
+        {
+            Trace.Call(sender, e);
+            
+            try {
+                ChatViewManager.CurrentChatView.Close();
+                if (Frontend.IsMacOSX && ChatViewManager.Chats.Count == 1) {
+                    ChatViewManager.Minimize();
+                }
+            } catch (Exception ex) {
+                Frontend.ShowException(Parent, ex);
+            }
+        }
+
+        protected void OnUseLocalEngineActionActivated(object sender, EventArgs e)
+        {
+            Trace.Call(sender, e);
+            
+            try {
+                var dialog = new Gtk.MessageDialog(
+                    Parent, Gtk.DialogFlags.Modal,
+                    Gtk.MessageType.Warning, Gtk.ButtonsType.YesNo,
+                    _("Switching to local engine will disconnect you from the current engine!\n"+
+                      "Are you sure you want to do this?")
+                );
+                int result = dialog.Run();
+                dialog.Destroy();
+                if ((Gtk.ResponseType)result == Gtk.ResponseType.Yes) {
+                    Frontend.DisconnectEngineFromGUI();
+                    Frontend.InitLocalEngine();
+                    Frontend.ConnectEngineToGUI();
+                }
+            } catch (Exception ex) {
+                Frontend.ShowException(Parent, ex);
+            }
+        }
+
+        protected void OnAddRemoteEngineActionActivated(object sender, EventArgs e)
+        {
+            Trace.Call(sender, e);
+            
+            try {
+                var assistant = new EngineAssistant(
+                    Parent,
+                    Frontend.FrontendConfig
+                );
+                assistant.Cancel += delegate {
+                    assistant.Destroy();
+                };
+                assistant.Close += delegate {
+                    assistant.Destroy();
+                };
+                assistant.ShowAll();
+            } catch (Exception ex) {
+                Frontend.ShowException(Parent, ex);
+            }
+        }
+
+        protected void OnSwitchRemoteEngineActionActivated(object sender, EventArgs e)
+        {
+            Trace.Call(sender, e);
+            
+            try {
+                var dialog = new Gtk.MessageDialog(
+                    Parent, Gtk.DialogFlags.Modal,
+                    Gtk.MessageType.Warning, Gtk.ButtonsType.YesNo,
+                    _("Switching the remote engine will disconnect you from the current engine!\n"+
+                      "Are you sure you want to do this?")
+                );
+                int result = dialog.Run();
+                dialog.Destroy();
+                if ((Gtk.ResponseType)result == Gtk.ResponseType.Yes) {
+                    Frontend.DisconnectEngineFromGUI();
+                    Frontend.ShowEngineManagerDialog();
+                }
+            } catch (Exception ex) {
+                Frontend.ShowException(Parent, ex);
+            }
+        }
+
+        protected void OnCaretModeActionToggled(object sender, EventArgs e)
+        {
+            Trace.Call(sender, e);
+            
+            try {
+                var caretMode = f_CaretModeAction.Active;
+
+                foreach (var chatView in ChatViewManager.Chats) {
+                    chatView.OutputMessageTextView.CursorVisible = caretMode;
+                }
+                
+                if (caretMode) {
+                    ChatViewManager.CurrentChatView.OutputMessageTextView.HasFocus = true;
+                } else {
+                    MainWindow.Entry.HasFocus = true;
+                }
+            } catch (Exception ex) {
+                Frontend.ShowException(Parent, ex);
+            }
+        }
+
+        protected void OnBrowseModeActionToggled(object sender, EventArgs e)
+        {
+            Trace.Call(sender, e);
+
+            try {
+                MainWindow.Notebook.IsBrowseModeEnabled = !MainWindow.Notebook.IsBrowseModeEnabled;
+            } catch (Exception ex) {
+                Frontend.ShowException(Parent, ex);
+            }
+        }
+
+        protected void OnShowMenubarActionToggled(object sender, EventArgs e)
+        {
+            Trace.Call(sender, e);
+
+            try {
+                var active = f_ShowMenubarAction.Active;
+                f_MenuBar.Visible = active;
+                Frontend.FrontendConfig["ShowMenuBar"] = active;
+                Frontend.FrontendConfig.Save();
+            } catch (Exception ex) {
+                Frontend.ShowException(Parent, ex);
+            }
+        }
+
+        protected void OnShowStatusbarActionToggled(object sender, EventArgs e)
+        {
+            Trace.Call(sender, e);
+
+            try {
+                var active = f_ShowStatusbarAction.Active;
+                MainWindow.ShowStatusbar = active;
+                Frontend.FrontendConfig["ShowStatusBar"] = active;
+                Frontend.FrontendConfig.Save();
+            } catch (Exception ex) {
+                Frontend.ShowException(Parent, ex);
+            }
+        }
+
+        protected virtual void OnJoinWidgetActivated(object sender, EventArgs e)
+        {
+            Trace.Call(sender, e);
+
+            try {
+                var chatLink = JoinWidget.GetChatLink();
+                Frontend.OpenChatLink(chatLink);
+                JoinWidget.Clear();
+            } catch (Exception ex) {
+                Frontend.ShowException(Parent, ex);
+            }
+        }
+
+        protected void OnShowJoinBarActionToggled(object sender, EventArgs e)
+        {
+            Trace.Call(sender, e);
+
+            try {
+                var active = f_ShowJoinBarAction.Active;
+                JoinWidget.Visible = active;
+                Frontend.FrontendConfig["ShowQuickJoin"] = active;
+                Frontend.FrontendConfig.Save();
+            } catch (Exception ex) {
+                Frontend.ShowException(Parent, ex);
+            }
+        }
+
+        protected void OnFullscreenActionActivated(object sender, EventArgs e)
+        {
+            Trace.Call(sender, e);
+
+            try {
+                MainWindow.IsFullscreen = !MainWindow.IsFullscreen;
+            } catch (Exception ex) {
+                Frontend.ShowException(Parent, ex);
+            }
+        }
+
+        protected void OnWebsiteActionActivated(object sender, EventArgs e)
+        {
+            Trace.Call(sender, e);
+
+            try {
+                Frontend.OpenLink(new Uri("http://www.smuxi.org/"));
+            } catch (Exception ex) {
+                Frontend.ShowException(Parent, ex);
+            }
+        }
+
+        private static string _(string msg)
+        {
+            return Mono.Unix.Catalog.GetString(msg);
+        }
+    }
+}
diff --git a/src/Frontend-GNOME/Views/MessageTextView.cs b/src/Frontend-GNOME/Views/MessageTextView.cs
index 1f4edfb..c821c01 100644
--- a/src/Frontend-GNOME/Views/MessageTextView.cs
+++ b/src/Frontend-GNOME/Views/MessageTextView.cs
@@ -46,7 +46,6 @@ namespace Smuxi.Frontend.Gnome
         private bool         _ShowMarkerline;
         private bool         _AtLinkTag;
         private Uri          _ActiveLink;
-        private UserConfig   _Config;
         private ThemeSettings _ThemeSettings;
         private Gdk.Color    _MarkerlineColor = new Gdk.Color(255, 0, 0);
         private int          _MarkerlineBufferPosition;
@@ -58,8 +57,12 @@ namespace Smuxi.Frontend.Gnome
         Gtk.TextTag LinkTag { get; set; }
         Gtk.TextTag EventTag { get; set; }
 
+        Gtk.TextTag PersonTag { get; set; }
+        bool AtPersonTag { get; set; }
+
         public event MessageTextViewMessageAddedEventHandler       MessageAdded;
         public event MessageTextViewMessageHighlightedEventHandler MessageHighlighted;
+        public event EventHandler<MessageTextViewPersonClickedEventArgs> PersonClicked;
         
         public bool ShowTimestamps {
             get {
@@ -248,6 +251,7 @@ namespace Smuxi.Frontend.Gnome
             var startMark = new Gtk.TextMark(null, true);
             buffer.AddMark(startMark, iter);
 
+
             var senderPrefixWidth = GetSenderPrefixWidth(msg);
             Gtk.TextTag indentTag = null;
             if (senderPrefixWidth != 0) {
@@ -263,22 +267,20 @@ namespace Smuxi.Frontend.Gnome
                 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");
+                    if (span.Days > 0) {
+                        var dayLine = new MessageBuilder().
+                            AppendEventPrefix();
+                        if (span.Days > 1) {
+                            dayLine.AppendText(_("Day changed from {0} to {1}"),
+                                               lastMsgTimeStamp.ToShortDateString(),
+                                               msgTimeStamp.ToShortDateString());
+                        } else {
+                            dayLine.AppendText(_("Day changed to {0}"),
+                                               msgTimeStamp.ToLongDateString());
+                        }
+                        dayLine.AppendText("\n");
+                        var dayLineMsg = dayLine.ToMessage().ToString();
+                        Buffer.InsertWithTags(ref iter, dayLineMsg, EventTag);
                     }
                 }
                 
@@ -303,6 +305,9 @@ namespace Smuxi.Frontend.Gnome
                 }
             }
 
+            var msgStartMark = new Gtk.TextMark(null, true);
+            buffer.AddMark(msgStartMark, iter);
+
             bool hasHighlight = false;
             foreach (MessagePartModel msgPart in msg.MessageParts) {
                 // supposed to be used only in a ChatView
@@ -397,6 +402,21 @@ namespace Smuxi.Frontend.Gnome
             if (indentTag != null) {
                 buffer.ApplyTag(indentTag, startIter, iter);
             }
+            var nick = msg.GetNick();
+            if (nick != null) {
+                // TODO: re-use the same person tag for the same nick
+                var personTag = new PersonTag(nick, nick);
+                personTag.TextEvent += OnPersonTagTextEvent;
+                _MessageTextTagTable.Add(personTag);
+
+                var msgStartIter = buffer.GetIterAtMark(msgStartMark);
+                var nickEndIter = msgStartIter;
+                nickEndIter.ForwardChars(nick.Length + 2);
+                buffer.ApplyTag(PersonTag, msgStartIter, nickEndIter);
+                buffer.ApplyTag(personTag, msgStartIter, nickEndIter);
+            }
+            buffer.DeleteMark(startMark);
+            buffer.DeleteMark(msgStartMark);
             if (addLinebreak) {
                 buffer.Insert(ref iter, "\n");
             }
@@ -443,6 +463,8 @@ namespace Smuxi.Frontend.Gnome
             _MessageTextTagTable.Foreach(tag => {
                 if (tag is LinkTag) {
                     tag.TextEvent -= OnLinkTagTextEvent;
+                } else if (tag is PersonTag) {
+                    tag.TextEvent -= OnPersonTagTextEvent;
                 }
             });
             _MessageTextTagTable.Dispose();
@@ -493,6 +515,10 @@ namespace Smuxi.Frontend.Gnome
             LinkTag = tt;
             ttt.Add(tt);
 
+            tt = new Gtk.TextTag("person");
+            PersonTag = tt;
+            ttt.Add(tt);
+
             return ttt;
         }
 
@@ -512,11 +538,16 @@ namespace Smuxi.Frontend.Gnome
             // get TextIter with buffer position
             Gtk.TextIter iter = GetIterAtLocation(bufferX, bufferY);
             bool atUrlTag = false;
+            bool atPersonTag = false;
             foreach (Gtk.TextTag tag in iter.Tags) {
                 if (tag.Name == "link") {
                     atUrlTag = true;
                     break;
                 }
+                if (tag.Name == "person") {
+                    atPersonTag = true;
+                    break;
+                }
             }
             
             Gdk.Window window = GetWindow(Gtk.TextWindowType.Text); 
@@ -536,6 +567,21 @@ namespace Smuxi.Frontend.Gnome
                     _ActiveLink = null;
                 }
             }
+            if (atPersonTag != AtPersonTag) {
+                AtPersonTag = atPersonTag;
+                
+                if (atPersonTag) {
+#if LOG4NET
+                    _Logger.Debug("OnMotionNotifyEvent(): at person tag");
+#endif
+                    window.Cursor = _LinkCursor;
+                } else {
+#if LOG4NET
+                    _Logger.Debug("OnMotionNotifyEvent(): not at person tag");
+#endif
+                    window.Cursor = _NormalCursor;
+                }
+            }
         }
         
         protected virtual void OnLinkTagTextEvent(object sender, Gtk.TextEventArgs e)
@@ -565,7 +611,37 @@ namespace Smuxi.Frontend.Gnome
                 return;
             }
 
-            OpenLink(_ActiveLink);
+            Frontend.OpenLink(_ActiveLink);
+        }
+
+        protected virtual void OnPersonTagTextEvent(object sender, Gtk.TextEventArgs e)
+        {
+            // logging noise
+            //Trace.Call(sender, e);
+            
+            // if something in the textview is selected, bail out
+            if (HasTextViewSelection) {
+#if LOG4NET
+                _Logger.Debug("OnPersonTagTextEvent(): active selection present, bailing out...");
+#endif
+                return;
+            }
+            
+            var tag = (PersonTag) sender;
+            if (tag == null) {
+                return;
+            }
+
+            if (e.Event.Type != Gdk.EventType.ButtonPress) {
+                return;
+            }
+
+            if (PersonClicked != null) {
+                PersonClicked(
+                    this,
+                    new MessageTextViewPersonClickedEventArgs(tag.IdentityName)
+                );
+            }
         }
 
         protected virtual void OnPopulatePopup(object sender, Gtk.PopulatePopupArgs e)
@@ -585,7 +661,7 @@ namespace Smuxi.Frontend.Gnome
             Gtk.ImageMenuItem open_item = new Gtk.ImageMenuItem(Gtk.Stock.Open, null);
             open_item.Activated += delegate {
                 if (_ActiveLink != null) {
-                    OpenLink(_ActiveLink);
+                    Frontend.OpenLink(_ActiveLink);
                 }
             };
             popup.Append(open_item);
@@ -604,36 +680,6 @@ namespace Smuxi.Frontend.Gnome
             popup.ShowAll();
         }
 
-        private void OpenLink(Uri link)
-        {
-            Trace.Call(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 {
-                    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: '" + url + "' failed", ex);
-#endif
-                }
-            });
-        }
-        
         private string GetTextTagName(TextColor fgColor, TextColor bgColor)
         {
              string hexcode;
@@ -698,14 +744,45 @@ namespace Smuxi.Frontend.Gnome
                 return;
             }
 
-            if (Buffer.LineCount > _BufferLines) {
-                Gtk.TextIter start_iter = Buffer.StartIter;
+            var buffer = Buffer;
+            if (buffer.LineCount > _BufferLines) {
+                Gtk.TextIter start_iter = buffer.StartIter;
                 // TODO: maybe we should delete chunks instead of each line
-                Gtk.TextIter end_iter = Buffer.GetIterAtLine(Buffer.LineCount -
+                Gtk.TextIter end_iter = buffer.GetIterAtLine(buffer.LineCount -
                                                              _BufferLines);
                 int offset = end_iter.Offset;
-                Buffer.Delete(ref start_iter, ref end_iter);
-                // TODO: remove unnamed tags from TextTagTable
+
+                // release tags
+                var toggled_tags = new List<Gtk.TextTag>(16);
+                var start_tags = start_iter.GetToggledTags(true);
+                toggled_tags.AddRange(start_tags);
+
+                var tag_iter = start_iter;
+                while (tag_iter.ForwardToTagToggle(null)) {
+                    if (tag_iter.Compare(end_iter) >= 0) {
+                        // tag is after line end
+                        break;
+                    }
+                    var iter_tags = tag_iter.GetToggledTags(true);
+                    toggled_tags.AddRange(iter_tags);
+                }
+
+                foreach (var tag in toggled_tags) {
+                    // don't remove color tags as they are shared wither other lines
+                    var tagName = tag.Name;
+                    if (tagName != null &&
+                        (tagName.StartsWith("fg_color:") ||
+                         tagName.StartsWith("bg_color:"))) {
+                        continue;
+                    }
+                    if (tag.IndentSet || tag is LinkTag) {
+                        buffer.RemoveTag(tag, start_iter, end_iter);
+                        _MessageTextTagTable.Remove(tag);
+                        tag.Dispose();
+                    }
+                }
+
+                buffer.Delete(ref start_iter, ref end_iter);
 
                 // update markerline offset if present
                 if (_MarkerlineBufferPosition != 0) {
@@ -768,15 +845,15 @@ namespace Smuxi.Frontend.Gnome
 
         int GetPangoWidth(string text, bool isMarkup)
         {
-            Pango.Layout layout;
-            if (isMarkup) {
-                layout = CreatePangoLayout(null);
-                layout.SetMarkup(text);
-            } else {
-                layout = CreatePangoLayout(text);
-            }
             int width, heigth;
-            layout.GetPixelSize(out width, out heigth);
+            using (var layout = CreatePangoLayout(null)) {
+                if (isMarkup) {
+                    layout.SetMarkup(text);
+                } else {
+                    layout.SetText(text);
+                }
+                layout.GetPixelSize(out width, out heigth);
+            }
             return width;
         }
 
@@ -821,4 +898,14 @@ namespace Smuxi.Frontend.Gnome
             f_Message = message;
         }
     }
+
+    public class MessageTextViewPersonClickedEventArgs : EventArgs
+    {
+        public string IdentityName { get; private set; }
+        
+        public MessageTextViewPersonClickedEventArgs(string identityName)
+        {
+            IdentityName = identityName;
+        }
+    }
 }
diff --git a/src/Frontend-GNOME/Views/ServerDialog.cs b/src/Frontend-GNOME/Views/ServerDialog.cs
index 285e7dd..975e8a7 100644
--- a/src/Frontend-GNOME/Views/ServerDialog.cs
+++ b/src/Frontend-GNOME/Views/ServerDialog.cs
@@ -31,7 +31,8 @@ namespace Smuxi.Frontend.Gnome
     {
         public ServerDialog(Gtk.Window parent, ServerModel server,
                             IList<string> supportedProtocols,
-                            IList<string> networks)
+                            IList<string> networks) :
+                       base(null, parent, Gtk.DialogFlags.DestroyWithParent)
         {
             Trace.Call(parent, server, supportedProtocols, networks);
 
@@ -53,7 +54,7 @@ namespace Smuxi.Frontend.Gnome
             if (server != null) {
                 try {
                     f_Widget.Load(server);
-                } catch (Exception ex) {
+                } catch (Exception) {
                     Destroy();
                     throw;
                 }
diff --git a/src/Frontend-GNOME/Views/ServerWidget.cs b/src/Frontend-GNOME/Views/ServerWidget.cs
index 3336562..2d40a85 100644
--- a/src/Frontend-GNOME/Views/ServerWidget.cs
+++ b/src/Frontend-GNOME/Views/ServerWidget.cs
@@ -32,6 +32,8 @@ namespace Smuxi.Frontend.Gnome
     {
         Gtk.ListStore f_NetworkListStore;
 
+        string ServerID { get; set; }
+
         public Gtk.Entry HostnameEntry {
             get {
                 return f_HostnameEntry;
@@ -80,6 +82,18 @@ namespace Smuxi.Frontend.Gnome
             }
         }
 
+        public bool SupportUseEncryption {
+            set {
+                f_UseEncryptionCheckButton.Sensitive = value;
+                f_ValidateServerCertificateCheckButton.Sensitive = value;
+                if (!value) {
+                    f_UseEncryptionCheckButton.Active = false;
+                    f_ValidateServerCertificateCheckButton.Active = false;
+                }
+                CheckUseEncryptionCheckButton();
+            }
+        }
+
         public ServerWidget()
         {
             Trace.Call();
@@ -112,11 +126,8 @@ namespace Smuxi.Frontend.Gnome
                 throw new ApplicationException("Unsupported protocol: " + server.Protocol);
             }
             f_ProtocolComboBox.Active = protocolPosition;
-
-            // hostname is part of the PKEY, not allowed to change
-            f_HostnameEntry.Sensitive = false;
+            ServerID = server.ServerID;
             f_HostnameEntry.Text = server.Hostname;
-
             f_NetworkComboBoxEntry.Entry.Text = server.Network;
             f_UsernameEntry.Text = server.Username;
             // HACK: Twitter username is part of the PKEY, not allowed to change
@@ -146,6 +157,7 @@ namespace Smuxi.Frontend.Gnome
         {
             ServerModel server = new ServerModel();
             server.Protocol = f_ProtocolComboBox.ActiveText;
+            server.ServerID = ServerID;
             server.Hostname = f_HostnameEntry.Text.Trim();
             server.Network  = f_NetworkComboBoxEntry.Entry.Text.Trim();
             server.Port     = f_PortSpinButton.ValueAsInt;
@@ -247,6 +259,9 @@ namespace Smuxi.Frontend.Gnome
 
             var useEncryption = f_UseEncryptionCheckButton.Active;
             f_ValidateServerCertificateCheckButton.Sensitive = useEncryption;
+            if (!useEncryption) {
+                f_ValidateServerCertificateCheckButton.Active = false;
+            }
             switch (f_ProtocolComboBox.ActiveText) {
                 case "IRC":
                     f_PortSpinButton.Value = useEncryption ? 6697 : 6667;
@@ -267,21 +282,19 @@ namespace Smuxi.Frontend.Gnome
                     ShowHostname = true;
                     ShowNetwork = true;
                     ShowPassword = true;
+                    SupportUseEncryption = true;
 
                     f_HostnameEntry.Sensitive = true;
                     f_NetworkComboBoxEntry.Sensitive = true;
 
                     f_PortSpinButton.Value = 6667;
                     f_PortSpinButton.Sensitive = true;
-                    f_UseEncryptionCheckButton.Active = false;
-                    f_UseEncryptionCheckButton.Sensitive = true;
-                    f_ValidateServerCertificateCheckButton.Active = false;
-                    f_ValidateServerCertificateCheckButton.Sensitive = true;
                     break;
                 case "XMPP":
                     ShowHostname = true;
                     ShowNetwork = false;
                     ShowPassword = true;
+                    SupportUseEncryption = true;
                 
                     f_HostnameEntry.Sensitive = true;
                     f_NetworkComboBoxEntry.Entry.Text = String.Empty;
@@ -289,10 +302,6 @@ namespace Smuxi.Frontend.Gnome
 
                     f_PortSpinButton.Value = 5222;
                     f_PortSpinButton.Sensitive = true;
-                    f_UseEncryptionCheckButton.Active = false;
-                    f_UseEncryptionCheckButton.Sensitive = true;
-                    f_ValidateServerCertificateCheckButton.Active = false;
-                    f_ValidateServerCertificateCheckButton.Sensitive = true;
                     break;
                 // this protocols have static servers
                 case "AIM":
@@ -301,6 +310,7 @@ namespace Smuxi.Frontend.Gnome
                     ShowHostname = false;
                     ShowNetwork = false;
                     ShowPassword = true;
+                    SupportUseEncryption = false;
 
                     f_HostnameEntry.Text = String.Empty;
                     f_HostnameEntry.Sensitive = false;
@@ -309,25 +319,29 @@ namespace Smuxi.Frontend.Gnome
 
                     f_PortSpinButton.Value = 0;
                     f_PortSpinButton.Sensitive = false;
-                    f_UseEncryptionCheckButton.Active = false;
-                    f_UseEncryptionCheckButton.Sensitive = false;
-                    f_ValidateServerCertificateCheckButton.Active = false;
-                    f_ValidateServerCertificateCheckButton.Sensitive = false;
                     break;
                 case "Twitter":
                     ShowHostname = false;
                     ShowNetwork = false;
                     ShowPassword = false;
+                    SupportUseEncryption = false;
 
                     f_HostnameEntry.Text = String.Empty;
                     f_PortSpinButton.Value = 0;
                     f_NetworkComboBoxEntry.Entry.Text = String.Empty;
                     f_PasswordEntry.Text = String.Empty;
+                    break;
+                case "Campfire":
+                    ShowHostname = true;
+                    ShowNetwork = false;
+                    ShowPassword = true;
+                    SupportUseEncryption = false;
 
-                    f_UseEncryptionCheckButton.Active = false;
-                    f_UseEncryptionCheckButton.Sensitive = false;
-                    f_ValidateServerCertificateCheckButton.Active = false;
-                    f_ValidateServerCertificateCheckButton.Sensitive = false;
+                    f_HostnameEntry.Text = ".campfirenow.com";
+                    f_HostnameEntry.Sensitive = true;
+                    f_PortSpinButton.Value = 0;
+                    f_NetworkComboBoxEntry.Entry.Text = String.Empty;
+                    f_PasswordEntry.Text = String.Empty;
                     break;
                 // in case we don't know / handle the protocol here, make
                 // sure we grant maximum flexibility for the input
@@ -335,6 +349,7 @@ namespace Smuxi.Frontend.Gnome
                     ShowHostname = true;
                     ShowNetwork = true;
                     ShowPassword = true;
+                    SupportUseEncryption = true;
 
                     f_HostnameEntry.Sensitive = true;
                     f_PortSpinButton.Sensitive = true;
diff --git a/src/Frontend-GNOME/LinkTag.cs b/src/Frontend-GNOME/Views/Tags/LinkTag.cs
similarity index 100%
rename from src/Frontend-GNOME/LinkTag.cs
rename to src/Frontend-GNOME/Views/Tags/LinkTag.cs
diff --git a/src/Frontend-GNOME/Views/Tags/PersonTag.cs b/src/Frontend-GNOME/Views/Tags/PersonTag.cs
new file mode 100644
index 0000000..b50482e
--- /dev/null
+++ b/src/Frontend-GNOME/Views/Tags/PersonTag.cs
@@ -0,0 +1,43 @@
+// Smuxi - Smart MUltipleXed Irc
+// 
+// Copyright (c) 2012 
+// 
+// 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 PersonTag : Gtk.TextTag
+    {
+        public string ID { get; private set; }
+        public string IdentityName { get; private set; }
+        
+        public PersonTag(string id, string identityName) : base(null)
+        {
+            if (id == null) {
+                throw new ArgumentNullException("id");
+            }
+            if (identityName == null) {
+                throw new ArgumentNullException("identityName");
+            }
+
+            ID = id;
+            IdentityName = identityName;
+        }
+    }
+}
diff --git a/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.JoinWidget.cs b/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.JoinWidget.cs
index 497b322..56832ae 100644
--- a/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.JoinWidget.cs
+++ b/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.JoinWidget.cs
@@ -4,6 +4,7 @@ namespace Smuxi.Frontend.Gnome
 {
 	public partial class JoinWidget
 	{
+		private global::Gtk.UIManager UIManager;
 		private global::Gtk.HBox hbox1;
 		private global::Gtk.Entry f_ChatEntry;
 		private global::Gtk.Label label1;
@@ -14,7 +15,10 @@ namespace Smuxi.Frontend.Gnome
 		{
 			global::Stetic.Gui.Initialize (this);
 			// Widget Smuxi.Frontend.Gnome.JoinWidget
-			global::Stetic.BinContainer.Attach (this);
+			Stetic.BinContainer w1 = global::Stetic.BinContainer.Attach (this);
+			this.UIManager = new global::Gtk.UIManager ();
+			global::Gtk.ActionGroup w2 = new global::Gtk.ActionGroup ("Default");
+			this.UIManager.InsertActionGroup (w2, 0);
 			this.Name = "Smuxi.Frontend.Gnome.JoinWidget";
 			// Container child Smuxi.Frontend.Gnome.JoinWidget.Gtk.Container+ContainerChild
 			this.hbox1 = new global::Gtk.HBox ();
@@ -27,41 +31,57 @@ namespace Smuxi.Frontend.Gnome
 			this.f_ChatEntry.IsEditable = true;
 			this.f_ChatEntry.InvisibleChar = '•';
 			this.hbox1.Add (this.f_ChatEntry);
-			global::Gtk.Box.BoxChild w1 = ((global::Gtk.Box.BoxChild)(this.hbox1 [this.f_ChatEntry]));
-			w1.Position = 0;
+			global::Gtk.Box.BoxChild w3 = ((global::Gtk.Box.BoxChild)(this.hbox1 [this.f_ChatEntry]));
+			w3.Position = 0;
 			// Container child hbox1.Gtk.Box+BoxChild
 			this.label1 = new global::Gtk.Label ();
 			this.label1.Name = "label1";
 			this.label1.LabelProp = "@";
 			this.hbox1.Add (this.label1);
-			global::Gtk.Box.BoxChild w2 = ((global::Gtk.Box.BoxChild)(this.hbox1 [this.label1]));
-			w2.Position = 1;
-			w2.Expand = false;
-			w2.Fill = false;
+			global::Gtk.Box.BoxChild w4 = ((global::Gtk.Box.BoxChild)(this.hbox1 [this.label1]));
+			w4.Position = 1;
+			w4.Expand = false;
+			w4.Fill = false;
 			// Container child hbox1.Gtk.Box+BoxChild
 			this.f_NetworkComboBox = global::Gtk.ComboBox.NewText ();
 			this.f_NetworkComboBox.Name = "f_NetworkComboBox";
 			this.hbox1.Add (this.f_NetworkComboBox);
-			global::Gtk.Box.BoxChild w3 = ((global::Gtk.Box.BoxChild)(this.hbox1 [this.f_NetworkComboBox]));
-			w3.Position = 2;
-			w3.Expand = false;
-			w3.Fill = false;
+			global::Gtk.Box.BoxChild w5 = ((global::Gtk.Box.BoxChild)(this.hbox1 [this.f_NetworkComboBox]));
+			w5.Position = 2;
+			w5.Expand = false;
+			w5.Fill = false;
 			// Container child hbox1.Gtk.Box+BoxChild
 			this.f_JoinButton = new global::Gtk.Button ();
 			this.f_JoinButton.CanFocus = true;
 			this.f_JoinButton.Name = "f_JoinButton";
 			this.f_JoinButton.UseUnderline = true;
-			this.f_JoinButton.Label = global::Mono.Unix.Catalog.GetString ("Join Chat");
+			// Container child f_JoinButton.Gtk.Container+ContainerChild
+			global::Gtk.Alignment w6 = new global::Gtk.Alignment (0.5F, 0.5F, 0F, 0F);
+			// Container child GtkAlignment.Gtk.Container+ContainerChild
+			global::Gtk.HBox w7 = new global::Gtk.HBox ();
+			w7.Spacing = 2;
+			// Container child GtkHBox.Gtk.Container+ContainerChild
+			global::Gtk.Image w8 = new global::Gtk.Image ();
+			w8.Pixbuf = global::Stetic.IconLoader.LoadIcon (this, "gtk-go-forward", global::Gtk.IconSize.Menu);
+			w7.Add (w8);
+			// Container child GtkHBox.Gtk.Container+ContainerChild
+			global::Gtk.Label w10 = new global::Gtk.Label ();
+			w10.LabelProp = global::Mono.Unix.Catalog.GetString ("Join");
+			w10.UseUnderline = true;
+			w7.Add (w10);
+			w6.Add (w7);
+			this.f_JoinButton.Add (w6);
 			this.hbox1.Add (this.f_JoinButton);
-			global::Gtk.Box.BoxChild w4 = ((global::Gtk.Box.BoxChild)(this.hbox1 [this.f_JoinButton]));
-			w4.Position = 3;
-			w4.Expand = false;
-			w4.Fill = false;
+			global::Gtk.Box.BoxChild w14 = ((global::Gtk.Box.BoxChild)(this.hbox1 [this.f_JoinButton]));
+			w14.Position = 3;
+			w14.Expand = false;
+			w14.Fill = false;
 			this.Add (this.hbox1);
 			if ((this.Child != null)) {
 				this.Child.ShowAll ();
 			}
-			this.Hide ();
+			w1.SetUiManager (UIManager);
+			this.Show ();
 		}
 	}
 }
diff --git a/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs b/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs
new file mode 100644
index 0000000..fafba22
--- /dev/null
+++ b/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.MenuWidget.cs
@@ -0,0 +1,238 @@
+
+// This file has been generated by the GUI designer. Do not modify.
+namespace Smuxi.Frontend.Gnome
+{
+	public partial class MenuWidget
+	{
+		private global::Gtk.UIManager UIManager;
+		private global::Gtk.Action f_SmuxiAction;
+		private global::Gtk.Action ServerAction;
+		private global::Gtk.Action ChatAction;
+		private global::Gtk.Action EngineAction;
+		private global::Gtk.Action ViewAction;
+		private global::Gtk.Action f_HelpAction;
+		private global::Gtk.Action f_ConnectToolAction;
+		private global::Gtk.Action f_OpenLogToolAction;
+		private global::Gtk.Action f_FullscreenToolAction;
+		private global::Gtk.Action f_PreferencesToolAction;
+		private global::Gtk.Action f_PreferencesAction;
+		private global::Gtk.Action f_QuitAction;
+		private global::Gtk.Action f_ConnectAction;
+		private global::Gtk.Action f_AddServerAction;
+		private global::Gtk.Action f_ManageServerAction;
+		private global::Gtk.Action f_JoinChatAction;
+		private global::Gtk.Action f_FindGroupChatAction;
+		private global::Gtk.Action f_ClearAllActivityAction;
+		private global::Gtk.Action f_NextChatAction;
+		private global::Gtk.Action f_PreviousChatAction;
+		private global::Gtk.Action f_CloseChatAction;
+		private global::Gtk.Action f_UseLocalEngineAction;
+		private global::Gtk.Action f_AddRemoteEngineAction;
+		private global::Gtk.Action f_SwitchRemoteEngineAction;
+		private global::Gtk.ToggleAction f_CaretModeAction;
+		private global::Gtk.ToggleAction f_BrowseModeAction;
+		private global::Gtk.ToggleAction f_ShowMenubarAction;
+		private global::Gtk.ToggleAction f_ShowStatusbarAction;
+		private global::Gtk.ToggleAction f_ShowJoinBarAction;
+		private global::Gtk.Action f_FullscreenAction;
+		private global::Gtk.Action f_AboutAction;
+		private global::Gtk.Action f_OpenLogAction;
+		private global::Gtk.Action f_FindGroupChatToolAction;
+		private global::Gtk.Action f_WebsiteAction;
+		private global::Gtk.VBox vbox2;
+		private global::Gtk.MenuBar f_MenuBar;
+		private global::Gtk.HBox hbox1;
+		private global::Gtk.Toolbar f_MenuToolbar;
+		private global::Gtk.Toolbar f_JoinToolbar;
+        
+		protected virtual void Build ()
+		{
+			global::Stetic.Gui.Initialize (this);
+			// Widget Smuxi.Frontend.Gnome.MenuWidget
+			Stetic.BinContainer w1 = global::Stetic.BinContainer.Attach (this);
+			this.UIManager = new global::Gtk.UIManager ();
+			global::Gtk.ActionGroup w2 = new global::Gtk.ActionGroup ("Default");
+			this.f_SmuxiAction = new global::Gtk.Action ("f_SmuxiAction", global::Mono.Unix.Catalog.GetString ("_Smuxi"), null, null);
+			this.f_SmuxiAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("_Smuxi");
+			w2.Add (this.f_SmuxiAction, null);
+			this.ServerAction = new global::Gtk.Action ("ServerAction", global::Mono.Unix.Catalog.GetString ("_Server"), null, null);
+			this.ServerAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("_Server");
+			w2.Add (this.ServerAction, null);
+			this.ChatAction = new global::Gtk.Action ("ChatAction", global::Mono.Unix.Catalog.GetString ("_Chat"), null, null);
+			this.ChatAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("_Chat");
+			w2.Add (this.ChatAction, null);
+			this.EngineAction = new global::Gtk.Action ("EngineAction", global::Mono.Unix.Catalog.GetString ("_Engine"), null, null);
+			this.EngineAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("_Engine");
+			w2.Add (this.EngineAction, null);
+			this.ViewAction = new global::Gtk.Action ("ViewAction", global::Mono.Unix.Catalog.GetString ("_View"), null, null);
+			this.ViewAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("_View");
+			w2.Add (this.ViewAction, null);
+			this.f_HelpAction = new global::Gtk.Action ("f_HelpAction", global::Mono.Unix.Catalog.GetString ("_Help"), null, null);
+			this.f_HelpAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("_Help");
+			w2.Add (this.f_HelpAction, null);
+			this.f_ConnectToolAction = new global::Gtk.Action ("f_ConnectToolAction", global::Mono.Unix.Catalog.GetString ("Connect"), null, "gtk-network");
+			this.f_ConnectToolAction.IsImportant = true;
+			this.f_ConnectToolAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("Connect");
+			w2.Add (this.f_ConnectToolAction, null);
+			this.f_OpenLogToolAction = new global::Gtk.Action ("f_OpenLogToolAction", global::Mono.Unix.Catalog.GetString ("Open Log"), null, "gtk-open");
+			this.f_OpenLogToolAction.IsImportant = true;
+			this.f_OpenLogToolAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("Open Log");
+			w2.Add (this.f_OpenLogToolAction, null);
+			this.f_FullscreenToolAction = new global::Gtk.Action ("f_FullscreenToolAction", null, null, "gtk-fullscreen");
+			this.f_FullscreenToolAction.IsImportant = true;
+			w2.Add (this.f_FullscreenToolAction, null);
+			this.f_PreferencesToolAction = new global::Gtk.Action ("f_PreferencesToolAction", null, null, "gtk-preferences");
+			this.f_PreferencesToolAction.IsImportant = true;
+			w2.Add (this.f_PreferencesToolAction, null);
+			this.f_PreferencesAction = new global::Gtk.Action ("f_PreferencesAction", global::Mono.Unix.Catalog.GetString ("_Preferences"), null, "gtk-preferences");
+			this.f_PreferencesAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("_Preferences");
+			w2.Add (this.f_PreferencesAction, null);
+			this.f_QuitAction = new global::Gtk.Action ("f_QuitAction", global::Mono.Unix.Catalog.GetString ("_Quit"), null, null);
+			this.f_QuitAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("_Quit");
+			w2.Add (this.f_QuitAction, "<Control>q");
+			this.f_ConnectAction = new global::Gtk.Action ("f_ConnectAction", global::Mono.Unix.Catalog.GetString ("_Connect"), null, "gtk-network");
+			this.f_ConnectAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("_Connect");
+			w2.Add (this.f_ConnectAction, null);
+			this.f_AddServerAction = new global::Gtk.Action ("f_AddServerAction", global::Mono.Unix.Catalog.GetString ("_Add"), null, "gtk-add");
+			this.f_AddServerAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("_Add");
+			w2.Add (this.f_AddServerAction, null);
+			this.f_ManageServerAction = new global::Gtk.Action ("f_ManageServerAction", global::Mono.Unix.Catalog.GetString ("_Manage"), null, "gtk-edit");
+			this.f_ManageServerAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("_Manage");
+			w2.Add (this.f_ManageServerAction, null);
+			this.f_JoinChatAction = new global::Gtk.Action ("f_JoinChatAction", global::Mono.Unix.Catalog.GetString ("_Open / Join Chat"), null, null);
+			this.f_JoinChatAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("_Open / Join Chat");
+			w2.Add (this.f_JoinChatAction, "<Control>l");
+			this.f_FindGroupChatAction = new global::Gtk.Action ("f_FindGroupChatAction", global::Mono.Unix.Catalog.GetString ("_Find Group Chat"), null, null);
+			this.f_FindGroupChatAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("_Find Group Chat");
+			w2.Add (this.f_FindGroupChatAction, null);
+			this.f_ClearAllActivityAction = new global::Gtk.Action ("f_ClearAllActivityAction", global::Mono.Unix.Catalog.GetString ("C_lear All Activity"), null, "gtk-clear");
+			this.f_ClearAllActivityAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("C_lear All Activity");
+			w2.Add (this.f_ClearAllActivityAction, null);
+			this.f_NextChatAction = new global::Gtk.Action ("f_NextChatAction", global::Mono.Unix.Catalog.GetString ("_Next Chat"), null, "gtk-go-forward");
+			this.f_NextChatAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("_Next Chat");
+			w2.Add (this.f_NextChatAction, "<Control>Page_Down");
+			this.f_PreviousChatAction = new global::Gtk.Action ("f_PreviousChatAction", global::Mono.Unix.Catalog.GetString ("_Previous Chat"), null, "gtk-go-back");
+			this.f_PreviousChatAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("_Previous Chat");
+			w2.Add (this.f_PreviousChatAction, "<Control>Page_Up");
+			this.f_CloseChatAction = new global::Gtk.Action ("f_CloseChatAction", global::Mono.Unix.Catalog.GetString ("_Close"), null, null);
+			this.f_CloseChatAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("_Close");
+			w2.Add (this.f_CloseChatAction, "<Control>w");
+			this.f_UseLocalEngineAction = new global::Gtk.Action ("f_UseLocalEngineAction", global::Mono.Unix.Catalog.GetString ("_Use Local Engine"), null, null);
+			this.f_UseLocalEngineAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("_Use Local Engine");
+			w2.Add (this.f_UseLocalEngineAction, null);
+			this.f_AddRemoteEngineAction = new global::Gtk.Action ("f_AddRemoteEngineAction", global::Mono.Unix.Catalog.GetString ("_Add Remote Engine"), null, null);
+			this.f_AddRemoteEngineAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("_Add Remote Engine");
+			w2.Add (this.f_AddRemoteEngineAction, null);
+			this.f_SwitchRemoteEngineAction = new global::Gtk.Action ("f_SwitchRemoteEngineAction", global::Mono.Unix.Catalog.GetString ("Switch Remote Engine"), null, null);
+			this.f_SwitchRemoteEngineAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("Switch Remote Engine");
+			w2.Add (this.f_SwitchRemoteEngineAction, null);
+			this.f_CaretModeAction = new global::Gtk.ToggleAction ("f_CaretModeAction", global::Mono.Unix.Catalog.GetString ("_Caret Mode"), null, null);
+			this.f_CaretModeAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("_Caret Mode");
+			w2.Add (this.f_CaretModeAction, "F7");
+			this.f_BrowseModeAction = new global::Gtk.ToggleAction ("f_BrowseModeAction", global::Mono.Unix.Catalog.GetString ("_Browse Mode"), null, null);
+			this.f_BrowseModeAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("_Browse Mode");
+			w2.Add (this.f_BrowseModeAction, "F8");
+			this.f_ShowMenubarAction = new global::Gtk.ToggleAction ("f_ShowMenubarAction", global::Mono.Unix.Catalog.GetString ("Show _Menubar"), null, null);
+			this.f_ShowMenubarAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("Show _Menubar");
+			w2.Add (this.f_ShowMenubarAction, null);
+			this.f_ShowStatusbarAction = new global::Gtk.ToggleAction ("f_ShowStatusbarAction", global::Mono.Unix.Catalog.GetString ("Show _Statusbar"), null, null);
+			this.f_ShowStatusbarAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("Show _Statusbar");
+			w2.Add (this.f_ShowStatusbarAction, null);
+			this.f_ShowJoinBarAction = new global::Gtk.ToggleAction ("f_ShowJoinBarAction", global::Mono.Unix.Catalog.GetString ("Show _Join Bar"), null, null);
+			this.f_ShowJoinBarAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("Show _Join Bar");
+			w2.Add (this.f_ShowJoinBarAction, null);
+			this.f_FullscreenAction = new global::Gtk.Action ("f_FullscreenAction", global::Mono.Unix.Catalog.GetString ("_Fullscreen"), null, "gtk-fullscreen");
+			this.f_FullscreenAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("_Fullscreen");
+			w2.Add (this.f_FullscreenAction, "F11");
+			this.f_AboutAction = new global::Gtk.Action ("f_AboutAction", global::Mono.Unix.Catalog.GetString ("_About"), null, "gtk-about");
+			this.f_AboutAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("_About");
+			w2.Add (this.f_AboutAction, null);
+			this.f_OpenLogAction = new global::Gtk.Action ("f_OpenLogAction", global::Mono.Unix.Catalog.GetString ("Open Log"), null, null);
+			this.f_OpenLogAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("Open Log");
+			w2.Add (this.f_OpenLogAction, null);
+			this.f_FindGroupChatToolAction = new global::Gtk.Action ("f_FindGroupChatToolAction", global::Mono.Unix.Catalog.GetString ("Find Group Chat"), null, null);
+			this.f_FindGroupChatToolAction.IsImportant = true;
+			this.f_FindGroupChatToolAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("Find Group Chat");
+			w2.Add (this.f_FindGroupChatToolAction, null);
+			this.f_WebsiteAction = new global::Gtk.Action ("f_WebsiteAction", global::Mono.Unix.Catalog.GetString ("_Website"), null, null);
+			this.f_WebsiteAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("_Website");
+			w2.Add (this.f_WebsiteAction, null);
+			this.UIManager.InsertActionGroup (w2, 0);
+			this.Name = "Smuxi.Frontend.Gnome.MenuWidget";
+			// Container child Smuxi.Frontend.Gnome.MenuWidget.Gtk.Container+ContainerChild
+			this.vbox2 = new global::Gtk.VBox ();
+			this.vbox2.Name = "vbox2";
+			// Container child vbox2.Gtk.Box+BoxChild
+			this.UIManager.AddUiFromString ("<ui><menubar name='f_MenuBar'><menu name='f_SmuxiAction' action='f_SmuxiAction'><menuitem name='f_PreferencesAction' action='f_PreferencesAction'/><menuitem name='f_QuitAction' action='f_QuitAction'/></menu><menu name='ServerAction' action='ServerAction'><menuitem name='f_ConnectAction' action='f_ConnectAction'/><separator/><menuitem name='f_AddServerAction' action='f_AddServerAction'/><menuitem name='f_ManageServerAction' action='f_ManageServerAction'/></menu><menu name='ChatAction' action='ChatAction'><menuitem name='f_JoinChatAction' action='f_JoinChatAction'/><menuitem name='f_FindGroupChatAction' action='f_FindGroupChatAction'/><menuitem name='f_ClearAllActivityAction' action='f_ClearAllActivityAction'/><separator/><menuitem name='f_NextChatAction' action='f_NextChatAction'/><menuitem name='f_PreviousChatAction' action='f_PreviousChatAction'/><separator/><menuitem name='f_OpenLogAction' action='f_OpenLogAction'/><menuitem name='f_CloseChatAction' action='f_CloseChatAction'/></menu><menu name='EngineAction' action='EngineAction'><menuitem name='f_UseLocalEngineAction' action='f_UseLocalEngineAction'/><separator/><menuitem name='f_AddRemoteEngineAction' action='f_AddRemoteEngineAction'/><menuitem name='f_SwitchRemoteEngineAction' action='f_SwitchRemoteEngineAction'/></menu><menu name='ViewAction' action='ViewAction'><menuitem name='f_CaretModeAction' action='f_CaretModeAction'/><menuitem name='f_BrowseModeAction' action='f_BrowseModeAction'/><menuitem name='f_ShowMenubarAction' action='f_ShowMenubarAction'/><menuitem name='f_ShowStatusbarAction' action='f_ShowStatusbarAction'/><menuitem name='f_ShowJoinBarAction' action='f_ShowJoinBarAction'/><menuitem name='f_FullscreenAction' action='f_FullscreenAction'/></menu><menu name='f_HelpAction' action='f_HelpAction'><menuitem name='f_WebsiteAction' action='f_WebsiteAction'/><menuitem name='f_AboutAction' action='f_AboutAction'/></menu></menubar></ui>");
+			this.f_MenuBar = ((global::Gtk.MenuBar)(this.UIManager.GetWidget ("/f_MenuBar")));
+			this.f_MenuBar.Name = "f_MenuBar";
+			this.vbox2.Add (this.f_MenuBar);
+			global::Gtk.Box.BoxChild w3 = ((global::Gtk.Box.BoxChild)(this.vbox2 [this.f_MenuBar]));
+			w3.Position = 0;
+			w3.Expand = false;
+			w3.Fill = false;
+			// Container child vbox2.Gtk.Box+BoxChild
+			this.hbox1 = new global::Gtk.HBox ();
+			this.hbox1.Name = "hbox1";
+			// Container child hbox1.Gtk.Box+BoxChild
+			this.UIManager.AddUiFromString ("<ui><toolbar name='f_MenuToolbar'><toolitem name='f_ConnectToolAction' action='f_ConnectToolAction'/><toolitem name='f_FindGroupChatToolAction' action='f_FindGroupChatToolAction'/><toolitem name='f_OpenLogToolAction' action='f_OpenLogToolAction'/><toolitem name='f_FullscreenToolAction' action='f_FullscreenToolAction'/><toolitem name='f_PreferencesToolAction' action='f_PreferencesToolAction'/></toolbar></ui>");
+			this.f_MenuToolbar = ((global::Gtk.Toolbar)(this.UIManager.GetWidget ("/f_MenuToolbar")));
+			this.f_MenuToolbar.Name = "f_MenuToolbar";
+			this.f_MenuToolbar.ShowArrow = false;
+			this.f_MenuToolbar.ToolbarStyle = ((global::Gtk.ToolbarStyle)(3));
+			this.f_MenuToolbar.IconSize = ((global::Gtk.IconSize)(3));
+			this.hbox1.Add (this.f_MenuToolbar);
+			global::Gtk.Box.BoxChild w4 = ((global::Gtk.Box.BoxChild)(this.hbox1 [this.f_MenuToolbar]));
+			w4.Position = 0;
+			// Container child hbox1.Gtk.Box+BoxChild
+			this.UIManager.AddUiFromString ("<ui><toolbar name='f_JoinToolbar'/></ui>");
+			this.f_JoinToolbar = ((global::Gtk.Toolbar)(this.UIManager.GetWidget ("/f_JoinToolbar")));
+			this.f_JoinToolbar.Name = "f_JoinToolbar";
+			this.f_JoinToolbar.ShowArrow = false;
+			this.hbox1.Add (this.f_JoinToolbar);
+			global::Gtk.Box.BoxChild w5 = ((global::Gtk.Box.BoxChild)(this.hbox1 [this.f_JoinToolbar]));
+			w5.PackType = ((global::Gtk.PackType)(1));
+			w5.Position = 1;
+			w5.Expand = false;
+			this.vbox2.Add (this.hbox1);
+			global::Gtk.Box.BoxChild w6 = ((global::Gtk.Box.BoxChild)(this.vbox2 [this.hbox1]));
+			w6.Position = 1;
+			w6.Expand = false;
+			w6.Fill = false;
+			this.Add (this.vbox2);
+			if ((this.Child != null)) {
+				this.Child.ShowAll ();
+			}
+			w1.SetUiManager (UIManager);
+			this.Hide ();
+			this.f_ConnectToolAction.Activated += new global::System.EventHandler (this.OnConnectActionActivated);
+			this.f_OpenLogToolAction.Activated += new global::System.EventHandler (this.OnOpenLogActionActivated);
+			this.f_FullscreenToolAction.Activated += new global::System.EventHandler (this.OnFullscreenActionActivated);
+			this.f_PreferencesToolAction.Activated += new global::System.EventHandler (this.OnPreferencesActionActivated);
+			this.f_PreferencesAction.Activated += new global::System.EventHandler (this.OnPreferencesActionActivated);
+			this.f_QuitAction.Activated += new global::System.EventHandler (this.OnQuitActionActivated);
+			this.f_ConnectAction.Activated += new global::System.EventHandler (this.OnConnectActionActivated);
+			this.f_AddServerAction.Activated += new global::System.EventHandler (this.OnAddServerActionActivated);
+			this.f_ManageServerAction.Activated += new global::System.EventHandler (this.OnManageServerActionActivated);
+			this.f_JoinChatAction.Activated += new global::System.EventHandler (this.OnJoinChatActionActivated);
+			this.f_FindGroupChatAction.Activated += new global::System.EventHandler (this.OnFindGroupChatActionActivated);
+			this.f_ClearAllActivityAction.Activated += new global::System.EventHandler (this.OnClearAllActivityActionActivated);
+			this.f_NextChatAction.Activated += new global::System.EventHandler (this.OnNextChatActionActivated);
+			this.f_PreviousChatAction.Activated += new global::System.EventHandler (this.OnPreviousChatActionActivated);
+			this.f_CloseChatAction.Activated += new global::System.EventHandler (this.OnCloseChatActionActivated);
+			this.f_UseLocalEngineAction.Activated += new global::System.EventHandler (this.OnUseLocalEngineActionActivated);
+			this.f_AddRemoteEngineAction.Activated += new global::System.EventHandler (this.OnAddRemoteEngineActionActivated);
+			this.f_SwitchRemoteEngineAction.Activated += new global::System.EventHandler (this.OnSwitchRemoteEngineActionActivated);
+			this.f_CaretModeAction.Toggled += new global::System.EventHandler (this.OnCaretModeActionToggled);
+			this.f_BrowseModeAction.Toggled += new global::System.EventHandler (this.OnBrowseModeActionToggled);
+			this.f_ShowMenubarAction.Toggled += new global::System.EventHandler (this.OnShowMenubarActionToggled);
+			this.f_ShowStatusbarAction.Toggled += new global::System.EventHandler (this.OnShowStatusbarActionToggled);
+			this.f_ShowJoinBarAction.Toggled += new global::System.EventHandler (this.OnShowJoinBarActionToggled);
+			this.f_FullscreenAction.Activated += new global::System.EventHandler (this.OnFullscreenActionActivated);
+			this.f_AboutAction.Activated += new global::System.EventHandler (this.OnAboutActionActivated);
+			this.f_OpenLogAction.Activated += new global::System.EventHandler (this.OnOpenLogActionActivated);
+			this.f_FindGroupChatToolAction.Activated += new global::System.EventHandler (this.OnFindGroupChatActionActivated);
+			this.f_WebsiteAction.Activated += new global::System.EventHandler (this.OnWebsiteActionActivated);
+		}
+	}
+}
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 1b9e030..184ceed 100644
--- a/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs
+++ b/src/Frontend-GNOME/gtk-gui/Smuxi.Frontend.Gnome.QuickConnectDialog.cs
@@ -16,7 +16,7 @@ namespace Smuxi.Frontend.Gnome
 			global::Stetic.Gui.Initialize (this);
 			// Widget Smuxi.Frontend.Gnome.QuickConnectDialog
 			this.Name = "Smuxi.Frontend.Gnome.QuickConnectDialog";
-			this.Title = global::Mono.Unix.Catalog.GetString ("Smuxi - Quick Connect");
+			this.Title = global::Mono.Unix.Catalog.GetString ("Smuxi - Connect");
 			this.TypeHint = ((global::Gdk.WindowTypeHint)(1));
 			this.BorderWidth = ((uint)(5));
 			this.DefaultWidth = 640;
diff --git a/src/Frontend-GNOME/gtk-gui/gui.stetic b/src/Frontend-GNOME/gtk-gui/gui.stetic
index 7fb6c30..458ea6e 100644
--- a/src/Frontend-GNOME/gtk-gui/gui.stetic
+++ b/src/Frontend-GNOME/gtk-gui/gui.stetic
@@ -2311,9 +2311,9 @@
       </widget>
     </child>
   </widget>
-  <widget class="Gtk.Dialog" id="Smuxi.Frontend.Gnome.QuickConnectDialog" design-size="559 420">
+  <widget class="Gtk.Dialog" id="Smuxi.Frontend.Gnome.QuickConnectDialog" design-size="559 505">
     <property name="MemberName" />
-    <property name="Title" translatable="yes">Smuxi - Quick Connect</property>
+    <property name="Title" translatable="yes">Smuxi - Connect</property>
     <property name="TypeHint">Dialog</property>
     <property name="BorderWidth">5</property>
     <property name="DefaultWidth">640</property>
@@ -4262,9 +4262,9 @@ Click "Forward" to begin.</property>
       </widget>
     </child>
   </widget>
-  <widget class="Gtk.Bin" id="Smuxi.Frontend.Gnome.JoinWidget" design-size="393 36">
+  <widget class="Gtk.Bin" id="Smuxi.Frontend.Gnome.JoinWidget" design-size="393 55">
+    <action-group name="Default" />
     <property name="MemberName" />
-    <property name="Visible">False</property>
     <child>
       <widget class="Gtk.HBox" id="hbox1">
         <property name="MemberName" />
@@ -4310,8 +4310,9 @@ Click "Forward" to begin.</property>
           <widget class="Gtk.Button" id="f_JoinButton">
             <property name="MemberName" />
             <property name="CanFocus">True</property>
-            <property name="Type">TextOnly</property>
-            <property name="Label" translatable="yes">Join Chat</property>
+            <property name="Type">TextAndIcon</property>
+            <property name="Icon">stock:gtk-go-forward Menu</property>
+            <property name="Label" translatable="yes">Join</property>
             <property name="UseUnderline">True</property>
           </widget>
           <packing>
@@ -4324,4 +4325,342 @@ Click "Forward" to begin.</property>
       </widget>
     </child>
   </widget>
+  <widget class="Gtk.Bin" id="Smuxi.Frontend.Gnome.MenuWidget" design-size="716 69">
+    <action-group name="Default">
+      <action id="f_SmuxiAction">
+        <property name="Type">Action</property>
+        <property name="Label" translatable="yes">_Smuxi</property>
+        <property name="ShortLabel" translatable="yes">_Smuxi</property>
+      </action>
+      <action id="ServerAction">
+        <property name="Type">Action</property>
+        <property name="Label" translatable="yes">_Server</property>
+        <property name="ShortLabel" translatable="yes">_Server</property>
+      </action>
+      <action id="ChatAction">
+        <property name="Type">Action</property>
+        <property name="Label" translatable="yes">_Chat</property>
+        <property name="ShortLabel" translatable="yes">_Chat</property>
+      </action>
+      <action id="EngineAction">
+        <property name="Type">Action</property>
+        <property name="Label" translatable="yes">_Engine</property>
+        <property name="ShortLabel" translatable="yes">_Engine</property>
+      </action>
+      <action id="ViewAction">
+        <property name="Type">Action</property>
+        <property name="Label" translatable="yes">_View</property>
+        <property name="ShortLabel" translatable="yes">_View</property>
+      </action>
+      <action id="f_HelpAction">
+        <property name="Type">Action</property>
+        <property name="Label" translatable="yes">_Help</property>
+        <property name="ShortLabel" translatable="yes">_Help</property>
+      </action>
+      <action id="f_ConnectToolAction">
+        <property name="Type">Action</property>
+        <property name="IsImportant">True</property>
+        <property name="Label" translatable="yes">Connect</property>
+        <property name="ShortLabel" translatable="yes">Connect</property>
+        <property name="StockId">gtk-network</property>
+        <signal name="Activated" handler="OnConnectActionActivated" />
+      </action>
+      <action id="f_OpenLogToolAction">
+        <property name="Type">Action</property>
+        <property name="IsImportant">True</property>
+        <property name="Label" translatable="yes">Open Log</property>
+        <property name="ShortLabel" translatable="yes">Open Log</property>
+        <property name="StockId">gtk-open</property>
+        <signal name="Activated" handler="OnOpenLogActionActivated" />
+      </action>
+      <action id="f_FullscreenToolAction">
+        <property name="Type">Action</property>
+        <property name="IsImportant">True</property>
+        <property name="Label" translatable="yes" />
+        <property name="StockId">gtk-fullscreen</property>
+        <signal name="Activated" handler="OnFullscreenActionActivated" />
+      </action>
+      <action id="f_PreferencesToolAction">
+        <property name="Type">Action</property>
+        <property name="IsImportant">True</property>
+        <property name="Label" translatable="yes" />
+        <property name="StockId">gtk-preferences</property>
+        <signal name="Activated" handler="OnPreferencesActionActivated" />
+      </action>
+      <action id="f_PreferencesAction">
+        <property name="Type">Action</property>
+        <property name="Label" translatable="yes">_Preferences</property>
+        <property name="ShortLabel" translatable="yes">_Preferences</property>
+        <property name="StockId">gtk-preferences</property>
+        <signal name="Activated" handler="OnPreferencesActionActivated" />
+      </action>
+      <action id="f_QuitAction">
+        <property name="Type">Action</property>
+        <property name="Accelerator"><Control>q</property>
+        <property name="Label" translatable="yes">_Quit</property>
+        <property name="ShortLabel" translatable="yes">_Quit</property>
+        <signal name="Activated" handler="OnQuitActionActivated" />
+      </action>
+      <action id="f_ConnectAction">
+        <property name="Type">Action</property>
+        <property name="Label" translatable="yes">_Connect</property>
+        <property name="ShortLabel" translatable="yes">_Connect</property>
+        <property name="StockId">gtk-network</property>
+        <signal name="Activated" handler="OnConnectActionActivated" />
+      </action>
+      <action id="f_AddServerAction">
+        <property name="Type">Action</property>
+        <property name="Label" translatable="yes">_Add</property>
+        <property name="ShortLabel" translatable="yes">_Add</property>
+        <property name="StockId">gtk-add</property>
+        <signal name="Activated" handler="OnAddServerActionActivated" />
+      </action>
+      <action id="f_ManageServerAction">
+        <property name="Type">Action</property>
+        <property name="Label" translatable="yes">_Manage</property>
+        <property name="ShortLabel" translatable="yes">_Manage</property>
+        <property name="StockId">gtk-edit</property>
+        <signal name="Activated" handler="OnManageServerActionActivated" />
+      </action>
+      <action id="f_JoinChatAction">
+        <property name="Type">Action</property>
+        <property name="Accelerator"><Control>l</property>
+        <property name="Label" translatable="yes">_Open / Join Chat</property>
+        <property name="ShortLabel" translatable="yes">_Open / Join Chat</property>
+        <signal name="Activated" handler="OnJoinChatActionActivated" />
+      </action>
+      <action id="f_FindGroupChatAction">
+        <property name="Type">Action</property>
+        <property name="Label" translatable="yes">_Find Group Chat</property>
+        <property name="ShortLabel" translatable="yes">_Find Group Chat</property>
+        <signal name="Activated" handler="OnFindGroupChatActionActivated" />
+      </action>
+      <action id="f_ClearAllActivityAction">
+        <property name="Type">Action</property>
+        <property name="Label" translatable="yes">C_lear All Activity</property>
+        <property name="ShortLabel" translatable="yes">C_lear All Activity</property>
+        <property name="StockId">gtk-clear</property>
+        <signal name="Activated" handler="OnClearAllActivityActionActivated" />
+      </action>
+      <action id="f_NextChatAction">
+        <property name="Type">Action</property>
+        <property name="Accelerator"><Control>Page_Down</property>
+        <property name="Label" translatable="yes">_Next Chat</property>
+        <property name="ShortLabel" translatable="yes">_Next Chat</property>
+        <property name="StockId">gtk-go-forward</property>
+        <signal name="Activated" handler="OnNextChatActionActivated" />
+      </action>
+      <action id="f_PreviousChatAction">
+        <property name="Type">Action</property>
+        <property name="Accelerator"><Control>Page_Up</property>
+        <property name="Label" translatable="yes">_Previous Chat</property>
+        <property name="ShortLabel" translatable="yes">_Previous Chat</property>
+        <property name="StockId">gtk-go-back</property>
+        <signal name="Activated" handler="OnPreviousChatActionActivated" />
+      </action>
+      <action id="f_CloseChatAction">
+        <property name="Type">Action</property>
+        <property name="Accelerator"><Control>w</property>
+        <property name="Label" translatable="yes">_Close</property>
+        <property name="ShortLabel" translatable="yes">_Close</property>
+        <signal name="Activated" handler="OnCloseChatActionActivated" />
+      </action>
+      <action id="f_UseLocalEngineAction">
+        <property name="Type">Action</property>
+        <property name="Label" translatable="yes">_Use Local Engine</property>
+        <property name="ShortLabel" translatable="yes">_Use Local Engine</property>
+        <signal name="Activated" handler="OnUseLocalEngineActionActivated" />
+      </action>
+      <action id="f_AddRemoteEngineAction">
+        <property name="Type">Action</property>
+        <property name="Label" translatable="yes">_Add Remote Engine</property>
+        <property name="ShortLabel" translatable="yes">_Add Remote Engine</property>
+        <signal name="Activated" handler="OnAddRemoteEngineActionActivated" />
+      </action>
+      <action id="f_SwitchRemoteEngineAction">
+        <property name="Type">Action</property>
+        <property name="Label" translatable="yes">Switch Remote Engine</property>
+        <property name="ShortLabel" translatable="yes">Switch Remote Engine</property>
+        <signal name="Activated" handler="OnSwitchRemoteEngineActionActivated" />
+      </action>
+      <action id="f_CaretModeAction">
+        <property name="Type">Toggle</property>
+        <property name="Accelerator">F7</property>
+        <property name="Label" translatable="yes">_Caret Mode</property>
+        <property name="ShortLabel" translatable="yes">_Caret Mode</property>
+        <property name="DrawAsRadio">False</property>
+        <property name="Active">False</property>
+        <signal name="Toggled" handler="OnCaretModeActionToggled" />
+      </action>
+      <action id="f_BrowseModeAction">
+        <property name="Type">Toggle</property>
+        <property name="Accelerator">F8</property>
+        <property name="Label" translatable="yes">_Browse Mode</property>
+        <property name="ShortLabel" translatable="yes">_Browse Mode</property>
+        <property name="DrawAsRadio">False</property>
+        <property name="Active">False</property>
+        <signal name="Toggled" handler="OnBrowseModeActionToggled" />
+      </action>
+      <action id="f_ShowMenubarAction">
+        <property name="Type">Toggle</property>
+        <property name="Label" translatable="yes">Show _Menubar</property>
+        <property name="ShortLabel" translatable="yes">Show _Menubar</property>
+        <property name="DrawAsRadio">False</property>
+        <property name="Active">False</property>
+        <signal name="Toggled" handler="OnShowMenubarActionToggled" />
+      </action>
+      <action id="f_ShowStatusbarAction">
+        <property name="Type">Toggle</property>
+        <property name="Label" translatable="yes">Show _Statusbar</property>
+        <property name="ShortLabel" translatable="yes">Show _Statusbar</property>
+        <property name="DrawAsRadio">False</property>
+        <property name="Active">False</property>
+        <signal name="Toggled" handler="OnShowStatusbarActionToggled" />
+      </action>
+      <action id="f_ShowJoinBarAction">
+        <property name="Type">Toggle</property>
+        <property name="Label" translatable="yes">Show _Join Bar</property>
+        <property name="ShortLabel" translatable="yes">Show _Join Bar</property>
+        <property name="DrawAsRadio">False</property>
+        <property name="Active">False</property>
+        <signal name="Toggled" handler="OnShowJoinBarActionToggled" />
+      </action>
+      <action id="f_FullscreenAction">
+        <property name="Type">Action</property>
+        <property name="Accelerator">F11</property>
+        <property name="Label" translatable="yes">_Fullscreen</property>
+        <property name="ShortLabel" translatable="yes">_Fullscreen</property>
+        <property name="StockId">gtk-fullscreen</property>
+        <signal name="Activated" handler="OnFullscreenActionActivated" />
+      </action>
+      <action id="f_AboutAction">
+        <property name="Type">Action</property>
+        <property name="Label" translatable="yes">_About</property>
+        <property name="ShortLabel" translatable="yes">_About</property>
+        <property name="StockId">gtk-about</property>
+        <signal name="Activated" handler="OnAboutActionActivated" />
+      </action>
+      <action id="f_OpenLogAction">
+        <property name="Type">Action</property>
+        <property name="Label" translatable="yes">Open Log</property>
+        <property name="ShortLabel" translatable="yes">Open Log</property>
+        <signal name="Activated" handler="OnOpenLogActionActivated" />
+      </action>
+      <action id="f_FindGroupChatToolAction">
+        <property name="Type">Action</property>
+        <property name="IsImportant">True</property>
+        <property name="Label" translatable="yes">Find Group Chat</property>
+        <property name="ShortLabel" translatable="yes">Find Group Chat</property>
+        <signal name="Activated" handler="OnFindGroupChatActionActivated" />
+      </action>
+      <action id="f_WebsiteAction">
+        <property name="Type">Action</property>
+        <property name="Label" translatable="yes">_Website</property>
+        <property name="ShortLabel" translatable="yes">_Website</property>
+        <signal name="Activated" handler="OnWebsiteActionActivated" />
+      </action>
+    </action-group>
+    <property name="MemberName" />
+    <property name="Visible">False</property>
+    <child>
+      <widget class="Gtk.VBox" id="vbox2">
+        <property name="MemberName" />
+        <child>
+          <widget class="Gtk.MenuBar" id="f_MenuBar">
+            <property name="MemberName" />
+            <node name="f_MenuBar" type="Menubar">
+              <node type="Menu" action="f_SmuxiAction">
+                <node type="Menuitem" action="f_PreferencesAction" />
+                <node type="Menuitem" action="f_QuitAction" />
+              </node>
+              <node type="Menu" action="ServerAction">
+                <node type="Menuitem" action="f_ConnectAction" />
+                <node type="Separator" />
+                <node type="Menuitem" action="f_AddServerAction" />
+                <node type="Menuitem" action="f_ManageServerAction" />
+              </node>
+              <node type="Menu" action="ChatAction">
+                <node type="Menuitem" action="f_JoinChatAction" />
+                <node type="Menuitem" action="f_FindGroupChatAction" />
+                <node type="Menuitem" action="f_ClearAllActivityAction" />
+                <node type="Separator" />
+                <node type="Menuitem" action="f_NextChatAction" />
+                <node type="Menuitem" action="f_PreviousChatAction" />
+                <node type="Separator" />
+                <node type="Menuitem" action="f_OpenLogAction" />
+                <node type="Menuitem" action="f_CloseChatAction" />
+              </node>
+              <node type="Menu" action="EngineAction">
+                <node type="Menuitem" action="f_UseLocalEngineAction" />
+                <node type="Separator" />
+                <node type="Menuitem" action="f_AddRemoteEngineAction" />
+                <node type="Menuitem" action="f_SwitchRemoteEngineAction" />
+              </node>
+              <node type="Menu" action="ViewAction">
+                <node type="Menuitem" action="f_CaretModeAction" />
+                <node type="Menuitem" action="f_BrowseModeAction" />
+                <node type="Menuitem" action="f_ShowMenubarAction" />
+                <node type="Menuitem" action="f_ShowStatusbarAction" />
+                <node type="Menuitem" action="f_ShowJoinBarAction" />
+                <node type="Menuitem" action="f_FullscreenAction" />
+              </node>
+              <node type="Menu" action="f_HelpAction">
+                <node type="Menuitem" action="f_WebsiteAction" />
+                <node type="Menuitem" action="f_AboutAction" />
+              </node>
+            </node>
+          </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.HBox" id="hbox1">
+            <property name="MemberName" />
+            <child>
+              <widget class="Gtk.Toolbar" id="f_MenuToolbar">
+                <property name="MemberName" />
+                <property name="ShowArrow">False</property>
+                <property name="ButtonStyle">BothHoriz</property>
+                <property name="IconSize">LargeToolbar</property>
+                <node name="f_MenuToolbar" type="Toolbar">
+                  <node type="Toolitem" action="f_ConnectToolAction" />
+                  <node type="Toolitem" action="f_FindGroupChatToolAction" />
+                  <node type="Toolitem" action="f_OpenLogToolAction" />
+                  <node type="Toolitem" action="f_FullscreenToolAction" />
+                  <node type="Toolitem" action="f_PreferencesToolAction" />
+                </node>
+              </widget>
+              <packing>
+                <property name="Position">0</property>
+                <property name="AutoSize">True</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="Gtk.Toolbar" id="f_JoinToolbar">
+                <property name="MemberName" />
+                <property name="ShowArrow">False</property>
+                <node name="f_JoinToolbar" type="Toolbar" />
+              </widget>
+              <packing>
+                <property name="PackType">End</property>
+                <property name="Position">1</property>
+                <property name="AutoSize">False</property>
+                <property name="Expand">False</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="Position">1</property>
+            <property name="AutoSize">True</property>
+            <property name="Expand">False</property>
+            <property name="Fill">False</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
 </stetic-interface>
\ No newline at end of file
diff --git a/src/Frontend-GNOME/osx/AppleEvent.cs b/src/Frontend-GNOME/osx/AppleEvent.cs
new file mode 100644
index 0000000..36c70ee
--- /dev/null
+++ b/src/Frontend-GNOME/osx/AppleEvent.cs
@@ -0,0 +1,226 @@
+// 
+// AppleEvent.cs
+//  
+// Author:
+//       Michael Hutchinson <mhutchinson at novell.com>
+// 
+// Copyright (c) 2010 Novell, Inc.
+// 
+// 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.
+using System;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+
+namespace MonoDevelop.MacInterop
+{
+    internal static class AppleEvent
+    {
+        const string AELib = Carbon.CarbonLib;
+        
+        //FIXME: is "int" correct for size?
+        [DllImport (AELib)]
+        static extern AEDescStatus AECreateDesc (OSType typeCode, IntPtr dataPtr, int dataSize, out AEDesc desc);
+        
+        [DllImport (AELib)]
+        static extern AEDescStatus AECreateDesc (OSType typeCode, byte[] data, int dataSize, out AEDesc desc);
+                
+        [DllImport (AELib)]
+        static extern AEDescStatus AEGetNthPtr (ref AEDesc descList, int index, OSType desiredType, uint keyword,
+                                                out CarbonEventParameterType actualType, IntPtr buffer, int bufferSize, out int actualSize);
+        
+        [DllImport (AELib)]
+        static extern AEDescStatus AEGetNthPtr (ref AEDesc descList, int index, OSType desiredType, uint keyword,
+                                                uint zero, IntPtr buffer, int bufferSize, int zero2);
+        
+        [DllImport (AELib)]
+        static extern AEDescStatus AECountItems (ref AEDesc descList, out int count); //return an OSErr
+        
+        [DllImport (AELib)]
+        static extern AEDescStatus AEGetNthPtr (ref AEDesc descList, int index, OSType desiredType, uint keyword,
+                                                uint zero, out IntPtr outPtr, int bufferSize, int zero2);
+        
+        [DllImport (AELib)]
+        public static extern AEDescStatus AEDisposeDesc (ref AEDesc desc);
+        
+        [DllImport (AELib)]
+        public static extern AEDescStatus AESizeOfNthItem  (ref AEDesc descList, int index, ref OSType type, out int size);
+        
+        [DllImport (AELib)]
+        static extern AEDescStatus AEGetDescData (ref AEDesc desc, IntPtr ptr, int maximumSize);
+        
+        [DllImport (AELib)]
+        static extern int AEGetDescDataSize (ref AEDesc desc);
+        
+        [DllImport (AELib)]
+        static extern AEDescStatus AECoerceDesc (ref AEDesc theAEDesc, DescType toType, ref AEDesc result);
+        
+        public static void AECreateDesc (OSType typeCode, byte[] data, out AEDesc result)
+        {
+            CheckReturn (AECreateDesc (typeCode, data, data.Length, out result));
+        }
+        
+        public static void AECreateDescUtf8 (string value, out AEDesc result)
+        {
+            var type = (OSType)(int)CarbonEventParameterType.UnicodeText;
+            var bytes = System.Text.Encoding.UTF8.GetBytes (value);
+            CheckReturn (AECreateDesc (type, bytes, bytes.Length, out result));
+        }
+        
+        public static void AECreateDescAscii (string value, out AEDesc result)
+        {
+            var type = (OSType)(int)CarbonEventParameterType.Char;
+            var bytes = System.Text.Encoding.ASCII.GetBytes (value);
+            CheckReturn (AECreateDesc (type, bytes, bytes.Length, out result));
+        }
+        
+        public static void AECreateDescNull (out AEDesc desc)
+        {
+            CheckReturn (AECreateDesc ((OSType)0, IntPtr.Zero, 0, out desc));
+        }
+        
+        public static int AECountItems (ref AEDesc descList)
+        {
+            int count;
+            CheckReturn (AECountItems (ref descList, out count));
+            return count;
+        }
+
+        public static T AEGetNthPtr<T> (ref AEDesc descList, int index, OSType desiredType) where T : struct
+        {
+            int len = Marshal.SizeOf (typeof (T));
+            IntPtr bufferPtr = Marshal.AllocHGlobal (len);
+            try {
+                CheckReturn (AEGetNthPtr (ref descList, index, desiredType, 0, 0, bufferPtr, len, 0));
+                T val = (T)Marshal.PtrToStructure (bufferPtr, typeof (T));
+                return val;
+            } finally{ 
+                Marshal.FreeHGlobal (bufferPtr);
+            }
+        }
+        
+        public static IntPtr AEGetNthPtr (ref AEDesc descList, int index, OSType desiredType)
+        {
+            IntPtr ret;
+            CheckReturn (AEGetNthPtr (ref descList, index, desiredType, 0, 0, out ret, 4, 0));
+            return ret;
+        }
+        
+        //FIXME: this might not work in some encodings. need to test more.
+        static string GetUtf8StringFromAEPtr (ref AEDesc descList, int index)
+        {
+            int size;
+            var type = (OSType)(int)CarbonEventParameterType.UnicodeText;
+            if (AESizeOfNthItem (ref descList, index, ref type, out size) == AEDescStatus.Ok) {
+                IntPtr buffer = Marshal.AllocHGlobal (size);
+                try {
+                    if (AEGetNthPtr (ref descList, index, type, 0, 0, buffer, size, 0) == AEDescStatus.Ok)
+                        return Marshal.PtrToStringAuto (buffer, size);
+                } finally {
+                    Marshal.FreeHGlobal (buffer);
+                }
+            }
+            return null;
+        }
+        
+        public static string GetStringFromAEDesc (ref AEDesc desc)
+        {
+            int size = AEGetDescDataSize (ref desc);
+            if (size > 0) {
+                IntPtr buffer = Marshal.AllocHGlobal (size);
+                try {
+                    if (AEGetDescData (ref desc, buffer, size) == AEDescStatus.Ok)
+                        return Marshal.PtrToStringAuto (buffer, size);
+                } finally {
+                    Marshal.FreeHGlobal (buffer);
+                }
+            }
+            return null;
+        }
+        
+        public static IList<string> GetUtf8StringListFromAEDesc (ref AEDesc list, bool skipEmpty)
+        {
+            long count = AppleEvent.AECountItems (ref list);
+            var items = new List<string> ();
+            for (int i = 1; i <= count; i++) {
+                string str = AppleEvent.GetUtf8StringFromAEPtr (ref list, i);
+                if (!string.IsNullOrEmpty (str))
+                    items.Add (str);
+            }
+            return items;
+        }
+        
+        public static T[] GetListFromAEDesc<T,TRef> (ref AEDesc list, AEDescValueSelector<TRef,T> sel, OSType type)
+            where TRef : struct
+        {
+            long count = AppleEvent.AECountItems (ref list);
+            T[] arr = new T[count];
+            for (int i = 1; i <= count; i++) {
+                TRef r = AppleEvent.AEGetNthPtr<TRef> (ref list, i, type);
+                arr [i - 1] = sel (ref r);
+            }
+            return arr;
+        }
+        
+        static void CheckReturn (AEDescStatus status)
+        {
+            if (status != AEDescStatus.Ok)
+            throw new Exception ("Failed with code " + status.ToString ());
+        }
+    }
+    
+    public delegate T AEDescValueSelector<TRef,T> (ref TRef desc);
+    
+    [StructLayout(LayoutKind.Sequential, Pack = 2)]
+    public struct AEDesc
+    {
+        public uint descriptorType;
+        public IntPtr dataHandle;
+    }
+    
+    public enum AEDescStatus
+    {
+        Ok = 0,
+        MemoryFull = -108,
+        CoercionFail = -1700,
+        DescRecordNotFound = -1701,
+        WrongDataType = -1703,
+        NotAEDesc = -1704,
+        ReplyNotArrived = -1718,
+    }
+    
+    public enum AESendMode {
+        NoReply = 0x00000001,
+        QueueReply = 0x00000002,
+        WaitReply = 0x00000003,
+        DontReconnect = 0x00000080,
+        WantReceipt = 0x00000200,
+        NeverInteract = 0x00000010,
+        CanInteract = 0x00000020,
+        AlwaysInteract = 0x00000030,
+        CanSwitchLayer = 0x00000040,
+        DontRecord = 0x00001000,
+        DontExecute = 0x00002000,
+        ProcessNonReplyEvents = 0x00008000,
+    }
+
+    struct DescType
+    {
+        public OSType Value;
+    }
+}
\ No newline at end of file
diff --git a/src/Frontend-GNOME/osx/ApplicationEvents.cs b/src/Frontend-GNOME/osx/ApplicationEvents.cs
new file mode 100644
index 0000000..f017521
--- /dev/null
+++ b/src/Frontend-GNOME/osx/ApplicationEvents.cs
@@ -0,0 +1,221 @@
+// 
+// ApplicationEvents.cs
+//  
+// Author:
+//       Michael Hutchinson <mhutchinson at novell.com>
+// 
+// Copyright (c) 2010 Novell, Inc. (http://www.novell.com)
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+// 
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using System.Collections.Generic;
+
+namespace MonoDevelop.MacInterop
+{
+    public static class ApplicationEvents
+    {
+        static object lockObj = new object ();
+        
+        #region Quit
+        
+        static EventHandler<ApplicationQuitEventArgs> quit;
+        static IntPtr quitHandlerRef = IntPtr.Zero;
+        
+        public static event EventHandler<ApplicationQuitEventArgs> Quit {
+            add {
+                lock (lockObj) {
+                    quit += value;
+                    if (quitHandlerRef == IntPtr.Zero)
+                        quitHandlerRef = Carbon.InstallApplicationEventHandler (HandleQuit, CarbonEventApple.QuitApplication);
+                }
+            }
+            remove {
+                lock (lockObj) {
+                    quit -= value;
+                    if (quit == null && quitHandlerRef != IntPtr.Zero) {
+                        Carbon.RemoveEventHandler (quitHandlerRef);
+                        quitHandlerRef = IntPtr.Zero;
+                    }
+                }
+            }
+        }
+        
+        static CarbonEventHandlerStatus HandleQuit (IntPtr callRef, IntPtr eventRef, IntPtr user_data)
+        {
+            var args = new ApplicationQuitEventArgs ();
+            quit (null, args);
+            return args.UserCancelled? CarbonEventHandlerStatus.UserCancelled : args.HandledStatus;
+        }
+        
+        #endregion
+        
+        #region Reopen
+        
+        static EventHandler<ApplicationEventArgs> reopen;
+        static IntPtr reopenHandlerRef = IntPtr.Zero;
+        
+        public static event EventHandler<ApplicationEventArgs> Reopen {
+            add {
+                lock (lockObj) {
+                    reopen += value;
+                    if (reopenHandlerRef == IntPtr.Zero)
+                        reopenHandlerRef = Carbon.InstallApplicationEventHandler (HandleReopen, CarbonEventApple.ReopenApplication);
+                }
+            }
+            remove {
+                lock (lockObj) {
+                    reopen -= value;
+                    if (reopen == null && reopenHandlerRef != IntPtr.Zero) {
+                        Carbon.RemoveEventHandler (reopenHandlerRef);
+                        reopenHandlerRef = IntPtr.Zero;
+                    }
+                }
+            }
+        }
+        
+        static CarbonEventHandlerStatus HandleReopen (IntPtr callRef, IntPtr eventRef, IntPtr user_data)
+        {
+            var args = new ApplicationEventArgs ();
+            reopen (null, args);
+            return args.HandledStatus;
+        }
+        
+        #endregion
+        
+        #region OpenDocuments
+        
+        static EventHandler<ApplicationDocumentEventArgs> openDocuments;
+        static IntPtr openDocumentsHandlerRef = IntPtr.Zero;
+        
+        public static event EventHandler<ApplicationDocumentEventArgs> OpenDocuments {
+            add {
+                lock (lockObj) {
+                    openDocuments += value;
+                    if (openDocumentsHandlerRef == IntPtr.Zero)
+                        openDocumentsHandlerRef = Carbon.InstallApplicationEventHandler (HandleOpenDocuments, CarbonEventApple.OpenDocuments);
+                }
+            }
+            remove {
+                lock (lockObj) {
+                    openDocuments -= value;
+                    if (openDocuments == null && openDocumentsHandlerRef != IntPtr.Zero) {
+                        Carbon.RemoveEventHandler (openDocumentsHandlerRef);
+                        openDocumentsHandlerRef = IntPtr.Zero;
+                    }
+                }
+            }
+        }
+        
+        static CarbonEventHandlerStatus HandleOpenDocuments (IntPtr callRef, IntPtr eventRef, IntPtr user_data)
+        {
+            try {
+                var docs = Carbon.GetFileListFromEventRef (eventRef);
+                var args = new ApplicationDocumentEventArgs (docs);
+                openDocuments (null, args);
+                return args.HandledStatus;
+            } catch (Exception ex) {
+                System.Console.WriteLine (ex);
+                return CarbonEventHandlerStatus.NotHandled;
+            }
+        }
+        
+        #endregion
+        
+        #region OpenUrls
+        
+        static EventHandler<ApplicationUrlEventArgs> openUrls;
+        static IntPtr openUrlsHandlerRef = IntPtr.Zero;
+        
+        public static event EventHandler<ApplicationUrlEventArgs> OpenUrls {
+            add {
+                lock (lockObj) {
+                    openUrls += value;
+                    if (openUrlsHandlerRef == IntPtr.Zero)
+                        openUrlsHandlerRef = Carbon.InstallApplicationEventHandler (HandleOpenUrls,
+                            new CarbonEventTypeSpec[] {
+                                //For some reason GetUrl doesn't take CarbonEventClass.AppleEvent
+                                //need to use GURL, GURL
+                                new CarbonEventTypeSpec (CarbonEventClass.Internet, (int)CarbonEventApple.GetUrl)
+                            }
+                        );
+                }
+            }
+            remove {
+                lock (lockObj) {
+                    openUrls -= value;
+                    if (openUrls == null && openUrlsHandlerRef != IntPtr.Zero) {
+                        Carbon.RemoveEventHandler (openUrlsHandlerRef);
+                        openUrlsHandlerRef = IntPtr.Zero;
+                    }
+                }
+            }
+        }
+        
+        static CarbonEventHandlerStatus HandleOpenUrls (IntPtr callRef, IntPtr eventRef, IntPtr user_data)
+        {
+            try {
+                var urls = Carbon.GetUrlListFromEventRef (eventRef);
+                var args = new ApplicationUrlEventArgs (urls);
+                openUrls (null, args);
+                return args.HandledStatus;
+            } catch (Exception ex) {
+                System.Console.WriteLine (ex);
+                return CarbonEventHandlerStatus.NotHandled;
+            }
+        }
+        
+        #endregion
+    }
+    
+    public class ApplicationEventArgs : EventArgs
+    {
+        public bool Handled { get; set; }
+        
+        internal CarbonEventHandlerStatus HandledStatus {
+            get {
+                return Handled? CarbonEventHandlerStatus.Handled : CarbonEventHandlerStatus.NotHandled;
+            }
+        }
+    }
+    
+    public class ApplicationQuitEventArgs : ApplicationEventArgs
+    {
+        public bool UserCancelled { get; set; }
+    }
+    
+    public class ApplicationDocumentEventArgs : ApplicationEventArgs
+    {
+        public ApplicationDocumentEventArgs (IDictionary<string,int> documents)
+        {
+            this.Documents = documents;
+        }       
+        
+        public IDictionary<string,int> Documents { get; private set; }
+    }
+    
+    public class ApplicationUrlEventArgs : ApplicationEventArgs
+    {
+        public ApplicationUrlEventArgs (IList<string> urls)
+        {
+            this.Urls = urls;
+        }       
+        
+        public IList<string> Urls { get; private set; }
+    }
+}
diff --git a/src/Frontend-GNOME/osx/Carbon.cs b/src/Frontend-GNOME/osx/Carbon.cs
new file mode 100644
index 0000000..b8e1594
--- /dev/null
+++ b/src/Frontend-GNOME/osx/Carbon.cs
@@ -0,0 +1,599 @@
+// 
+// Carbon.cs
+//  
+// Author:
+//       Michael Hutchinson <mhutchinson at novell.com>
+//       Geoff Norton  <gnorton at novell.com>
+// 
+// Copyright (c) 2009 Novell, Inc. (http://www.novell.com)
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+// 
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+using System.Diagnostics;
+
+namespace MonoDevelop.MacInterop
+{
+    internal delegate CarbonEventHandlerStatus EventDelegate (IntPtr callRef, IntPtr eventRef, IntPtr userData);
+    internal delegate CarbonEventHandlerStatus AEHandlerDelegate (IntPtr inEvnt, IntPtr outEvt, uint refConst);
+    
+    internal static class Carbon
+    {
+        public const string CarbonLib = "/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon";
+        
+        [DllImport (CarbonLib)]
+        static extern int Gestalt (int selector, out int result);
+        
+        public static int Gestalt (string selector)
+        {
+            int cc = ConvertCharCode (selector);
+            int result;
+            int ret = Gestalt (cc, out result);
+            CheckReturn (ret);
+            return result;
+        }
+        
+        [DllImport (CarbonLib)]
+        public static extern IntPtr GetApplicationEventTarget ();
+        
+        [DllImport (CarbonLib)]
+        public static extern IntPtr GetControlEventTarget (IntPtr control);
+        
+        [DllImport (CarbonLib)]
+        public static extern IntPtr GetWindowEventTarget (IntPtr window);
+        
+        [DllImport (CarbonLib)]
+        public static extern IntPtr GetMenuEventTarget (IntPtr menu);
+
+        [DllImport (CarbonLib)]
+        public static extern CarbonEventClass GetEventClass (IntPtr eventref);
+        
+        [DllImport (CarbonLib)]
+        public static extern uint GetEventKind (IntPtr eventref);
+        
+        #region Event handler installation
+        
+        [DllImport (CarbonLib)]
+        static extern EventStatus InstallEventHandler (IntPtr target, EventDelegate handler, uint count,
+                                                       CarbonEventTypeSpec [] types, IntPtr user_data, out IntPtr handlerRef);
+        
+        [DllImport (CarbonLib)]
+        public static extern EventStatus RemoveEventHandler (IntPtr handlerRef);
+        
+        public static IntPtr InstallEventHandler (IntPtr target, EventDelegate handler, CarbonEventTypeSpec [] types)
+        {
+            IntPtr handlerRef;
+            CheckReturn (InstallEventHandler (target, handler, (uint)types.Length, types, IntPtr.Zero, out handlerRef));
+            return handlerRef;
+        }
+        
+        public static IntPtr InstallEventHandler (IntPtr target, EventDelegate handler, CarbonEventTypeSpec type)
+        {
+            return InstallEventHandler (target, handler, new CarbonEventTypeSpec[] { type });
+        }
+        
+        public static IntPtr InstallApplicationEventHandler (EventDelegate handler, CarbonEventTypeSpec [] types)
+        {
+            return InstallEventHandler (GetApplicationEventTarget (), handler, types);
+        }
+        
+        public static IntPtr InstallApplicationEventHandler (EventDelegate handler, CarbonEventTypeSpec type)
+        {
+            return InstallEventHandler (GetApplicationEventTarget (), handler, new CarbonEventTypeSpec[] { type });
+        }
+        
+        #endregion
+        
+        #region Event parameter extraction
+        
+        [DllImport (CarbonLib)]
+        public static extern EventStatus GetEventParameter (IntPtr eventRef, CarbonEventParameterName name, CarbonEventParameterType desiredType,
+                                                            out CarbonEventParameterType actualType, uint size, ref uint outSize, ref IntPtr outPtr);
+        
+        public static IntPtr GetEventParameter (IntPtr eventRef, CarbonEventParameterName name, CarbonEventParameterType desiredType)
+        {
+            CarbonEventParameterType actualType;
+            uint outSize = 0;
+            IntPtr val = IntPtr.Zero;
+            CheckReturn (GetEventParameter (eventRef, name, desiredType, out actualType, (uint)IntPtr.Size, ref outSize, ref val));
+            return val;
+        } 
+        
+        [DllImport (CarbonLib)]
+        static extern EventStatus GetEventParameter (IntPtr eventRef, CarbonEventParameterName name, CarbonEventParameterType desiredType,  
+                                                     out CarbonEventParameterType actualType, uint size, ref uint outSize, IntPtr dataBuffer);
+          
+        [DllImport (CarbonLib)]
+        static extern EventStatus GetEventParameter (IntPtr eventRef, CarbonEventParameterName name, CarbonEventParameterType desiredType,  
+                                                     uint zero, uint size, uint zero2, IntPtr dataBuffer);
+        
+        public static T GetEventParameter<T> (IntPtr eventRef, CarbonEventParameterName name, CarbonEventParameterType desiredType) where T : struct
+        {
+            int len = Marshal.SizeOf (typeof (T));
+            IntPtr bufferPtr = Marshal.AllocHGlobal (len);
+            CheckReturn (GetEventParameter (eventRef, name, desiredType, 0, (uint)len, 0, bufferPtr));
+            T val = (T)Marshal.PtrToStructure (bufferPtr, typeof (T));
+            Marshal.FreeHGlobal (bufferPtr);
+            return val;
+        }
+        
+        #endregion
+        
+        #region Sending events
+        
+        [DllImport (CarbonLib)]
+        static extern EventStatus SendEventToEventTarget (IntPtr eventRef, IntPtr eventTarget);
+        
+        [DllImport (CarbonLib)]
+        static extern EventStatus CreateEvent (IntPtr allocator, CarbonEventClass classID, uint kind, double eventTime,
+                                               CarbonEventAttributes flags, out IntPtr eventHandle);
+        
+        [DllImport (CarbonLib)]
+        static extern void ReleaseEvent (IntPtr eventHandle);
+        
+        static EventStatus SendApplicationEvent (CarbonEventClass classID, uint kind, CarbonEventAttributes flags)
+        {
+            IntPtr eventHandle;
+            EventStatus s = CreateEvent (IntPtr.Zero, classID, kind, 0, flags, out eventHandle);
+            if (s != EventStatus.Ok)
+                return s;
+            s = SendEventToEventTarget (eventHandle, GetApplicationEventTarget ());
+            ReleaseEvent (eventHandle);
+            return s;
+        }
+        
+        [DllImport (CarbonLib)]
+        public static extern CarbonEventHandlerStatus ProcessHICommand (ref CarbonHICommand command);
+        
+        #endregion
+        
+        #region Error checking
+        
+        public static void CheckReturn (EventStatus status)
+        {
+            int intStatus = (int) status;
+            if (intStatus < 0)
+                throw new EventStatusException (status);
+        }
+        
+        public static void CheckReturn (int osErr)
+        {
+            if (osErr != 0) {
+                string s = GetMacOSStatusCommentString (osErr);
+                throw new SystemException ("Unexpected OS error code " + osErr + ": " + s);
+            }
+        }
+        
+        [DllImport (CarbonLib)]
+        static extern string GetMacOSStatusCommentString (int osErr);
+        
+        #endregion
+        
+        #region Char code conversion
+        
+        internal static int ConvertCharCode (string fourcc)
+        {
+            Debug.Assert (fourcc != null);
+            Debug.Assert (fourcc.Length == 4);
+            return (fourcc[3]) | (fourcc[2] << 8) | (fourcc[1] << 16) | (fourcc[0] << 24);
+        }
+        
+        internal static string UnConvertCharCode (int i)
+        {
+            return new string (new char[] {
+                (char)(i >> 24),
+                (char)(0xFF & (i >> 16)),
+                (char)(0xFF & (i >> 8)),
+                (char)(0xFF & i),
+            });
+        }
+        
+        #endregion
+        
+        #region Internal Mac API for setting process name
+        
+        [DllImport (CarbonLib)]
+        static extern int GetCurrentProcess (out ProcessSerialNumber psn);
+        
+        [DllImport (CarbonLib)]
+        static extern int CPSSetProcessName (ref ProcessSerialNumber psn, string name);
+        
+        public static void SetProcessName (string name)
+        {
+            try {
+                ProcessSerialNumber psn;
+                if (GetCurrentProcess (out psn) == 0)
+                    CPSSetProcessName (ref psn, name);
+            } catch {} //EntryPointNotFoundException?
+        }
+        
+        struct ProcessSerialNumber {
+#pragma warning disable 0169
+            ulong highLongOfPSN;
+            ulong lowLongOfPSN;
+#pragma warning restore 0169
+        }
+        
+        #endregion
+        
+        public static Dictionary<string,int> GetFileListFromEventRef (IntPtr eventRef)
+        {
+            AEDesc list = GetEventParameter<AEDesc> (eventRef, CarbonEventParameterName.DirectObject, CarbonEventParameterType.AEList);
+            try {
+                int line = 0;
+                try {
+                    SelectionRange range = GetEventParameter<SelectionRange> (eventRef, CarbonEventParameterName.AEPosition, CarbonEventParameterType.Char);
+                    line = range.lineNum+1;
+                } catch {
+                }
+                
+                var arr = AppleEvent.GetListFromAEDesc<string,FSRef> (ref list, CoreFoundation.FSRefToString,
+                    (OSType)(int)CarbonEventParameterType.FSRef);
+                var files = new Dictionary<string,int> ();
+                foreach (var s in arr) {
+                    if (!string.IsNullOrEmpty (s))
+                        files[s] = line;
+                }
+                return files;
+            } finally {
+                CheckReturn ((int)AppleEvent.AEDisposeDesc (ref list));
+            }
+        }
+        
+        public static IList<string> GetUrlListFromEventRef (IntPtr eventRef)
+        {
+            AEDesc list = GetEventParameter<AEDesc> (eventRef, CarbonEventParameterName.DirectObject, CarbonEventParameterType.AEList);
+            try {
+                return AppleEvent.GetUtf8StringListFromAEDesc (ref list, true);
+            } finally {
+                Carbon.CheckReturn ((int)AppleEvent.AEDisposeDesc (ref list));
+            }
+        }
+    }
+    
+    [StructLayout(LayoutKind.Sequential, Pack = 2, Size = 80)]
+    struct FSRef
+    {
+        //this is an 80-char opaque byte array
+        #pragma warning disable 0169
+        private byte hidden;
+        #pragma warning restore 0169
+    }
+    
+    [StructLayout(LayoutKind.Sequential)]
+    struct SelectionRange
+    {
+        public short unused1; // 0 (not used)
+        public short lineNum; // line to select (<0 to specify range)
+        public int startRange; // start of selection range (if line < 0)
+        public int endRange; // end of selection range (if line < 0)
+        public int unused2; // 0 (not used)
+        public int theDate; // modification date/time
+    }
+    
+    internal enum CarbonEventHandlerStatus //this is an OSStatus
+    {
+        Handled = 0,
+        NotHandled = -9874,
+        UserCancelled = -128,
+    }
+    
+    internal enum CarbonEventParameterName : uint
+    {
+        DirectObject = 757935405, // '----'
+        AEPosition = 1802530675, // 'kpos'
+    }
+    
+    internal enum CarbonEventParameterType : uint
+    {
+        HICommand = 1751346532, // 'hcmd'
+        MenuRef = 1835363957, // 'menu'
+        WindowRef = 2003398244, // 'wind'
+        Char = 1413830740, // 'TEXT'
+        UInt32 = 1835100014, // 'magn'
+        UnicodeText = 1970567284, // 'utxt'
+        AEList = 1818850164, // 'list'
+        WildCard = 707406378, // '****'
+        FSRef = 1718841958, // 'fsrf' 
+    }
+    
+    internal enum CarbonEventClass : uint
+    {
+        Mouse = 1836021107, // 'mous'
+        Keyboard = 1801812322, // 'keyb'
+        TextInput = 1952807028, // 'text'
+        Application = 1634758764, // 'appl'
+        RemoteAppleEvent = 1701867619,  //'eppc' //remote apple event?
+        Menu = 1835363957, // 'menu'
+        Window = 2003398244, // 'wind'
+        Control = 1668183148, // 'cntl'
+        Command = 1668113523, // 'cmds'
+        Tablet = 1952607348, // 'tblt'
+        Volume = 1987013664, // 'vol '
+        Appearance = 1634758765, // 'appm'
+        Service = 1936028278, // 'serv'
+        Toolbar = 1952604530, // 'tbar'
+        ToolbarItem = 1952606580, // 'tbit'
+        Accessibility = 1633903461, // 'acce'
+        HIObject = 1751740258, // 'hiob'
+        AppleEvent = 1634039412, // 'aevt'
+        Internet = 1196773964, // 'GURL'
+    }
+    
+    public enum CarbonCommandID : uint
+    {
+        OK = 1869291552, // 'ok  '
+        Cancel = 1852797985, // 'not!'
+        Quit = 1903520116, // 'quit'
+        Undo = 1970168943, // 'undo'
+        Redo = 1919247471, // 'redo'
+        Cut = 1668641824, // 'cut '
+        Copy = 1668247673, // 'copy'
+        Paste = 1885434740, // 'past'
+        Clear = 1668048225, // 'clea',
+        SelectAll = 1935764588, // 'sall',
+        Preferences = 1886545254, //'pref'
+        About = 1633841013, // 'abou'
+        New = 1852143392, // 'new ',
+        Open = 1869636974, // 'open'
+        Close = 1668050803, // 'clos'
+        Save = 1935767141, // 'save',
+        SaveAs = 1937138035, // 'svas'
+        Revert = 1920365172, // 'rvrt'
+        Print = 1886547572, // 'prnt'
+        PageSetup = 1885431653, // 'page',
+        AppHelp = 1634233456, //'ahlp'
+        
+        //menu manager handles these automatically
+        
+        Hide = 1751737445, // 'hide'
+        HideOthers = 1751737455, // 'hido'
+        ShowAll = 1936220524, // 'shal'
+        ZoomWindow = 2054123373, // 'zoom'
+        MinimizeWindow = 1835626089, // 'mini'
+        MinimizeAll = 1835626081, // 'mina'
+        MaximizeAll = 1835104353, // 'maxa'
+        ArrangeInFront = 1718775412, // 'frnt'
+        BringAllToFront = 1650881140, // 'bfrt'
+        SelectWindow = 1937205614, // 'swin'
+        RotateWindowsForward = 1919906935, // 'rotw'
+        RotateWindowsBackward = 1919906914, // 'rotb'
+        RotateFloatingWindowsForward = 1920231031, // 'rtfw'
+        RotateFloatingWindowsBackward = 1920231010, // 'rtfb'
+        
+        //created automatically -- used for inserting before/after the default window list
+        WindowListSeparator = 2003592310, // 'wldv'
+        WindowListTerminator = 2003596148, // 'wlst'
+    }
+    
+    internal enum CarbonEventCommand : uint
+    {
+        Process = 1,
+        UpdateStatus = 2,
+    }
+    
+    internal enum CarbonEventMenu : uint
+    {
+        BeginTracking = 1,
+        EndTracking = 2,
+        ChangeTrackingMode = 3,
+        Opening = 4,
+        Closed = 5,
+        TargetItem = 6,
+        MatchKey = 7,
+    }
+    
+    internal enum CarbonEventAttributes : uint
+    {
+        None = 0,
+        UserEvent = (1 << 0),
+        Monitored= 1 << 3,
+    }
+    
+    internal enum CarbonEventApple
+    {
+        OpenApplication = 1868656752, // 'oapp'
+        ReopenApplication = 1918988400, //'rapp'
+        OpenDocuments = 1868853091, // 'odoc'
+        PrintDocuments = 188563030, // 'pdoc'
+        OpenContents = 1868787566, // 'ocon'
+        QuitApplication =  1903520116, // 'quit'
+        ShowPreferences = 1886545254, // 'pref'
+        ApplicationDied = 1868720500, // 'obit'
+        GetUrl = 1196773964, // 'GURL'
+    }
+    
+    [StructLayout(LayoutKind.Sequential, Pack = 2)]
+    struct CarbonEventTypeSpec
+    {
+        public CarbonEventClass EventClass;
+        public uint EventKind;
+
+        public CarbonEventTypeSpec (CarbonEventClass eventClass, UInt32 eventKind)
+        {
+            this.EventClass = eventClass;
+            this.EventKind = eventKind;
+        }
+        
+        public CarbonEventTypeSpec (CarbonEventMenu kind) : this (CarbonEventClass.Menu, (uint) kind)
+        {
+        }
+        
+        public CarbonEventTypeSpec (CarbonEventCommand kind) : this (CarbonEventClass.Command, (uint) kind)
+        {
+        }
+        
+        
+        public CarbonEventTypeSpec (CarbonEventApple kind) : this (CarbonEventClass.AppleEvent, (uint) kind)
+        {
+        }
+        
+        public static implicit operator CarbonEventTypeSpec (CarbonEventMenu kind)
+        {
+            return new CarbonEventTypeSpec (kind);
+        }
+        
+        public static implicit operator CarbonEventTypeSpec (CarbonEventCommand kind)
+        {
+            return new CarbonEventTypeSpec (kind);
+        }
+        
+        public static implicit operator CarbonEventTypeSpec (CarbonEventApple kind)
+        {
+            return new CarbonEventTypeSpec (kind);
+        }
+    }
+    
+    class EventStatusException : SystemException
+    {
+        public EventStatusException (EventStatus status)
+        {
+            StatusCode = status;
+        }
+        
+        public EventStatus StatusCode {
+            get; private set;
+        }
+    }
+    
+    enum EventStatus // this is an OSStatus
+    {
+        Ok = 0,
+        
+        //event manager
+        EventAlreadyPostedErr = -9860,
+        EventTargetBusyErr = -9861,
+        EventClassInvalidErr = -9862,
+        EventClassIncorrectErr = -9864,
+        EventHandlerAlreadyInstalledErr = -9866,
+        EventInternalErr = -9868,
+        EventKindIncorrectErr = -9869,
+        EventParameterNotFoundErr = -9870,
+        EventNotHandledErr = -9874,
+        EventLoopTimedOutErr = -9875,
+        EventLoopQuitErr = -9876,
+        EventNotInQueueErr = -9877,
+        EventHotKeyExistsErr = -9878,
+        EventHotKeyInvalidErr = -9879,
+    }
+    
+    [StructLayout(LayoutKind.Explicit)]
+    struct CarbonHICommand //technically HICommandExtended, but they're compatible
+    {
+        [FieldOffset(0)]
+        CarbonHICommandAttributes attributes;
+        
+        [FieldOffset(4)]
+        uint commandID;
+        
+        [FieldOffset(8)]
+        IntPtr controlRef;
+        
+        [FieldOffset(8)]
+        IntPtr windowRef;
+        
+        [FieldOffset(8)]
+        HIMenuItem menuItem;
+        
+        public CarbonHICommand (uint commandID, HIMenuItem item)
+        {
+            windowRef = controlRef = IntPtr.Zero;
+            this.commandID = commandID;
+            this.menuItem = item;
+            this.attributes = CarbonHICommandAttributes.FromMenu;
+        }
+        
+        public CarbonHICommandAttributes Attributes { get { return attributes; } }
+        public uint CommandID { get { return commandID; } }
+        public IntPtr ControlRef { get { return controlRef; } }
+        public IntPtr WindowRef { get { return windowRef; } }
+        public HIMenuItem MenuItem { get { return menuItem; } }
+        
+        public bool IsFromMenu {
+            get { return attributes == CarbonHICommandAttributes.FromMenu; }
+        }
+        
+        public bool IsFromControl {
+            get { return attributes == CarbonHICommandAttributes.FromControl; }
+        }
+        
+        public bool IsFromWindow {
+            get { return attributes == CarbonHICommandAttributes.FromWindow; }
+        }
+    }
+    
+    [StructLayout(LayoutKind.Sequential, Pack = 2)]
+    struct HIMenuItem
+    {
+        IntPtr menuRef;
+        ushort index;
+        
+        public HIMenuItem (IntPtr menuRef, ushort index)
+        {
+            this.index = index;
+            this.menuRef = menuRef;
+        }
+        
+        public IntPtr MenuRef { get { return menuRef; } }
+        public ushort Index { get { return index; } }
+    }
+    
+    //*NOT* flags
+    enum CarbonHICommandAttributes : uint
+    {
+        FromMenu = 1,
+        FromControl = 1 << 1,
+        FromWindow  = 1 << 2,
+    }
+    
+    struct OSType {
+        int value;
+        
+        public int Value {
+            get { return Value; }
+        }
+        
+        public OSType (int value)
+        {
+            this.value = value;
+        }
+        
+        public OSType (string fourcc)
+        {
+            value = Carbon.ConvertCharCode (fourcc);
+        }
+        
+        public static explicit operator OSType (string fourcc)
+        {
+            return new OSType (fourcc); 
+        }
+        
+        public static implicit operator int (OSType o)
+        {
+            return o.value;
+        }
+        
+        public static implicit operator OSType (int i)
+        {
+            return new OSType (i);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Frontend-GNOME/osx/CoreFoundation.cs b/src/Frontend-GNOME/osx/CoreFoundation.cs
new file mode 100644
index 0000000..fe00db5
--- /dev/null
+++ b/src/Frontend-GNOME/osx/CoreFoundation.cs
@@ -0,0 +1,228 @@
+// 
+// CoreFoundation.cs
+//  
+// Author:
+//       Michael Hutchinson <mhutchinson at novell.com>
+//       Miguel de Icaza
+// 
+// Copyright (c) 2009 Novell, Inc. (http://www.novell.com)
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+// 
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace MonoDevelop.MacInterop
+{
+    internal static class CoreFoundation
+    {
+        const string CFLib = "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation";
+        const string LSLib = "/System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices";
+        
+        [DllImport (CFLib)]
+        static extern IntPtr CFStringCreateWithCString (IntPtr alloc, string str, int encoding);
+        
+        public static IntPtr CreateString (string s)
+        {
+            // The magic value is "kCFStringENcodingUTF8"
+            return CFStringCreateWithCString (IntPtr.Zero, s, 0x08000100);
+        }
+        
+        [DllImport (CFLib, EntryPoint="CFRelease")]
+        public static extern void Release (IntPtr cfRef);
+        
+        struct CFRange {
+            public int Location, Length;
+            public CFRange (int l, int len)
+            {
+                Location = l;
+                Length = len;
+            }
+        }
+        
+        [DllImport (CFLib, CharSet=CharSet.Unicode)]
+        extern static int CFStringGetLength (IntPtr handle);
+
+        [DllImport (CFLib, CharSet=CharSet.Unicode)]
+        extern static IntPtr CFStringGetCharactersPtr (IntPtr handle);
+        
+        [DllImport (CFLib, CharSet=CharSet.Unicode)]
+        extern static IntPtr CFStringGetCharacters (IntPtr handle, CFRange range, IntPtr buffer);
+        
+        public static string FetchString (IntPtr handle)
+        {
+            if (handle == IntPtr.Zero)
+                return null;
+            
+            string str;
+            
+            int l = CFStringGetLength (handle);
+            IntPtr u = CFStringGetCharactersPtr (handle);
+            IntPtr buffer = IntPtr.Zero;
+            if (u == IntPtr.Zero){
+                CFRange r = new CFRange (0, l);
+                buffer = Marshal.AllocCoTaskMem (l * 2);
+                CFStringGetCharacters (handle, r, buffer);
+                u = buffer;
+            }
+
+            /*
+            unsafe {
+                str = new string ((char *) u, 0, l);
+            }
+            */
+            str = Marshal.PtrToStringUni(u, l);
+
+            if (buffer != IntPtr.Zero)
+                Marshal.FreeCoTaskMem (buffer);
+            
+            return str;
+        }
+        
+        public static string FSRefToString (ref FSRef fsref)
+        {
+            IntPtr url = IntPtr.Zero;
+            IntPtr str = IntPtr.Zero;
+            try {
+                url = CFURLCreateFromFSRef (IntPtr.Zero, ref fsref);
+                if (url == IntPtr.Zero)
+                    return null;
+                str = CFURLCopyFileSystemPath (url, CFUrlPathStyle.Posix);
+                if (str == IntPtr.Zero)
+                    return null;
+                return FetchString (str);
+            } finally {
+                if (url != IntPtr.Zero)
+                    Release (url);
+                if (str != IntPtr.Zero)
+                    Release (str);
+            }
+        }
+        
+        [DllImport (CFLib)]
+        extern static IntPtr CFURLCreateFromFSRef (IntPtr allocator, ref FSRef fsref);
+        
+        [DllImport (CFLib)]
+        extern static IntPtr CFURLCopyFileSystemPath (IntPtr urlRef, CFUrlPathStyle pathStyle);
+        
+        enum CFUrlPathStyle
+        {
+            Posix = 0,
+            Hfs = 1,
+            Windows = 2
+        };
+        
+        [DllImport (CFLib)]
+        extern static IntPtr CFURLCreateWithFileSystemPath (IntPtr allocator, IntPtr filePathString, 
+            CFUrlPathStyle pathStyle, bool isDirectory);
+        
+        [DllImport (LSLib)]
+        extern static IntPtr LSCopyApplicationURLsForURL (IntPtr urlRef, LSRolesMask roleMask); //CFArrayRef
+        
+        [DllImport (LSLib)]
+        extern static int LSGetApplicationForURL (IntPtr url, LSRolesMask roleMask, IntPtr fsRefZero,
+            ref IntPtr  appUrl);
+        
+        [DllImport (CFLib)]
+        extern static int CFArrayGetCount (IntPtr theArray);
+        
+        [DllImport (CFLib)]
+        extern static IntPtr CFArrayGetValueAtIndex (IntPtr theArray, int idx);
+        
+        [Flags]
+        public enum LSRolesMask : uint
+        {
+            None = 0x00000001,
+            Viewer = 0x00000002,
+            Editor = 0x00000004,
+            Shell = 0x00000008,
+            All = 0xFFFFFFFF
+        }
+        
+        static IntPtr CreatePathUrl (string path)
+        {
+            IntPtr str = IntPtr.Zero;
+            IntPtr url = IntPtr.Zero;
+            try {
+                str = CreateString (path);
+                if (str == IntPtr.Zero)
+                    throw new Exception ("CreateString failed");
+                url = CFURLCreateWithFileSystemPath (IntPtr.Zero, str, CFUrlPathStyle.Posix, false);
+                if (url == IntPtr.Zero)
+                    throw new Exception ("CFURLCreateWithFileSystemPath failed");
+                return url;
+            } finally {
+                if (str != IntPtr.Zero)
+                    Release (str);
+            }
+        }
+        
+        public static string UrlToPath (IntPtr url)
+        {
+            IntPtr str = IntPtr.Zero;
+            try {
+                str = CFURLCopyFileSystemPath (url, CFUrlPathStyle.Posix);
+                return str == IntPtr.Zero? null : FetchString (str);
+            } finally {
+                if (str != IntPtr.Zero)
+                    Release (str);
+            }
+        }
+        
+        public static string GetApplicationUrl (string filePath, LSRolesMask roles)
+        {
+            IntPtr url = IntPtr.Zero;
+            try {
+                url = CreatePathUrl (filePath);
+                IntPtr appUrl = IntPtr.Zero;
+                if (LSGetApplicationForURL (url, roles, IntPtr.Zero, ref appUrl) == 0 && appUrl != IntPtr.Zero)
+                    return UrlToPath (appUrl);
+                return null;
+            } finally {
+                if (url != IntPtr.Zero)
+                    Release (url);
+            }
+        }
+        
+        public static string[] GetApplicationUrls (string filePath, LSRolesMask roles)
+        {
+            IntPtr url = IntPtr.Zero;
+            IntPtr arr = IntPtr.Zero;
+            try {
+                url = CreatePathUrl (filePath);
+                arr = LSCopyApplicationURLsForURL (url, roles);
+                if (arr == IntPtr.Zero)
+                    return new string[0];
+                int count = CFArrayGetCount (arr);
+                string[] values = new string [count];
+                for (int i = 0; i < values.Length; i++ ) {
+                    var u = CFArrayGetValueAtIndex (arr, i);
+                    if (u != IntPtr.Zero)
+                        values[i] = UrlToPath (u);
+                }
+                return values;
+            } finally {
+                if (url != IntPtr.Zero)
+                    Release (url);
+                if (arr != IntPtr.Zero)
+                    Release (arr);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Frontend-GNOME/osx/IgeMacMenu.cs b/src/Frontend-GNOME/osx/IgeMacMenu.cs
new file mode 100644
index 0000000..4ef2838
--- /dev/null
+++ b/src/Frontend-GNOME/osx/IgeMacMenu.cs
@@ -0,0 +1,67 @@
+using System;
+using System.Collections;
+using System.Runtime.InteropServices;
+
+namespace IgeMacIntegration {
+
+    public class IgeMacMenu {
+
+        [DllImport("libigemacintegration.dylib")]
+        static extern void ige_mac_menu_connect_window_key_handler (IntPtr window);
+
+        public static void ConnectWindowKeyHandler (Gtk.Window window)
+        {
+            ige_mac_menu_connect_window_key_handler (window.Handle);
+        }
+
+        [DllImport("libigemacintegration.dylib")]
+        static extern void ige_mac_menu_set_global_key_handler_enabled (bool enabled);
+
+        public static bool GlobalKeyHandlerEnabled {
+            set { 
+                ige_mac_menu_set_global_key_handler_enabled (value);
+            }
+        }
+
+        [DllImport("libigemacintegration.dylib")]
+        static extern void ige_mac_menu_set_menu_bar(IntPtr menu_shell);
+
+        public static Gtk.MenuShell MenuBar { 
+            set {
+                ige_mac_menu_set_menu_bar(value == null ? IntPtr.Zero : value.Handle);
+            }
+        }
+
+        [DllImport("libigemacintegration.dylib")]
+        static extern void ige_mac_menu_set_quit_menu_item(IntPtr quit_item);
+
+        public static Gtk.MenuItem QuitMenuItem { 
+            set {
+                ige_mac_menu_set_quit_menu_item(value == null ? IntPtr.Zero : value.Handle);
+            }
+        }
+
+        [DllImport("libigemacintegration.dylib")]
+        static extern IntPtr ige_mac_menu_add_app_menu_group();
+
+        public static IgeMacIntegration.IgeMacMenuGroup AddAppMenuGroup() {
+            IntPtr raw_ret = ige_mac_menu_add_app_menu_group();
+            IgeMacIntegration.IgeMacMenuGroup ret = raw_ret == IntPtr.Zero ? null : (IgeMacIntegration.IgeMacMenuGroup) GLib.Opaque.GetOpaque (raw_ret, typeof (IgeMacIntegration.IgeMacMenuGroup), false);
+            return ret;
+        }
+    }
+
+    public class IgeMacMenuGroup : GLib.Opaque {
+
+        [DllImport("libigemacintegration.dylib")]
+        static extern void ige_mac_menu_add_app_menu_item(IntPtr raw, IntPtr menu_item, IntPtr label);
+
+        public void AddMenuItem(Gtk.MenuItem menu_item, string label) {
+            IntPtr native_label = GLib.Marshaller.StringToPtrGStrdup (label);
+            ige_mac_menu_add_app_menu_item(Handle, menu_item == null ? IntPtr.Zero : menu_item.Handle, native_label);
+            GLib.Marshaller.Free (native_label);
+        }
+
+        public IgeMacMenuGroup(IntPtr raw) : base(raw) {}
+    }
+}
\ No newline at end of file
diff --git a/src/Frontend-GNOME/smuxi-frontend-gnome.exe.config b/src/Frontend-GNOME/smuxi-frontend-gnome.exe.config
index 528d6be..66dff12 100644
--- a/src/Frontend-GNOME/smuxi-frontend-gnome.exe.config
+++ b/src/Frontend-GNOME/smuxi-frontend-gnome.exe.config
@@ -3,7 +3,9 @@
     <configSections>
         <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
     </configSections>
-    <dllmap os="!windows" dll="gtkspell.dll" target="libgtkspell.so.0" />
+    <dllmap os="!windows,osx" dll="gtkspell.dll" target="libgtkspell.so.0" />
+    <dllmap os="!windows,osx" dll="libgtk-win32-2.0-0.dll" target="libgtk-x11-2.0.so.0" />
+    <dllmap os="osx" dll="libgtk-win32-2.0-0.dll" target="libgtk-quartz-2.0.0.dylib" />
     <log4net>
         <root>
             <appender-ref ref="ConsoleAppender" />
diff --git a/src/Frontend-STFL/ChatView.cs b/src/Frontend-STFL/ChatView.cs
deleted file mode 100644
index 74260e7..0000000
--- a/src/Frontend-STFL/ChatView.cs
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * Smuxi - Smart MUltipleXed Irc
- *
- * Copyright (c) 2007, 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.Text;
-using System.Collections.Generic;
-using System.Globalization;
-using Smuxi.Common;
-using Smuxi.Engine;
-using Smuxi.Frontend;
-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, IDisposable
-    {
-#if LOG4NET
-        static readonly log4net.ILog _Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
-#endif
-        // 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 f_ChatModel;
-            }
-        }
-
-        public string ID {
-            get {
-                return ChatModel.ID;
-            }
-        }
-
-        public int Position {
-            get {
-                return ChatModel.Position;
-            }
-        }
-
-        public bool IsVisible {
-            get {
-                return f_MainWindow[f_WidgetID + "d"] == "1";
-            }
-            set {
-                f_MainWindow[f_WidgetID + "d"] = value ?  "1" : "0";
-           }
-        }
-
-        public string WidgetName {
-            get {
-                return f_WidgetName;
-            }
-        }
-
-        public ChatView(ChatModel chat, MainWindow window)
-        {
-            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)
-        {
-            Trace.Call(disposing);
-
-            // do not make STFL calls from the finalizer thread!
-            if (disposing) {
-                f_MainWindow.Modify(f_WidgetName, "delete", null);
-            }
-        }
-
-        public virtual void Dispose()
-        {
-            Dispose(true);
-            GC.SuppressFinalize(this);
-        }
-
-        public virtual void Enable()
-        {
-            Trace.Call();
-        }
-        
-        public virtual void Disable()
-        {
-            Trace.Call();
-        }
-        
-        public virtual void Sync()
-        {
-#if LOG4NET
-            _Logger.Debug("Sync() syncing messages");
-#endif
-            // sync messages
-            // cleanup, be sure the output is empty
-            f_MainWindow.Modify("output_textview", "replace_inner", "");
-            
-            IList<MessageModel> messages = f_ChatModel.Messages;
-            if (messages.Count > 0) {
-                foreach (MessageModel msg in messages) {
-                    AddMessage(msg);
-                }
-            }
-        }
-        
-        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 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;
-            }
-            var finalMsg = String.Format("{0} {1}", timestamp, line.ToString());
-            MessageTextView.AppendLine(finalMsg);
-
-            ScrollToEnd();
-        }
-
-        public void ScrollUp()
-        {
-            Trace.Call();
-
-            MessageTextView.ScrollUp();
-        }
-
-        public void ScrollDown()
-        {
-            Trace.Call();
-
-            MessageTextView.ScrollDown();
-        }
-
-        public void ScrollToStart()
-        {
-            Trace.Call();
-
-            MessageTextView.ScrollToStart();
-        }
-
-        public void ScrollToEnd()
-        {
-            Trace.Call();
-
-            MessageTextView.ScrollToEnd();
-        }
-    }
-}
diff --git a/src/Frontend-STFL/ChatViewManager.cs b/src/Frontend-STFL/ChatViewManager.cs
index 136c8f8..f6f12a5 100644
--- a/src/Frontend-STFL/ChatViewManager.cs
+++ b/src/Frontend-STFL/ChatViewManager.cs
@@ -1,7 +1,7 @@
 /*
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2007, 2010-2011 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2007, 2010-2013 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -65,6 +65,8 @@ namespace Smuxi.Frontend.Stfl
                     _Logger.Debug("set_CurrentChat(): making " + value.ChatModel.ID + " visible");
 #endif
                     f_CurrentChat.IsVisible = true;
+                    UpdateNavigation();
+                    UpdateInput();
                     UpdateTitle();
                 }
 
@@ -153,11 +155,12 @@ namespace Smuxi.Frontend.Stfl
             return f_ChatViewList[chat];
         }
 
-        private void UpdateNavigation()
+        public void UpdateNavigation()
         {
             var nav = new StringBuilder();
             foreach (var chat in f_ChatViewList) {
-                nav.AppendFormat("[{0}] ", chat.ChatModel.Name);
+                nav.AppendFormat("[{0}] ",
+                                 chat == CurrentChat ? chat.Name : chat.Label);
             }
             if (nav.Length > 0) {
                 nav.Length--;
@@ -166,6 +169,16 @@ namespace Smuxi.Frontend.Stfl
             f_MainWindow.NavigationLabel = nav.ToString();
         }
 
+        public void UpdateInput()
+        {
+            var chatView = CurrentChat;
+            if (chatView == null) {
+                return;
+            }
+
+            f_MainWindow.InputLabel = String.Format("[{0}]", chatView.Name);
+        }
+
         void UpdateTitle()
         {
             var chatView = CurrentChat;
diff --git a/src/Frontend-STFL/Entry.cs b/src/Frontend-STFL/Entry.cs
index a04e5dc..d16ab50 100644
--- a/src/Frontend-STFL/Entry.cs
+++ b/src/Frontend-STFL/Entry.cs
@@ -1,7 +1,7 @@
 /*
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2007, 2010-2011 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2007, 2010-2013 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>
@@ -38,6 +38,9 @@ namespace Smuxi.Frontend.Stfl
 #endif
         MainWindow      f_MainWindow;
         ChatViewManager f_ChatViewManager;
+        CommandManager CommandManager { get; set; }
+        NickCompleter NickCompleter { get; set; }
+        EntrySettings Settings { get; set; }
 
         event EventHandler Activated;
 
@@ -61,20 +64,62 @@ namespace Smuxi.Frontend.Stfl
         
         public Entry(MainWindow mainWindow, ChatViewManager chatViewManager)
         {
-           if (mainWindow == null) {
+            if (mainWindow == null) {
                 throw new ArgumentNullException("mainWindow");
-           }
-           if (chatViewManager == null) {
+            }
+            if (chatViewManager == null) {
                 throw new ArgumentNullException("chatViewManager");
-           }
+            }
 
             f_MainWindow = mainWindow;
             f_MainWindow.KeyPressed += OnKeyPressed;
             
             f_ChatViewManager = chatViewManager;
-            f_ChatViewManager.CurrentChatSwitched += OnChatSwitched;
+
+            Frontend.SessionPropertyChanged += delegate {
+                InitCommandManager();
+            };
+
+            Settings = new EntrySettings();
+            NickCompleter = new TabCycleNickCompleter();
         }
         
+        public virtual void ApplyConfig(UserConfig config)
+        {
+            Trace.Call(config);
+
+            if (config == null) {
+                throw new ArgumentNullException("config");
+            }
+
+            Settings.ApplyConfig(config);
+
+            // replace nick completer if needed
+            if (Settings.BashStyleCompletion && !(NickCompleter is LongestPrefixNickCompleter)) {
+                NickCompleter = new LongestPrefixNickCompleter();
+            } else if (!Settings.BashStyleCompletion && !(NickCompleter is TabCycleNickCompleter)) {
+                NickCompleter = new TabCycleNickCompleter();
+            }
+
+            // set the completion character
+            NickCompleter.CompletionChar = Settings.CompletionCharacter;
+        }
+
+        void InitCommandManager()
+        {
+            Trace.Call();
+
+            if (CommandManager != null) {
+                CommandManager.Dispose();
+            }
+
+            if (Frontend.Session == null) {
+                CommandManager = null;
+            } else {
+                CommandManager = new CommandManager(Frontend.Session);
+            }
+        }
+
         private void OnKeyPressed(object sender, KeyPressedEventArgs e)
         {
             Trace.Call(sender, e);
@@ -96,6 +141,9 @@ namespace Smuxi.Frontend.Stfl
                         f_ChatViewManager.ActiveChat.ScrollDown();
                     }
                     break;
+                case "TAB":
+                    CompleteNick();
+                    break;
                 case "kPRV5": // CTRL + PAGE UP
                 case "^P":
                     f_ChatViewManager.CurrentChatNumber--;
@@ -119,14 +167,6 @@ namespace Smuxi.Frontend.Stfl
             }
         }
 
-        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)
         {
             var text = Text;
@@ -150,29 +190,23 @@ namespace Smuxi.Frontend.Stfl
             }
 
             ChatModel chat = null;
-            if (f_MainWindow.ChatViewManager.ActiveChat != null) {
-                chat = f_MainWindow.ChatViewManager.ActiveChat.ChatModel;
-            }
-            bool handled = false;
-            CommandModel cd = new CommandModel(Frontend.FrontendManager, chat,
-                                               (string)Frontend.UserConfig["Interface/Entry/CommandCharacter"],
-                                               cmd);
-            handled = Command(cd);
-            if (!handled) {
-                handled = Frontend.Session.Command(cd);
-            }
-            if (!handled) {
-                // we may have no network manager yet
-                Engine.IProtocolManager nm = Frontend.FrontendManager.CurrentProtocolManager;
-                if (nm != null) {
-                    handled = nm.Command(cd);
-                } else {
-                    handled = false;
-                }
+            var currentChat = f_ChatViewManager.CurrentChat;
+            if (currentChat != null) {
+                chat = currentChat.ChatModel;
             }
-            if (!handled) {
-               _CommandUnknown(cd);
+            CommandModel cd = new CommandModel(
+                Frontend.FrontendManager,
+                chat,
+                (string) Frontend.UserConfig["Interface/Entry/CommandCharacter"],
+                cmd
+            );
+
+            var handled = Command(cd);
+            if (handled) {
+                return;
             }
+
+            CommandManager.Execute(cd);
         }
 
         private bool Command(CommandModel cmd)
@@ -195,8 +229,11 @@ namespace Smuxi.Frontend.Stfl
 #if LOG4NET
                         _Logger.Debug("GC.Collect()");
 #endif
-                        cmd.FrontendManager.AddTextToChat(cmd.Chat,
-                            "-!- GCing...");
+                        var msg = new MessageBuilder().
+                            AppendEventPrefix().
+                            AppendText("GCing...").
+                            ToMessage();
+                        cmd.FrontendManager.AddMessageToChat(cmd.Chat, msg);
                         GC.Collect();
                         handled = true;
                         break;
@@ -216,7 +253,7 @@ namespace Smuxi.Frontend.Stfl
 
             string[] help = {
                 "help",
-                "window number",
+                "window (number|close)",
                 "exit",
             };
 
@@ -230,6 +267,11 @@ namespace Smuxi.Frontend.Stfl
 
         private void CommandWindow(CommandModel cmd)
         {
+            if (cmd.Parameter == "close") {
+                f_ChatViewManager.CurrentChat.Close();
+                return;
+            }
+
             int window;
             if (!Int32.TryParse(cmd.Parameter, out window)) {
                 return;
@@ -241,12 +283,13 @@ namespace Smuxi.Frontend.Stfl
             f_ChatViewManager.CurrentChat = chat;
         }
 
-        private void _CommandUnknown(CommandModel cd)
+        private void CommandUnknown(CommandModel cmd)
         {
-            cd.FrontendManager.AddTextToChat(cd.Chat, "-!- " +
-                                String.Format(Catalog.GetString(
-                                              "Unknown Command: {0}"),
-                                              cd.Command));
+            var msg = new MessageBuilder().
+                AppendEventPrefix().
+                AppendText(_("Unknown Command: {0}"), cmd.Command).
+                ToMessage();
+            cmd.FrontendManager.AddMessageToChat(cmd.Chat, msg);
         }
 
         // gets the position of the first space left
@@ -335,6 +378,16 @@ namespace Smuxi.Frontend.Stfl
                    Text.Substring(Math.Min(Position + 1, Text.Length));
         }
 
+        void CompleteNick()
+        {
+            // perform completion
+            string text = Text;
+            int position = Position;
+            NickCompleter.Complete(ref text, ref position, f_ChatViewManager.CurrentChat);
+            Text = text;
+            Position = position;
+        }
+
         static string _(string msg)
         {
             return Mono.Unix.Catalog.GetString(msg);
diff --git a/src/Frontend-STFL/Frontend.cs b/src/Frontend-STFL/Frontend.cs
index 7751506..511b283 100644
--- a/src/Frontend-STFL/Frontend.cs
+++ b/src/Frontend-STFL/Frontend.cs
@@ -1,7 +1,7 @@
 /*
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2007, 2010-2011 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2007, 2010-2013 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -38,7 +38,6 @@ namespace Smuxi.Frontend.Stfl
         private static readonly string    _Name = "smuxi";
         private static readonly string    _UIName = "STFL";
         private static Version            _Version;
-        private static string             _VersionNumber;
         private static string             _VersionString;
         private static Version            _EngineVersion;
         private static MainWindow         _MainWindow;
@@ -47,6 +46,8 @@ namespace Smuxi.Frontend.Stfl
         private static UserConfig         _UserConfig;
         private static FrontendManager    _FrontendManager;
         
+        public static event EventHandler SessionPropertyChanged;
+
         public static string Name {
             get {
                 return _Name;
@@ -92,6 +93,10 @@ namespace Smuxi.Frontend.Stfl
             }
             set {
                 _Session = value;
+
+                if (SessionPropertyChanged != null) {
+                    SessionPropertyChanged(value, EventArgs.Empty);
+                }
             }
         }
         
@@ -132,7 +137,6 @@ namespace Smuxi.Frontend.Stfl
             AssemblyProductAttribute pr = (AssemblyProductAttribute)asm.
                 GetCustomAttributes(typeof(AssemblyProductAttribute), false)[0];
             _Version = asm_name.Version;
-            _VersionNumber = asm_name.Version.ToString();
             _VersionString = pr.Product + " - " + _UIName + " frontend " + _Version;
 
             // this always calls abort() :(((
@@ -163,20 +167,17 @@ namespace Smuxi.Frontend.Stfl
                 // not hitting a key
                 _MainWindow.Run(500);
             }
-#if LOG4NET
-           _Logger.Warn("_MainWindow.Run() returned!");
-#endif
         }
         
         public static void InitLocalEngine()
         {
             Engine.Engine.Init();
             _EngineVersion = Engine.Engine.Version;
-            _Session = new Engine.Session(Engine.Engine.Config,
-                                          Engine.Engine.ProtocolManagerFactory,
-                                          "local");
-            _Session.RegisterFrontendUI(_MainWindow.UI);
-            _UserConfig = _Session.UserConfig;
+            Session = new Engine.Session(Engine.Engine.Config,
+                                         Engine.Engine.ProtocolManagerFactory,
+                                         "local");
+            Session.RegisterFrontendUI(_MainWindow.UI);
+            _UserConfig = Session.UserConfig;
             ConnectEngineToGUI();
         }
         
@@ -203,7 +204,7 @@ namespace Smuxi.Frontend.Stfl
                     Environment.Exit(1);
                 }
 
-                _Session = manager.Session;
+                Session = manager.Session;
                 _UserConfig = manager.UserConfig;
                 _EngineVersion = manager.EngineVersion;
                 ConnectEngineToGUI();
@@ -241,6 +242,17 @@ namespace Smuxi.Frontend.Stfl
             _Session = null;
         }
         
+        public static void ApplyConfig(UserConfig userConfig)
+        {
+            Trace.Call(userConfig);
+
+            if (userConfig == null) {
+                throw new ArgumentNullException("userConfig");
+            }
+
+            _MainWindow.ApplyConfig(userConfig);
+        }
+
         public static void Quit()
         {
             if (_FrontendManager != null) {
diff --git a/src/Frontend-STFL/MainWindow.cs b/src/Frontend-STFL/MainWindow.cs
index 009aaea..1237220 100644
--- a/src/Frontend-STFL/MainWindow.cs
+++ b/src/Frontend-STFL/MainWindow.cs
@@ -1,7 +1,7 @@
 /*
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2007, 2010-2011 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2007, 2010-2013 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -32,24 +32,9 @@ namespace Smuxi.Frontend.Stfl
 {
     public class MainWindow : Form
     {
-#if LOG4NET
-        private static readonly log4net.ILog _Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
-#endif
-        private StflUI          _UI;
-        private Entry           _Entry;
-        private ChatViewManager _ChatViewManager;
-        
-        public ChatViewManager ChatViewManager {
-            get {
-                return _ChatViewManager;
-            }
-        }
-        
-        public StflUI UI {
-            get {
-                return _UI;
-            }
-        }
+        public StflUI UI { get; private set; }
+        Entry Entry { get; set; }
+        public ChatViewManager ChatViewManager { get; private set; }
 
         public string InputLabel {
             get {
@@ -89,16 +74,21 @@ namespace Smuxi.Frontend.Stfl
 
         public MainWindow() : base(null, "MainWindow.stfl")
         {
-            _ChatViewManager = new ChatViewManager(this);
-            _Entry = new Entry(this, _ChatViewManager);
-            _UI = new StflUI(_ChatViewManager);
+            ChatViewManager = new ChatViewManager(this);
+            Entry = new Entry(this, ChatViewManager);
+            UI = new StflUI(ChatViewManager);
 
             if (StflApi.IsXterm) {
                 ShowTitle = false;
             }
 
-    	    Assembly asm = Assembly.GetExecutingAssembly();
-    	    _ChatViewManager.Load(asm);
-    	}
+            Assembly asm = Assembly.GetExecutingAssembly();
+            ChatViewManager.Load(asm);
+        }
+
+        public void ApplyConfig(UserConfig config)
+        {
+            Entry.ApplyConfig(config);
+        }
     }
 }
diff --git a/src/Frontend-STFL/MainWindow.stfl b/src/Frontend-STFL/MainWindow.stfl
index a9fdeec..958882f 100644
--- a/src/Frontend-STFL/MainWindow.stfl
+++ b/src/Frontend-STFL/MainWindow.stfl
@@ -25,6 +25,11 @@ vbox
     .expand:0 .height:1
     @style_normal:fg=white,bg=blue
     label
+      richtext:1
+      style_clear_normal:fg=white,bg=blue
+      style_event_normal:fg=green,bg=blue
+      style_msg_normal:fg=cyan,bg=blue,attr=bold
+      style_highlight_normal:fg=magenta,bg=blue,attr=bold
       text[navigation_label_text]:"Navigation"
   hbox[input_hbox]
     .expand:0 .height:1
diff --git a/src/Frontend-STFL/Makefile.am b/src/Frontend-STFL/Makefile.am
index b6daee1..d2fdc21 100644
--- a/src/Frontend-STFL/Makefile.am
+++ b/src/Frontend-STFL/Makefile.am
@@ -56,7 +56,9 @@ FILES = \
 	STFL/StflApi.cs \
 	STFL/TextView.cs \
 	STFL/Widget.cs \
-	ChatView.cs \
+	Views/ChatView.cs \
+	Views/GroupChatView.cs \
+	Views/PersonChatView.cs \
 	ChatViewManager.cs 
 
 DATA_FILES = 
diff --git a/src/Frontend-STFL/Makefile.in b/src/Frontend-STFL/Makefile.in
index 783986c..05f5e3b 100644
--- a/src/Frontend-STFL/Makefile.in
+++ b/src/Frontend-STFL/Makefile.in
@@ -59,8 +59,11 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
 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
@@ -191,9 +194,8 @@ 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_CAMPFIRE = @GETTEXT_PACKAGE_ENGINE_CAMPFIRE@
 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@
@@ -205,6 +207,9 @@ 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@
+GIO_SHARP_CFLAGS = @GIO_SHARP_CFLAGS@
+GIO_SHARP_FILES = @GIO_SHARP_FILES@
+GIO_SHARP_LIBS = @GIO_SHARP_LIBS@
 GLADE_SHARP_20_CFLAGS = @GLADE_SHARP_20_CFLAGS@
 GLADE_SHARP_20_LIBS = @GLADE_SHARP_20_LIBS@
 GLIB_SHARP_20_CFLAGS = @GLIB_SHARP_20_CFLAGS@
@@ -251,6 +256,11 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
+MESSAGINGMENU_SHARP_CFLAGS = @MESSAGINGMENU_SHARP_CFLAGS@
+MESSAGINGMENU_SHARP_FILES = @MESSAGINGMENU_SHARP_FILES@
+MESSAGINGMENU_SHARP_LIBS = @MESSAGINGMENU_SHARP_LIBS@
+MESSAGING_MENU_CFLAGS = @MESSAGING_MENU_CFLAGS@
+MESSAGING_MENU_LIBS = @MESSAGING_MENU_LIBS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
 MONO_MODULE_CFLAGS = @MONO_MODULE_CFLAGS@
@@ -258,8 +268,6 @@ 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@
@@ -272,8 +280,6 @@ 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@
@@ -418,7 +424,9 @@ FILES = \
 	STFL/StflApi.cs \
 	STFL/TextView.cs \
 	STFL/Widget.cs \
-	ChatView.cs \
+	Views/ChatView.cs \
+	Views/GroupChatView.cs \
+	Views/PersonChatView.cs \
 	ChatViewManager.cs 
 
 DATA_FILES = 
diff --git a/src/Frontend-STFL/STFL/Makefile.in b/src/Frontend-STFL/STFL/Makefile.in
index 04c3c09..345f83a 100644
--- a/src/Frontend-STFL/STFL/Makefile.in
+++ b/src/Frontend-STFL/STFL/Makefile.in
@@ -54,8 +54,11 @@ 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)/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
@@ -111,9 +114,8 @@ 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_CAMPFIRE = @GETTEXT_PACKAGE_ENGINE_CAMPFIRE@
 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@
@@ -125,6 +127,9 @@ 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@
+GIO_SHARP_CFLAGS = @GIO_SHARP_CFLAGS@
+GIO_SHARP_FILES = @GIO_SHARP_FILES@
+GIO_SHARP_LIBS = @GIO_SHARP_LIBS@
 GLADE_SHARP_20_CFLAGS = @GLADE_SHARP_20_CFLAGS@
 GLADE_SHARP_20_LIBS = @GLADE_SHARP_20_LIBS@
 GLIB_SHARP_20_CFLAGS = @GLIB_SHARP_20_CFLAGS@
@@ -171,6 +176,11 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
+MESSAGINGMENU_SHARP_CFLAGS = @MESSAGINGMENU_SHARP_CFLAGS@
+MESSAGINGMENU_SHARP_FILES = @MESSAGINGMENU_SHARP_FILES@
+MESSAGINGMENU_SHARP_LIBS = @MESSAGINGMENU_SHARP_LIBS@
+MESSAGING_MENU_CFLAGS = @MESSAGING_MENU_CFLAGS@
+MESSAGING_MENU_LIBS = @MESSAGING_MENU_LIBS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
 MONO_MODULE_CFLAGS = @MONO_MODULE_CFLAGS@
@@ -178,8 +188,6 @@ 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@
@@ -192,8 +200,6 @@ 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@
diff --git a/src/Frontend-STFL/STFL/StflApi.cs b/src/Frontend-STFL/STFL/StflApi.cs
index 7ff8b2f..59369b4 100644
--- a/src/Frontend-STFL/STFL/StflApi.cs
+++ b/src/Frontend-STFL/STFL/StflApi.cs
@@ -30,9 +30,6 @@ namespace Stfl
 {
     internal class StflApi
     {
-#if LOG4NET
-        private static readonly log4net.ILog f_Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
-#endif
         public static bool IsXterm { get; private set; }
         static bool IsUtf8Locale { get; set; }
         static string EscapeLessThanCharacter  { get; set; }
@@ -40,7 +37,11 @@ namespace Stfl
 
         static StflApi()
         {
-            IsXterm = Environment.GetEnvironmentVariable("TERM") == "xterm";
+            // check if he has a graphical terminal. screen/tmux in not
+            // detected in case someone is using it in pure text mode
+            string termName = Environment.GetEnvironmentVariable("TERM");
+            IsXterm = (termName != null && (termName.StartsWith("xterm") ||
+                termName.StartsWith("rxvt")));
             // detect UTF-8 locale according to:
             // http://www.cl.cam.ac.uk/~mgk25/unicode.html#activate
             var locale = Environment.GetEnvironmentVariable("LC_ALL") ??
diff --git a/src/Frontend-STFL/STFL/TextView.cs b/src/Frontend-STFL/STFL/TextView.cs
index 3590f8f..ce59252 100644
--- a/src/Frontend-STFL/STFL/TextView.cs
+++ b/src/Frontend-STFL/STFL/TextView.cs
@@ -184,7 +184,6 @@ namespace Stfl
                 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
diff --git a/src/Frontend-STFL/STFL/Widget.cs b/src/Frontend-STFL/STFL/Widget.cs
index 5557607..70b92f5 100644
--- a/src/Frontend-STFL/STFL/Widget.cs
+++ b/src/Frontend-STFL/STFL/Widget.cs
@@ -67,8 +67,8 @@ namespace Stfl
 
         public int XPosition {
             get {
-                return Int32.Parse(Form[String.Format("{0}:x", WidgetName)]);
                 Render();
+                return Int32.Parse(Form[String.Format("{0}:x", WidgetName)]);
             }
         }
 
diff --git a/src/Frontend-STFL/StflUI.cs b/src/Frontend-STFL/StflUI.cs
index 9a5ac7a..22fdba3 100644
--- a/src/Frontend-STFL/StflUI.cs
+++ b/src/Frontend-STFL/StflUI.cs
@@ -1,13 +1,7 @@
 /*
- * $Id: TestUI.cs 179 2007-04-21 15:01:29Z meebey $
- * $URL: svn+ssh://svn.qnetp.net/svn/smuxi/smuxi/trunk/src/Frontend-Test/TestUI.cs $
- * $Rev: 179 $
- * $Author: meebey $
- * $Date: 2007-04-21 17:01:29 +0200 (Sat, 21 Apr 2007) $
- *
  * Smuxi - Smart MUltipleXed Irc
  *
- * Copyright (c) 2005-2006 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2007, 2011, 2013 Mirco Bauer <meebey at meebey.net>
  *
  * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
  *
@@ -70,13 +64,16 @@ namespace Smuxi.Frontend.Stfl
 
             try {
                 ChatView chatView = _ChatViewManager.GetChat(chat);
-#if LOG4NET
                 if (chatView == null) {
+#if LOG4NET
                     _Logger.Fatal(String.Format("AddMessageToChat(): _ChatViewManager.GetChat(chat) chat.Name: {0} returned null!", chat.Name));
+#endif
                     return;
                 }
-#endif
+
+                // FIXME: this must be marshalled into the UI thread!
                 chatView.AddMessage(msg);
+                _ChatViewManager.UpdateNavigation();
             } catch (Exception ex) {
 #if LOG4NET
                 _Logger.Fatal(ex);
@@ -129,13 +126,16 @@ namespace Smuxi.Frontend.Stfl
             
             try {
                 var chatView = _ChatViewManager.GetChat(chat);
-#if LOG4NET
                 if (chatView == null) {
+#if LOG4NET
                     _Logger.Fatal(String.Format("SyncChat(): _ChatViewManager.GetChat(chat) chat.Name: {0} returned null!", chat.Name));
+#endif
                     return;
                 }
-#endif
                 chatView.Sync();
+                if (_ChatViewManager.CurrentChat == chatView) {
+                    _ChatViewManager.UpdateInput();
+                }
 
                 Frontend.FrontendManager.AddSyncedChat(chat);
             } catch (Exception ex) {
@@ -148,11 +148,48 @@ namespace Smuxi.Frontend.Stfl
         public void AddPersonToGroupChat(GroupChatModel groupChat, PersonModel person)
         {
             Trace.Call(groupChat, person);
+
+            try {
+                var chatView = _ChatViewManager.GetChat(groupChat);
+                if (chatView == null) {
+#if LOG4NET
+                    _Logger.Fatal(String.Format("AddPersonToGroupChat(): _ChatViewManager.GetChat(chat) chat.Name: {0} returned null!", groupChat.Name));
+#endif
+                    return;
+                }
+
+                lock (chatView.Participants) {
+                    chatView.Participants.Add(person);
+                }
+            } catch (Exception ex) {
+#if LOG4NET
+                _Logger.Fatal(ex);
+#endif
+            }
         }
         
-        public void UpdatePersonInGroupChat(GroupChatModel groupChat, PersonModel olduser, PersonModel newuser)
+        public void UpdatePersonInGroupChat(GroupChatModel groupChat, PersonModel oldPerson, PersonModel newPerson)
         {
-            Trace.Call(groupChat, olduser, newuser);
+            Trace.Call(groupChat, oldPerson, newPerson);
+
+            try {
+                var chatView = _ChatViewManager.GetChat(groupChat);
+                if (chatView == null) {
+#if LOG4NET
+                    _Logger.Fatal(String.Format("UpdatePersonInGroupChat(): _ChatViewManager.GetChat(groupChat) groupChat.Name: {0} returned null!", groupChat.Name));
+#endif
+                    return;
+                }
+
+                lock (chatView.Participants) {
+                    chatView.Participants.Remove(oldPerson);
+                    chatView.Participants.Add(newPerson);
+                }
+            } catch (Exception ex) {
+#if LOG4NET
+                _Logger.Fatal(ex);
+#endif
+            }
         }
     
         public void UpdateTopicInGroupChat(GroupChatModel groupChat, MessageModel topic)
@@ -165,6 +202,24 @@ namespace Smuxi.Frontend.Stfl
         public void RemovePersonFromGroupChat(GroupChatModel groupChat, PersonModel person)
         {
             Trace.Call(groupChat, person);
+
+            try {
+                var chatView = _ChatViewManager.GetChat(groupChat);
+                if (chatView == null) {
+#if LOG4NET
+                    _Logger.Fatal(String.Format("RemovePersonFromGroupChat(): _ChatViewManager.GetChat(groupChat) groupChat.Name: {0} returned null!", groupChat.Name));
+#endif
+                    return;
+                }
+
+                lock (chatView.Participants) {
+                    chatView.Participants.Remove(person);
+                }
+            } catch (Exception ex) {
+#if LOG4NET
+                _Logger.Fatal(ex);
+#endif
+            }
         }
 
         public void SetNetworkStatus(string status)
diff --git a/src/Frontend-STFL/Views/ChatView.cs b/src/Frontend-STFL/Views/ChatView.cs
new file mode 100644
index 0000000..e2619ff
--- /dev/null
+++ b/src/Frontend-STFL/Views/ChatView.cs
@@ -0,0 +1,328 @@
+/*
+ * Smuxi - Smart MUltipleXed Irc
+ *
+ * Copyright (c) 2007, 2010-2013 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.Threading;
+using System.Collections.Generic;
+using System.Globalization;
+using Smuxi.Common;
+using Smuxi.Engine;
+using Smuxi.Frontend;
+using Stfl;
+
+namespace Smuxi.Frontend.Stfl
+{
+    [ChatViewInfo(ChatType = ChatType.Session)]
+    [ChatViewInfo(ChatType = ChatType.Protocol)]
+    public class ChatView : IChatView, IDisposable
+    {
+#if LOG4NET
+        static readonly log4net.ILog _Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+#endif
+        // HACK: STFL crashes if we use 0 in a widget name
+        static int f_NextID = 1;
+        int        f_WidgetID;
+        string     f_WidgetName;
+        public ChatModel ChatModel { get; private set; }
+        MainWindow f_MainWindow;
+        TextView   MessageTextView { get; set; }
+        IProtocolManager ProtocolManager { get; set; }
+        bool HasEvent { get; set; }
+        bool HasMessage { get; set; }
+        bool HasHighlight { get; set; }
+        public string Name { get; private set; }
+        public IList<PersonModel> Participants { get; private set; }
+
+        public string ID {
+            get {
+                return ChatModel.ID;
+            }
+        }
+
+        public int Position {
+            get {
+                return ChatModel.Position;
+            }
+        }
+
+        public bool IsVisible {
+            get {
+                return f_MainWindow[f_WidgetID + "d"] == "1";
+            }
+            set {
+                if (value) {
+                    HasEvent = false;
+                    HasMessage = false;
+                    HasHighlight = false;
+                }
+                f_MainWindow[f_WidgetID + "d"] = value ?  "1" : "0";
+           }
+        }
+
+        public string WidgetName {
+            get {
+                return f_WidgetName;
+            }
+        }
+
+        public string Label {
+            get {
+                string style;
+                if (HasHighlight) {
+                    style = "highlight";
+                } else if (HasMessage) {
+                    style = "msg";
+                } else if (HasEvent) {
+                    style = "event";
+                } else {
+                    style = "clear";
+                }
+                return String.Format("<{0}>{1}</>", style, Name);
+            }
+        }
+
+        public ChatView(ChatModel chat, MainWindow window)
+        {
+            Trace.Call(chat, window);
+
+            if (chat == null) {
+                throw new ArgumentNullException("chat");
+            }
+            if (window == null) {
+                throw new ArgumentNullException("window");
+            }
+
+            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;
+
+            Participants = new List<PersonModel>();
+        }
+        
+        ~ChatView()
+        {
+            Dispose(false);
+        }
+
+        protected virtual void Dispose(bool disposing)
+        {
+            Trace.Call(disposing);
+
+            // do not make STFL calls from the finalizer thread!
+            if (disposing) {
+                f_MainWindow.Modify(f_WidgetName, "delete", null);
+            }
+        }
+
+        public virtual void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+
+        public virtual void Close()
+        {
+            Trace.Call();
+
+            var protocolManager = ProtocolManager;
+            if (protocolManager == null) {
+#if LOG4NET
+                _Logger.WarnFormat(
+                    "{0}.Close(): ProtocolManager is null, bailing out!", this
+                );
+#endif
+                return;
+            }
+
+            ThreadPool.QueueUserWorkItem(delegate {
+                try {
+                    protocolManager.CloseChat(
+                        Frontend.FrontendManager,
+                        ChatModel
+                    );
+                } catch (Exception ex) {
+                    Frontend.ShowException(ex);
+                }
+            });
+        }
+
+        public virtual void Enable()
+        {
+            Trace.Call();
+        }
+        
+        public virtual void Disable()
+        {
+            Trace.Call();
+        }
+        
+        public virtual void Sync()
+        {
+            ProtocolManager = ChatModel.ProtocolManager;
+            Name = ChatModel.Name;
+#if LOG4NET
+            _Logger.Debug("Sync() syncing messages");
+#endif
+            // sync messages
+            // cleanup, be sure the output is empty
+            f_MainWindow.Modify("output_textview", "replace_inner", "");
+
+            var messages = ChatModel.Messages;
+            if (messages.Count > 0) {
+                foreach (MessageModel msg in messages) {
+                    AddMessage(msg);
+                }
+            }
+        }
+        
+        public virtual void Populate()
+        {
+        }
+
+        public void AddMessage(MessageModel msg)
+        {
+            // OPT: typical message length
+            var line = new StringBuilder(512);
+            int msgLength = 0;
+            switch (msg.MessageType) {
+                case MessageType.Normal:
+                    HasMessage = true;
+                    break;
+                case MessageType.Event:
+                    HasEvent = true;
+                    break;
+            }
+            bool hasHighlight = false;
+            foreach (MessagePartModel msgPart in msg.MessageParts) {
+                if (msgPart.IsHighlight) {
+                    HasHighlight = true;
+                }
+                // TODO: implement other types
+                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;
+            }
+            var finalMsg = String.Format("{0} {1}", timestamp, line.ToString());
+            MessageTextView.AppendLine(finalMsg);
+
+            ScrollToEnd();
+        }
+
+        public void ScrollUp()
+        {
+            Trace.Call();
+
+            MessageTextView.ScrollUp();
+        }
+
+        public void ScrollDown()
+        {
+            Trace.Call();
+
+            MessageTextView.ScrollDown();
+        }
+
+        public void ScrollToStart()
+        {
+            Trace.Call();
+
+            MessageTextView.ScrollToStart();
+        }
+
+        public void ScrollToEnd()
+        {
+            Trace.Call();
+
+            MessageTextView.ScrollToEnd();
+        }
+    }
+}
diff --git a/src/Frontend-STFL/Views/GroupChatView.cs b/src/Frontend-STFL/Views/GroupChatView.cs
new file mode 100644
index 0000000..ab86192
--- /dev/null
+++ b/src/Frontend-STFL/Views/GroupChatView.cs
@@ -0,0 +1,51 @@
+// Smuxi - Smart MUltipleXed Irc
+//
+// Copyright (c) 2013 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 Smuxi.Common;
+using Smuxi.Engine;
+
+namespace Smuxi.Frontend.Stfl
+{
+    [ChatViewInfo(ChatType = ChatType.Group)]
+    public class GroupChatView : ChatView
+    {
+        public MessageModel Topic { get; set; }
+
+        public GroupChatView(ChatModel chat, MainWindow window) :
+                        base(chat, window)
+        {
+            Trace.Call(chat, window);
+        }
+
+        public override void Sync()
+        {
+            base.Sync();
+
+            var groupChat = (GroupChatModel) ChatModel;
+            Topic = groupChat.Topic;
+            var persons = groupChat.Persons;
+            if (persons != null) {
+                foreach (var person in persons.Values) {
+                    Participants.Add(person);
+                }
+            }
+        }
+    }
+}
diff --git a/src/Frontend-STFL/Views/PersonChatView.cs b/src/Frontend-STFL/Views/PersonChatView.cs
new file mode 100644
index 0000000..09d2db8
--- /dev/null
+++ b/src/Frontend-STFL/Views/PersonChatView.cs
@@ -0,0 +1,43 @@
+// Smuxi - Smart MUltipleXed Irc
+//
+// Copyright (c) 2013 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 Smuxi.Common;
+using Smuxi.Engine;
+
+namespace Smuxi.Frontend.Stfl
+{
+    [ChatViewInfo(ChatType = ChatType.Person)]
+    public class PersonChatView : ChatView
+    {
+        public PersonChatView(ChatModel chat, MainWindow window) :
+                         base(chat, window)
+        {
+            Trace.Call(chat, window);
+        }
+
+        public override void Sync()
+        {
+            base.Sync();
+
+            var personChat = (PersonChatModel) ChatModel;
+            Participants.Add(personChat.Person);
+        }
+    }
+}
diff --git a/src/Frontend-STFL/smuxi-frontend-stfl.exe.config b/src/Frontend-STFL/smuxi-frontend-stfl.exe.config
index cc68e59..cba442c 100644
--- a/src/Frontend-STFL/smuxi-frontend-stfl.exe.config
+++ b/src/Frontend-STFL/smuxi-frontend-stfl.exe.config
@@ -11,7 +11,13 @@
           <appender-ref ref="RollingFile" />
         </root>
         <appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
-          <file value="smuxi-frontend-stfl.log" />
+          <file type="log4net.Util.PatternString">
+            <converter>
+                <name value="SpecialFolder" />
+                <type value="Smuxi.Common.SpecialFolderPatternConverter,smuxi-common" />
+            </converter>
+            <conversionPattern value="%SpecialFolder{LocalApplicationData}/smuxi/smuxi-frontend-stfl.log" />
+          </file>
           <appendToFile value="true" />
           <maximumFileSize value="10240KB" />
           <maxSizeRollBackups value="1" />
diff --git a/src/Frontend-SWF/Chats/ChatView.cs b/src/Frontend-SWF/Chats/ChatView.cs
index 85cd5fd..1c5ab26 100644
--- a/src/Frontend-SWF/Chats/ChatView.cs
+++ b/src/Frontend-SWF/Chats/ChatView.cs
@@ -375,5 +375,12 @@ namespace Smuxi.Frontend.Swf
                 }
             }
         }
+
+        // empty by default
+        public virtual IList<PersonModel> Participants {
+            get {
+                return new List<PersonModel>();
+            }
+        }
     }
 }
diff --git a/src/Frontend-SWF/Chats/GroupChatView.cs b/src/Frontend-SWF/Chats/GroupChatView.cs
index d283f29..752a9a1 100644
--- a/src/Frontend-SWF/Chats/GroupChatView.cs
+++ b/src/Frontend-SWF/Chats/GroupChatView.cs
@@ -126,5 +126,15 @@ namespace Smuxi.Frontend.Swf
             _PersonListBox.Items.Clear();
             _TopicTextView.Clear();
         }
+
+        public override IList<PersonModel> Participants {
+            get {
+                var ret = new List<PersonModel>();
+                foreach (PersonModel person in GroupChatModel.Persons.Values) {
+                    ret.Add(person);
+                }
+                return ret;
+            }
+        }
     }
 }
diff --git a/src/Frontend-SWF/Chats/PersonChatView.cs b/src/Frontend-SWF/Chats/PersonChatView.cs
index 53db856..d78493a 100644
--- a/src/Frontend-SWF/Chats/PersonChatView.cs
+++ b/src/Frontend-SWF/Chats/PersonChatView.cs
@@ -27,7 +27,7 @@
  */
 
 using System;
-using Mono.Unix;
+using System.Collections.Generic;
 using Smuxi.Engine;
 
 namespace Smuxi.Frontend.Swf
@@ -40,5 +40,14 @@ namespace Smuxi.Frontend.Swf
         {
             this.Controls.Add(base.OutputTextView);
         }
+
+        public override IList<PersonModel> Participants
+        {
+            get {
+                var ret = new List<PersonModel>();
+                ret.Add(((PersonChatModel)ChatModel).Person);
+                return ret;
+            }
+        }
     }
 }
diff --git a/src/Frontend-SWF/Entry.cs b/src/Frontend-SWF/Entry.cs
index 64dcc30..5cc832b 100644
--- a/src/Frontend-SWF/Entry.cs
+++ b/src/Frontend-SWF/Entry.cs
@@ -47,6 +47,7 @@ namespace Smuxi.Frontend.Swf
         private int              _HistoryPosition;
         private bool             _HistoryChangedLine;
         private Notebook         _Notebook;
+        private NickCompleter NickCompleter { get; set; }
         
         public  EventHandler     Activated;
         
@@ -204,6 +205,18 @@ namespace Smuxi.Frontend.Swf
                 font = new Font(fontFamily, fontSize, style);
             }
             Font = font;
+
+            // replace nick completer if needed
+            bool wantBashCompletion = (bool)config["Interface/Entry/BashStyleCompletion"];
+            if (wantBashCompletion && !(NickCompleter is LongestPrefixNickCompleter)) {
+                NickCompleter = new LongestPrefixNickCompleter();
+            } else if (!wantBashCompletion && !(NickCompleter is TabCycleNickCompleter)) {
+                NickCompleter = new TabCycleNickCompleter();
+            }
+
+            // set the completion character
+            NickCompleter.CompletionChar = (string)config["Interface/Entry/CompletionChar"];
+
         }
         
         public string HistoryCurrent()
@@ -670,113 +683,12 @@ namespace Smuxi.Frontend.Swf
         
         private void _NickCompletion()
         {
-            int position = SelectionStart;
+            // perform completion
             string text = Text;
-            string word;
-            int previous_space;
-            int next_space;
-
-            // find the current word
-            string temp;
-            temp = text.Substring(0, position);
-            previous_space = temp.LastIndexOf(' ');
-            next_space = text.IndexOf(' ', position);
-
-#if LOG4NET
-            _Logger.Debug("previous_space: "+previous_space);
-            _Logger.Debug("next_space: "+next_space);
-#endif
-
-            if (previous_space != -1 && next_space != -1) {
-                // previous and next space exist
-                word = text.Substring(previous_space + 1, next_space - previous_space - 1);
-            } else if (previous_space != -1) {
-                // previous space exist
-                word = text.Substring(previous_space + 1);
-            } else if (next_space != -1) {
-                // next space exist
-                word = text.Substring(0, next_space);
-            } else {
-                // no spaces
-                word = text;
-            }
-
-            if (word == String.Empty) {
-                return;
-            }
-
-            // find the possible nickname
-            bool found = false;
-            bool partial_found = false;
-            string nick = null;
-            //GroupChatModel cp = (GroupChatModel) Frontend.FrontendManager.CurrentChat;
-            GroupChatModel cp = (GroupChatModel) _Notebook.CurrentChatView.ChatModel;
-            if ((bool)Frontend.UserConfig["Interface/Entry/BashStyleCompletion"]) {
-                IList<string> result = cp.PersonLookupAll(word);
-                if (result == null || result.Count == 0) {
-                    // no match
-                } else if (result.Count == 1) {
-                    found = true;
-                    nick = result[0];
-                } else if (result.Count >= 2) {
-                    string[] nickArray = new string[result.Count];
-                    result.CopyTo(nickArray, 0);
-                    string nicks = String.Join(" ", nickArray, 1, nickArray.Length - 1);
-                    Frontend.FrontendManager.AddTextToChat(cp, "-!- " + nicks);
-                    found = true;
-                    partial_found = true;
-                    nick = result[0];
-                }
-            } else {
-                PersonModel person = cp.PersonLookup(word);
-                if (person != null) {
-                    found = true;
-                    nick = person.IdentityName;
-                 }
-            }
-
-            if (found) {
-                // put the found nickname in place
-                if (previous_space != -1 && next_space != -1) {
-                    // previous and next space exist
-                    temp = text.Remove(previous_space + 1, word.Length);
-                    temp = temp.Insert(previous_space + 1, nick);
-                    Text = temp;
-                    if (partial_found) {
-                        SelectionStart = previous_space + 1 + nick.Length;
-                    } else {
-                        SelectionStart = previous_space + 2 + nick.Length;
-                    }
-                } else if (previous_space != -1) {
-                    // only previous space exist
-                    temp = text.Remove(previous_space + 1, word.Length);
-                    temp = temp.Insert(previous_space + 1, nick);
-                    if (partial_found) {
-                        Text = temp;
-                    } else {
-                        Text = temp+" ";
-                    }
-                    SelectionStart = previous_space + 2 + nick.Length;
-                } else if (next_space != -1) {
-                    // only next space exist
-                    temp = text.Remove(0, next_space + 1);
-                    if (partial_found) {
-                        Text = nick + " " + temp;
-                        SelectionStart = nick.Length;
-                    } else {
-                        Text = nick+(string)Frontend.UserConfig["Interface/Entry/CompletionCharacter"] + " " + temp;
-                        SelectionStart = nick.Length + 2;
-                    }
-                } else {
-                    // no spaces
-                    if (partial_found) {
-                        Text = nick;
-                    } else {
-                        Text = nick+(string)Frontend.UserConfig["Interface/Entry/CompletionCharacter"]+" ";
-                    }
-                    SelectionStart = -1;
-                }
-            }
+            int position = SelectionStart;
+            NickCompleter.Complete(ref text, ref position, _Notebook.CurrentChatView);
+            Text = text;
+            SelectionStart = position;
         }
         
         private static string _(string msg)
diff --git a/src/Frontend-SWF/Makefile.in b/src/Frontend-SWF/Makefile.in
index 2b9eed1..9f957fb 100644
--- a/src/Frontend-SWF/Makefile.in
+++ b/src/Frontend-SWF/Makefile.in
@@ -58,8 +58,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
@@ -150,9 +153,8 @@ 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_CAMPFIRE = @GETTEXT_PACKAGE_ENGINE_CAMPFIRE@
 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@
@@ -164,6 +166,9 @@ 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@
+GIO_SHARP_CFLAGS = @GIO_SHARP_CFLAGS@
+GIO_SHARP_FILES = @GIO_SHARP_FILES@
+GIO_SHARP_LIBS = @GIO_SHARP_LIBS@
 GLADE_SHARP_20_CFLAGS = @GLADE_SHARP_20_CFLAGS@
 GLADE_SHARP_20_LIBS = @GLADE_SHARP_20_LIBS@
 GLIB_SHARP_20_CFLAGS = @GLIB_SHARP_20_CFLAGS@
@@ -210,6 +215,11 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
+MESSAGINGMENU_SHARP_CFLAGS = @MESSAGINGMENU_SHARP_CFLAGS@
+MESSAGINGMENU_SHARP_FILES = @MESSAGINGMENU_SHARP_FILES@
+MESSAGINGMENU_SHARP_LIBS = @MESSAGINGMENU_SHARP_LIBS@
+MESSAGING_MENU_CFLAGS = @MESSAGING_MENU_CFLAGS@
+MESSAGING_MENU_LIBS = @MESSAGING_MENU_LIBS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
 MONO_MODULE_CFLAGS = @MONO_MODULE_CFLAGS@
@@ -217,8 +227,6 @@ 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@
@@ -231,8 +239,6 @@ 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@
diff --git a/src/Frontend-Test/Makefile.in b/src/Frontend-Test/Makefile.in
index 2434249..f385f11 100644
--- a/src/Frontend-Test/Makefile.in
+++ b/src/Frontend-Test/Makefile.in
@@ -58,8 +58,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
@@ -150,9 +153,8 @@ 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_CAMPFIRE = @GETTEXT_PACKAGE_ENGINE_CAMPFIRE@
 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@
@@ -164,6 +166,9 @@ 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@
+GIO_SHARP_CFLAGS = @GIO_SHARP_CFLAGS@
+GIO_SHARP_FILES = @GIO_SHARP_FILES@
+GIO_SHARP_LIBS = @GIO_SHARP_LIBS@
 GLADE_SHARP_20_CFLAGS = @GLADE_SHARP_20_CFLAGS@
 GLADE_SHARP_20_LIBS = @GLADE_SHARP_20_LIBS@
 GLIB_SHARP_20_CFLAGS = @GLIB_SHARP_20_CFLAGS@
@@ -210,6 +215,11 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
+MESSAGINGMENU_SHARP_CFLAGS = @MESSAGINGMENU_SHARP_CFLAGS@
+MESSAGINGMENU_SHARP_FILES = @MESSAGINGMENU_SHARP_FILES@
+MESSAGINGMENU_SHARP_LIBS = @MESSAGINGMENU_SHARP_LIBS@
+MESSAGING_MENU_CFLAGS = @MESSAGING_MENU_CFLAGS@
+MESSAGING_MENU_LIBS = @MESSAGING_MENU_LIBS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
 MONO_MODULE_CFLAGS = @MONO_MODULE_CFLAGS@
@@ -217,8 +227,6 @@ 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@
@@ -231,8 +239,6 @@ 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@
diff --git a/src/Frontend/ChatViewInfoAttribute.cs b/src/Frontend/ChatViewInfoAttribute.cs
index b7fb9d4..c852d77 100644
--- a/src/Frontend/ChatViewInfoAttribute.cs
+++ b/src/Frontend/ChatViewInfoAttribute.cs
@@ -33,10 +33,6 @@ namespace Smuxi.Engine
     [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
     public class ChatViewInfoAttribute : Attribute
     {
-#if LOG4NET
-        private static readonly log4net.ILog _Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
-#endif
-
         private ChatType _ChatType;
         private Type     _ProtocolManagerType;
         
diff --git a/src/Frontend/ChatViewSyncManager.cs b/src/Frontend/ChatViewSyncManager.cs
index 034292b..9139d72 100644
--- a/src/Frontend/ChatViewSyncManager.cs
+++ b/src/Frontend/ChatViewSyncManager.cs
@@ -1,6 +1,6 @@
 // Smuxi - Smart MUltipleXed Irc
 //
-// Copyright (c) 2011 Mirco Bauer <meebey at meebey.net>
+// Copyright (c) 2011, 2013 Mirco Bauer <meebey at meebey.net>
 //
 // Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
 //
@@ -70,7 +70,7 @@ namespace Smuxi.Frontend
             IProtocolManager protocolManager = chatModel.ProtocolManager;
             Type protocolManagerType = null;
             if (protocolManager != null) {
-                protocolManagerType = chatModel.ProtocolManager.GetType();
+                protocolManagerType = protocolManager.GetType();
             }
 #if LOG4NET
             DateTime stop = DateTime.UtcNow;
@@ -80,7 +80,28 @@ namespace Smuxi.Frontend
 #endif
 
             OnChatAdded(chatModel, chatId, chatType, chatPosition,
-                        protocolManagerType);
+                        protocolManager, protocolManagerType);
+        }
+
+        /// <remarks>
+        /// This method is thread safe.
+        /// </remarks>
+        public void Remove(ChatModel chatModel)
+        {
+            Trace.Call(chatModel);
+
+            if (chatModel == null) {
+                throw new ArgumentNullException("chatModel");
+            }
+
+            var chatKey = GetChatKey(chatModel);
+#if LOG4NET
+            Logger.DebugFormat("Remove() <{0}> removing from release queue",
+                               chatKey);
+#endif
+            lock (SyncReleaseQueue) {
+                SyncReleaseQueue.Remove(chatKey);
+            }
         }
 
         public void Sync(IChatView chatView)
@@ -246,6 +267,11 @@ namespace Smuxi.Frontend
 #endif
                         return;
                     }
+                    // no longer need the release slot
+                    // BUG: this breaks re-syncing an existing chat! For that
+                    // reason the frontend _must_ notify us via Remove() if the
+                    // chat sync state is no longer needed
+                    //SyncReleaseQueue.Remove(chatKey);
                 }
 
                 Sync(chatView);
@@ -259,12 +285,14 @@ namespace Smuxi.Frontend
 
         void OnChatAdded(ChatModel chatModel, string chatId,
                          ChatType chatType, int chatPosition,
+                         IProtocolManager protocolManager,
                          Type protocolManagerType)
         {
             if (ChatAdded != null) {
                 ChatAdded(this,
                           new ChatViewAddedEventArgs(chatModel, chatId,
                                                      chatType, chatPosition,
+                                                     protocolManager,
                                                      protocolManagerType));
             }
         }
@@ -293,16 +321,19 @@ namespace Smuxi.Frontend
         public string ChatID { get; private set; }
         public ChatType ChatType { get; private set; }
         public int ChatPosition { get; private set; }
+        public IProtocolManager ProtocolManager { get; private set; }
         public Type ProtocolManagerType { get; private set; }
 
         public ChatViewAddedEventArgs(ChatModel chatModel, string chatId,
                                       ChatType chatType, int chatPosition,
+                                      IProtocolManager protocolManager,
                                       Type protocolManagerType)
         {
             ChatModel = chatModel;
             ChatID = chatId;
             ChatType = chatType;
             ChatPosition = chatPosition;
+            ProtocolManager = protocolManager;
             ProtocolManagerType = protocolManagerType;
         }
     }
diff --git a/src/Frontend/CommandManager.cs b/src/Frontend/CommandManager.cs
index 047f739..9a13a9a 100644
--- a/src/Frontend/CommandManager.cs
+++ b/src/Frontend/CommandManager.cs
@@ -1,8 +1,6 @@
-// $Id$
-// 
 // Smuxi - Smart MUltipleXed Irc
 // 
-// Copyright (c) 2010 Mirco Bauer <meebey at meebey.net>
+// Copyright (c) 2010, 2012-2013 Mirco Bauer <meebey at meebey.net>
 // 
 // Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
 // 
@@ -21,6 +19,8 @@
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 
 using System;
+using System.Linq;
+using SysDiag = System.Diagnostics;
 using Smuxi.Common;
 using Smuxi.Engine;
 
@@ -111,14 +111,33 @@ namespace Smuxi.Frontend
         {
             Trace.Call(cmd);
 
+            var handled = false;
+            if (cmd.IsCommand) {
+                switch (cmd.Command) {
+                    case "exec":
+                        CommandExec(cmd);
+                        handled = true;
+                        break;
+                }
+            }
+            if (handled) {
+                // no need to send the command to the engine
+                return;
+            }
+
             DateTime start, stop;
             start = DateTime.UtcNow;
 
-            bool handled;
             handled = f_Session.Command(cmd);
             if (!handled) {
+                IProtocolManager pm;
+                if (cmd.Chat is SessionChatModel) {
+                    pm = cmd.FrontendManager.CurrentProtocolManager;
+                } else {
+                    pm = cmd.Chat.ProtocolManager;
+                }
+
                 // we maybe have no network manager yet
-                IProtocolManager pm = cmd.Chat.ProtocolManager;
                 if (pm != null) {
                     handled = pm.Command(cmd);
                 } else {
@@ -133,18 +152,123 @@ namespace Smuxi.Frontend
             f_LastCommandTimeSpan = (stop - start);
         }
 
+        private void CommandExec(CommandModel cmd)
+        {
+            Trace.Call(cmd);
+
+            if (cmd.DataArray.Length < 2) {
+                NotEnoughParameters(cmd);
+                return;
+            }
+            var parameter = cmd.Parameter;
+            var parameters = cmd.Parameter.Split(' ');
+            var messageOutput = false;
+            var executeOutput = false;
+            if (parameters.Length > 0) {
+                var shift = false;
+                switch (parameters[0]) {
+                    case "-c":
+                        executeOutput = true;
+                        shift = true;
+                        break;
+                    case "-o":
+                        messageOutput = true;
+                        shift = true;
+                        break;
+                }
+                if (shift) {
+                    parameters = parameters.Skip(1).ToArray();
+                    parameter = String.Join(" ", parameters);
+                }
+            }
+            SysDiag.DataReceivedEventHandler handler = (sender, e) => {
+                if (String.IsNullOrEmpty(e.Data)) {
+                  return;
+                }
+                // eat trailing newlines
+                var output = e.Data.TrimEnd('\r', '\n');
+                if (executeOutput || messageOutput) {
+                    if (messageOutput && output.StartsWith(cmd.CommandCharacter)) {
+                        // escape command character
+                        output = String.Format("{0}{1}",
+                                               cmd.CommandCharacter, output);
+                    }
+                    Execute(new CommandModel(cmd.FrontendManager,
+                                             cmd.Chat,
+                                             cmd.CommandCharacter, output));
+                } else {
+                    var msg = new MessageBuilder().AppendText(output).ToMessage();
+                    cmd.FrontendManager.AddMessageToChat(cmd.Chat, msg);
+                }
+            };
+
+            string file;
+            string args = null;
+            if (Environment.OSVersion.Platform == PlatformID.Unix) {
+                file = "sh";
+                args = String.Format("-c '{0}'",
+                                     parameter.Replace("'", @"\'"));
+            } else {
+                file = parameters[1];
+                if (parameters.Length > 1) {
+                    args = String.Join(" ", parameters.Skip(1).ToArray());
+                }
+            }
+            var info = new SysDiag.ProcessStartInfo() {
+                FileName = file,
+                Arguments = args,
+                RedirectStandardOutput = true,
+                RedirectStandardError = true,
+                UseShellExecute = false
+            };
+            using (var process = new SysDiag.Process()) {
+                process.StartInfo = info;
+                process.OutputDataReceived += handler;
+                process.ErrorDataReceived += handler;
+
+                try {
+                    process.Start();
+                    process.BeginOutputReadLine();
+                    process.BeginErrorReadLine();
+                    process.WaitForExit();
+                } catch (Exception ex) {
+#if LOG4NET
+                    f_Logger.Error(ex);
+#endif
+                    var command = info.FileName;
+                    if (!String.IsNullOrEmpty(info.Arguments)) {
+                        command += " " + info.Arguments;
+                    }
+                    var msg = new MessageBuilder().
+                        AppendErrorText("Executing '{0}' failed with: {1}",
+                                        command, ex.Message).
+                        ToMessage();
+                    cmd.FrontendManager.AddMessageToChat(cmd.Chat, msg);
+                }
+            }
+        }
+
         private void Unknown(CommandModel cmd)
         {
-            cmd.FrontendManager.AddTextToChat(
-                cmd.Chat,
-                String.Format(
-                    "-!- {0}",
-                    String.Format(
-                        _("Unknown Command: {0}"),
-                        cmd.Command
-                    )
-                )
-            );
+            var msg = CreateMessageBuilder().
+                AppendEventPrefix().
+                AppendText(_("Unknown Command: {0}"), cmd.Command).
+                ToMessage();
+            cmd.FrontendManager.AddMessageToChat(cmd.Chat, msg);
+        }
+
+        void NotEnoughParameters(CommandModel cmd)
+        {
+            var msg = CreateMessageBuilder().
+                AppendEventPrefix().
+                AppendText(_("Not enough parameters for {0} command"), cmd.Command).
+                ToMessage();
+            cmd.FrontendManager.AddMessageToChat(cmd.Chat, msg);
+        }
+
+        MessageBuilder CreateMessageBuilder()
+        {
+            return new MessageBuilder();
         }
 
         protected virtual void OnTaskQueueExceptionEvent(object sender, TaskQueueExceptionEventArgs e)
diff --git a/src/Frontend/EngineManager.cs b/src/Frontend/EngineManager.cs
index 0e8242c..70aa13e 100644
--- a/src/Frontend/EngineManager.cs
+++ b/src/Frontend/EngineManager.cs
@@ -212,7 +212,6 @@ namespace Smuxi.Frontend
             IDictionary props = new Hashtable();
             // ugly remoting expects the port as string ;)
             props["port"] = remotingPort.ToString();
-            string error_msg = null;
             string connection_url = null;
             SessionManager sessm = null;
             switch (channel) {
diff --git a/src/Frontend/IChatView.cs b/src/Frontend/IChatView.cs
index 1711ac5..8b89aa0 100644
--- a/src/Frontend/IChatView.cs
+++ b/src/Frontend/IChatView.cs
@@ -27,6 +27,7 @@
  */
 
 using System;
+using System.Collections.Generic;
 using Smuxi.Engine;
 
 namespace Smuxi.Frontend
@@ -36,6 +37,7 @@ namespace Smuxi.Frontend
         ChatModel ChatModel { get; }
         string    ID { get; }
         int       Position { get; }
+        IList<PersonModel> Participants { get; }
 
         void Enable();
         void Disable();
@@ -46,5 +48,7 @@ namespace Smuxi.Frontend
         void ScrollDown();
         void ScrollToStart();
         void ScrollToEnd();
+
+        void AddMessage(MessageModel msg);
     }
 }
diff --git a/src/Frontend/LongestPrefixNickCompleter.cs b/src/Frontend/LongestPrefixNickCompleter.cs
new file mode 100644
index 0000000..d5877a4
--- /dev/null
+++ b/src/Frontend/LongestPrefixNickCompleter.cs
@@ -0,0 +1,131 @@
+/*
+ * Smuxi - Smart MUltipleXed Irc
+ *
+ * Copyright (c) 2005-2013 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2013 Ondra Hosek <ondra.hosek at gmail.com>
+ *
+ * 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.Linq;
+using System.Collections.Generic;
+using Smuxi.Engine;
+
+namespace Smuxi.Frontend
+{
+    /// <summary>
+    /// Longest Common Prefix (bash-style) nick completer.
+    /// </summary>
+    /// <description>
+    /// When triggered, the nickname list is searched for all matching nicknames.
+    /// When only one nickname is found, it is fully completed. When more than one
+    /// nickname is found, the longest prefix common to all these nicknames is
+    /// completed, and a list of the nicknames is output into the chat view.
+    /// The user may then input additional characters to narrow down the search,
+    /// then trigger completion anew.
+    /// </description>
+    public class LongestPrefixNickCompleter : NickCompleter
+    {
+        protected static string LongestCommonPrefix(IList<string> nicks)
+        {
+            string ret = null;
+
+            if (nicks.Count == 0) {
+                return ret;
+            }
+
+            foreach (string nick in nicks) {
+                if (ret == null) {
+                    ret = nick;
+                } else {
+                    while (!nick.StartsWith(ret, StringComparison.OrdinalIgnoreCase)) {
+                        // cut off one character at the end
+                        ret = ret.Substring(0, ret.Length - 1);
+                    }
+                }
+            }
+
+            return ret;
+        }
+
+        public override void Complete(ref string entryLine, ref int cursorPosition, IChatView currentChatView)
+        {
+            // isolate the nick to complete
+            int matchPosition;
+            bool appendSpace, leadingAt;
+            string matchMe = IsolateNickToComplete(entryLine, cursorPosition, out matchPosition, out appendSpace, out leadingAt);
+
+            bool appendCompletionChar = (matchPosition == 0);
+            int additionalSteps = 0;
+
+            // find the matching nicknames
+            var nicks = NicksMatchingPrefix(currentChatView.Participants, matchMe);
+
+            if (nicks.Count == 0) {
+                // no matches; do nothing
+                return;
+            } else if (nicks.Count == 1) {
+                // bingo!
+                string nick = nicks [0];
+
+                // suppress the completion character if we had an @
+                if (leadingAt) {
+                    appendCompletionChar = false;
+                }
+
+                // find the beginning and end of the string
+                string prefix = entryLine.Substring(0, matchPosition);
+                string suffix = entryLine.Substring(matchPosition + matchMe.Length);
+
+                // append the completion character and a space, if requested
+                if (appendSpace) {
+                    suffix = ' ' + suffix;
+                    ++additionalSteps;
+                }
+                if (appendCompletionChar) {
+                    suffix = CompletionChar + suffix;
+                    ++additionalSteps;
+                }
+
+                // assemble the line and move the cursor
+                entryLine = prefix + nick + suffix;
+                cursorPosition = matchPosition + nick.Length + additionalSteps;
+            } else {
+                // find the longest common prefix
+                string lcp = LongestCommonPrefix(nicks);
+
+                // assemble nickname string
+                string nickString = string.Join(" ", nicks.ToArray());
+
+                // output the matched prefixes
+                currentChatView.AddMessage(
+                    new MessageModel(String.Format("-!- {0}", nickString))
+                );
+
+                // extend to the longest match
+                string prefix = entryLine.Substring(0, matchPosition);
+                string suffix = entryLine.Substring(matchPosition + matchMe.Length);
+
+                // assemble the line and move the cursor
+                entryLine = prefix + lcp + suffix;
+                cursorPosition = matchPosition + lcp.Length;
+            }
+        }
+    }
+}
+
diff --git a/src/Frontend/Makefile.am b/src/Frontend/Makefile.am
index 96db2ec..42cb703 100644
--- a/src/Frontend/Makefile.am
+++ b/src/Frontend/Makefile.am
@@ -70,7 +70,10 @@ FILES = \
 	IEntryView.cs \
 	EngineManager.cs \
 	SshTunnelManager.cs \
-	CommandManager.cs
+	CommandManager.cs \
+	NickCompleter.cs \
+	LongestPrefixNickCompleter.cs \
+	TabCycleNickCompleter.cs
 
 DATA_FILES = 
 
diff --git a/src/Frontend/Makefile.in b/src/Frontend/Makefile.in
index 0ee7da3..20e8657 100644
--- a/src/Frontend/Makefile.in
+++ b/src/Frontend/Makefile.in
@@ -58,8 +58,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
@@ -150,9 +153,8 @@ 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_CAMPFIRE = @GETTEXT_PACKAGE_ENGINE_CAMPFIRE@
 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@
@@ -164,6 +166,9 @@ 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@
+GIO_SHARP_CFLAGS = @GIO_SHARP_CFLAGS@
+GIO_SHARP_FILES = @GIO_SHARP_FILES@
+GIO_SHARP_LIBS = @GIO_SHARP_LIBS@
 GLADE_SHARP_20_CFLAGS = @GLADE_SHARP_20_CFLAGS@
 GLADE_SHARP_20_LIBS = @GLADE_SHARP_20_LIBS@
 GLIB_SHARP_20_CFLAGS = @GLIB_SHARP_20_CFLAGS@
@@ -210,6 +215,11 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
+MESSAGINGMENU_SHARP_CFLAGS = @MESSAGINGMENU_SHARP_CFLAGS@
+MESSAGINGMENU_SHARP_FILES = @MESSAGINGMENU_SHARP_FILES@
+MESSAGINGMENU_SHARP_LIBS = @MESSAGINGMENU_SHARP_LIBS@
+MESSAGING_MENU_CFLAGS = @MESSAGING_MENU_CFLAGS@
+MESSAGING_MENU_LIBS = @MESSAGING_MENU_LIBS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
 MONO_MODULE_CFLAGS = @MONO_MODULE_CFLAGS@
@@ -217,8 +227,6 @@ 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@
@@ -231,8 +239,6 @@ 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@
@@ -382,7 +388,10 @@ FILES = \
 	IEntryView.cs \
 	EngineManager.cs \
 	SshTunnelManager.cs \
-	CommandManager.cs
+	CommandManager.cs \
+	NickCompleter.cs \
+	LongestPrefixNickCompleter.cs \
+	TabCycleNickCompleter.cs
 
 DATA_FILES = 
 RESOURCES = 
diff --git a/src/Frontend/NickCompleter.cs b/src/Frontend/NickCompleter.cs
new file mode 100644
index 0000000..bbb2cd7
--- /dev/null
+++ b/src/Frontend/NickCompleter.cs
@@ -0,0 +1,116 @@
+/*
+ * Smuxi - Smart MUltipleXed Irc
+ *
+ * Copyright (c) 2005-2013 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2013 Ondra Hosek <ondra.hosek at gmail.com>
+ *
+ * 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 Smuxi.Engine;
+
+namespace Smuxi.Frontend
+{
+    /// <summary>
+    /// Automatically completes nicknames (e.g. when the user presses the Tab key).
+    /// </summary>
+    public abstract class NickCompleter
+    {
+        public string CompletionChar = ":";
+
+        /// <summary>
+        /// Isolates the nickname that should be completed.
+        /// </summary>
+        /// <returns>The isolated nickname.</returns>
+        /// <param name="entryLine">The text currently typed into the input text box.</param>
+        /// <param name="cursorPosition">The current location of the cursor in the input text box.</param>
+        /// <param name="nickBeginning">Stores where the isolated nickname begins in the entered text.</param>
+        /// <param name="appendSpace">Whether to append a space when the nickname is completed.</param>
+        /// <param name="leadingAt">Whether the nickname started with a leading @ (which was stripped away).</param>
+        protected static string IsolateNickToComplete(string entryLine, int cursorPosition, out int nickBeginning, out bool appendSpace, out bool leadingAt)
+        {
+            string ret;
+            int prev_space = entryLine.Substring(0, cursorPosition).LastIndexOf(' ');
+            int next_space = entryLine.IndexOf(' ', cursorPosition);
+            appendSpace = false;
+
+            if (prev_space == -1 && next_space == -1) {
+                // no spaces (the nick is the only thing)
+                nickBeginning = 0;
+                appendSpace = true;
+                ret = entryLine;
+            } else if (prev_space == -1) {
+                nickBeginning = 0;
+                ret = entryLine.Substring(0, next_space);
+            } else if (next_space == -1) {
+                nickBeginning = prev_space + 1;
+                appendSpace = true;
+                ret = entryLine.Substring(nickBeginning);
+            } else {
+                nickBeginning = prev_space + 1;
+                ret = entryLine.Substring(prev_space + 1, next_space - prev_space - 1);
+            }
+
+            leadingAt = false;
+            if (ret.StartsWith("@")) {
+                leadingAt = true;
+                ++nickBeginning;
+                ret = ret.Substring(1);
+            }
+
+            return ret;
+        }
+
+        /// <summary>
+        /// Returns a list containing only the nicknames matching the given prefix.
+        /// </summary>
+        /// <returns>
+        /// The (sorted) list of nicknames matching the given prefix.
+        /// </returns>
+        /// <param name="persons">List of people to enumerate.</param>
+        /// <param name="prefix">Prefix of nicknames to return.</param>
+        protected static IList<string> NicksMatchingPrefix(IList<PersonModel> persons, string prefix)
+        {
+            var ret = new List<string>();
+            string lowerPfx = prefix.ToLower();
+            foreach (PersonModel person in persons) {
+                string nick = person.IdentityName;
+                if (nick.ToLower().StartsWith(lowerPfx)) {
+                    ret.Add(nick);
+                }
+            }
+            ret.Sort();
+            return ret;
+        }
+
+        /// <summary>
+        /// Performs nickname tab completion on the specified input.
+        /// </summary>
+        /// <param name="entryLine">The text currently typed into the input text box.</param>
+        /// <param name="cursorPosition">
+        /// The current location of the cursor in the input text box. Equal to the index of the
+        /// character after the current cursor position.
+        /// </param>
+        /// <param name="currentChatView">
+        /// The current chat view. The list of participants is fetched from it; the completer may
+        /// also append messages to the chat to provide further information.
+        /// </param>
+        abstract public void Complete(ref string entryLine, ref int cursorPosition, IChatView currentChatView);
+    }
+}
diff --git a/src/Frontend/SshTunnelManager.cs b/src/Frontend/SshTunnelManager.cs
index 766e026..5796b57 100644
--- a/src/Frontend/SshTunnelManager.cs
+++ b/src/Frontend/SshTunnelManager.cs
@@ -38,7 +38,6 @@ namespace Smuxi.Frontend
         private static readonly string   f_LibraryTextDomain = "smuxi-frontend";
         private SysDiag.Process          f_Process;
         private SysDiag.ProcessStartInfo f_ProcessStartInfo;
-        private int                      f_RemotingBackChannelPort;
         private string                   f_Program;
         private string                   f_Parameters;
         private string                   f_Username;
@@ -187,7 +186,7 @@ namespace Smuxi.Frontend
                         f_ForwardBindPort
                     );
                     throw new ApplicationException(msg);
-                } catch (SocketException ex) {
+                } catch (SocketException) {
                 }
             }
 
@@ -542,7 +541,7 @@ namespace Smuxi.Frontend
                 exitCode = process.ExitCode;
             }
 
-            Match match = Regex.Match(output, @"[0-9]+\.[0-9a-zA-Z_]+");
+            Match match = Regex.Match(output, @"[0-9]+\.[0-9a-zA-Z_\.]+");
             if (match.Success) {
                 var version = match.Value;
 #if LOG4NET
diff --git a/src/Frontend/TabCycleNickCompleter.cs b/src/Frontend/TabCycleNickCompleter.cs
new file mode 100644
index 0000000..32f541f
--- /dev/null
+++ b/src/Frontend/TabCycleNickCompleter.cs
@@ -0,0 +1,134 @@
+/*
+ * Smuxi - Smart MUltipleXed Irc
+ *
+ * Copyright (c) 2005-2013 Mirco Bauer <meebey at meebey.net>
+ * Copyright (c) 2013 Ondra Hosek <ondra.hosek at gmail.com>
+ *
+ * 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.Frontend
+{
+    /// <summary>
+    /// Tab Cycle (irssi-style) nick completer.
+    /// </summary>
+    /// <description>
+    /// When triggered, the first nickname matching the input characters is
+    /// completed. If triggered again at the same position, the match is
+    /// replaced by the next nickname.
+    /// </description>
+    public class TabCycleNickCompleter : NickCompleter
+    {
+        IList<string> PreviousNicks { get; set; }
+        int PreviousNickIndex { get; set; }
+        int PreviousMatchPos { get; set; }
+        int PreviousMatchLength { get; set; }
+        int PreviousMatchCursorOffset { get; set; } // offset from match pos + match len
+        IChatView PreviousChatView { get; set; }
+
+        public TabCycleNickCompleter()
+        {
+            PreviousNicks = null;
+            PreviousNickIndex = -1;
+            PreviousMatchPos = -1;
+            PreviousMatchLength = -1;
+            PreviousMatchCursorOffset = 0;
+            PreviousChatView = null;
+        }
+
+        public override void Complete(ref string entryLine, ref int cursorPosition, IChatView currentChatView)
+        {
+            // isolate the nick to complete
+            int matchPosition;
+            bool appendSpace, leadingAt;
+            string matchMe = IsolateNickToComplete(entryLine, cursorPosition, out matchPosition, out appendSpace, out leadingAt);
+
+            int rematchCursorPosition = PreviousMatchPos + PreviousMatchLength + PreviousMatchCursorOffset;
+            if (PreviousNickIndex != -1 && currentChatView == PreviousChatView && cursorPosition == rematchCursorPosition) {
+                // re-match
+                PreviousNickIndex = (PreviousNickIndex + 1) % PreviousNicks.Count;
+
+                string nick = PreviousNicks [PreviousNickIndex];
+                string prefix = entryLine.Substring(0, PreviousMatchPos);
+                string suffix = entryLine.Substring(PreviousMatchPos + PreviousMatchLength);
+
+                PreviousMatchLength = nick.Length;
+                entryLine = prefix + nick + suffix;
+                cursorPosition = PreviousMatchPos + PreviousMatchLength + PreviousMatchCursorOffset;
+
+                return;
+            }
+
+            // don't re-match even if the user moves the cursor back to the "correct" position
+            PreviousNickIndex = -1;
+
+            // don't complete empty strings
+            if (matchMe.Length == 0) {
+                return;
+            }
+
+            bool appendCompletionChar = (matchPosition == 0);
+            int additionalSteps = 0;
+
+            // find the matching nicknames
+            IList<string> nicks = NicksMatchingPrefix(currentChatView.Participants, matchMe);
+
+            if (nicks.Count == 0) {
+                // no matches; do nothing
+                return;
+            } else {
+                // bingo!
+                string nick = nicks [0];
+
+                // store the new values for the next completion
+                PreviousNicks = nicks;
+                PreviousNickIndex = 0;
+                PreviousMatchPos = matchPosition;
+                PreviousMatchLength = nick.Length;
+                PreviousChatView = currentChatView;
+
+                // suppress the completion character if we had an @
+                if (leadingAt) {
+                    appendCompletionChar = false;
+                }
+
+                // find the beginning and end of the string
+                string prefix = entryLine.Substring(0, matchPosition);
+                string suffix = entryLine.Substring(matchPosition + matchMe.Length);
+
+                // append the completion character and a space, if requested
+                if (appendSpace) {
+                    suffix = ' ' + suffix;
+                    ++additionalSteps;
+                }
+                if (appendCompletionChar) {
+                    suffix = CompletionChar + suffix;
+                    ++additionalSteps;
+                }
+
+                // assemble the line and move the cursor
+                entryLine = prefix + nick + suffix;
+                cursorPosition = matchPosition + nick.Length + additionalSteps;
+                PreviousMatchCursorOffset = additionalSteps;
+            }
+        }
+    }
+}
+
diff --git a/src/Makefile.am b/src/Makefile.am
index d1d8b8b..a5b5d88 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -7,18 +7,14 @@ if ENABLE_ENGINE_XMPP
 ENGINE_XMPP = Engine-XMPP
 endif
 
-if ENABLE_ENGINE_OSCAR
-ENGINE_OSCAR = Engine-OSCAR
-endif
-
-if ENABLE_ENGINE_MSNP
-ENGINE_MSNP = Engine-MSNP
-endif
-
 if ENABLE_ENGINE_TWITTER
 ENGINE_TWITTER = Engine-Twitter
 endif
 
+if ENABLE_ENGINE_CAMPFIRE
+ENGINE_CAMPFIRE = Engine-Campfire
+endif
+
 # Frontends
 if ENABLE_FRONTEND_GNOME
 FRONTEND_GNOME = Frontend-GNOME
@@ -55,9 +51,8 @@ endif
 SUBDIRS =	Common \
 		Engine \
 		$(ENGINE_IRC) \
-		$(ENGINE_MSNP) \
-		$(ENGINE_OSCAR) \
 		$(ENGINE_TWITTER) \
+		$(ENGINE_CAMPFIRE) \
 		$(ENGINE_XMPP) \
 		Server \
 		Frontend \
diff --git a/src/Makefile.in b/src/Makefile.in
index 3673d09..ab1b5a0 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -55,8 +55,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
@@ -83,10 +86,10 @@ AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
 	distdir
 ETAGS = etags
 CTAGS = ctags
-DIST_SUBDIRS = Common Engine Engine-IRC Engine-MSNP Engine-OSCAR \
-	Engine-Twitter Engine-XMPP Server Frontend Frontend-GNOME \
-	Frontend-GNOME-IRC Frontend-GNOME-XMPP Frontend-STFL \
-	Frontend-Curses Frontend-SWF Frontend-Test
+DIST_SUBDIRS = Common Engine Engine-IRC Engine-Twitter Engine-Campfire \
+	Engine-XMPP Server Frontend Frontend-GNOME Frontend-GNOME-IRC \
+	Frontend-GNOME-XMPP Frontend-STFL Frontend-Curses Frontend-SWF \
+	Frontend-Test
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 am__relativize = \
   dir0=`pwd`; \
@@ -155,9 +158,8 @@ 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_CAMPFIRE = @GETTEXT_PACKAGE_ENGINE_CAMPFIRE@
 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@
@@ -169,6 +171,9 @@ 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@
+GIO_SHARP_CFLAGS = @GIO_SHARP_CFLAGS@
+GIO_SHARP_FILES = @GIO_SHARP_FILES@
+GIO_SHARP_LIBS = @GIO_SHARP_LIBS@
 GLADE_SHARP_20_CFLAGS = @GLADE_SHARP_20_CFLAGS@
 GLADE_SHARP_20_LIBS = @GLADE_SHARP_20_LIBS@
 GLIB_SHARP_20_CFLAGS = @GLIB_SHARP_20_CFLAGS@
@@ -215,6 +220,11 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
+MESSAGINGMENU_SHARP_CFLAGS = @MESSAGINGMENU_SHARP_CFLAGS@
+MESSAGINGMENU_SHARP_FILES = @MESSAGINGMENU_SHARP_FILES@
+MESSAGINGMENU_SHARP_LIBS = @MESSAGINGMENU_SHARP_LIBS@
+MESSAGING_MENU_CFLAGS = @MESSAGING_MENU_CFLAGS@
+MESSAGING_MENU_LIBS = @MESSAGING_MENU_LIBS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
 MONO_MODULE_CFLAGS = @MONO_MODULE_CFLAGS@
@@ -222,8 +232,6 @@ 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@
@@ -236,8 +244,6 @@ 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@
@@ -333,9 +339,8 @@ twitter_api_key = @twitter_api_key@
 # Engines
 @ENABLE_ENGINE_IRC_TRUE at ENGINE_IRC = Engine-IRC
 @ENABLE_ENGINE_XMPP_TRUE at ENGINE_XMPP = Engine-XMPP
- at ENABLE_ENGINE_OSCAR_TRUE@ENGINE_OSCAR = Engine-OSCAR
- at ENABLE_ENGINE_MSNP_TRUE@ENGINE_MSNP = Engine-MSNP
 @ENABLE_ENGINE_TWITTER_TRUE at ENGINE_TWITTER = Engine-Twitter
+ at ENABLE_ENGINE_CAMPFIRE_TRUE@ENGINE_CAMPFIRE = Engine-Campfire
 
 # Frontends
 @ENABLE_FRONTEND_GNOME_TRUE at FRONTEND_GNOME = Frontend-GNOME
@@ -350,9 +355,8 @@ twitter_api_key = @twitter_api_key@
 SUBDIRS = Common \
 		Engine \
 		$(ENGINE_IRC) \
-		$(ENGINE_MSNP) \
-		$(ENGINE_OSCAR) \
 		$(ENGINE_TWITTER) \
+		$(ENGINE_CAMPFIRE) \
 		$(ENGINE_XMPP) \
 		Server \
 		Frontend \
diff --git a/src/Server/Makefile.in b/src/Server/Makefile.in
index 7572841..9797502 100644
--- a/src/Server/Makefile.in
+++ b/src/Server/Makefile.in
@@ -60,8 +60,11 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
 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
@@ -152,9 +155,8 @@ 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_CAMPFIRE = @GETTEXT_PACKAGE_ENGINE_CAMPFIRE@
 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@
@@ -166,6 +168,9 @@ 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@
+GIO_SHARP_CFLAGS = @GIO_SHARP_CFLAGS@
+GIO_SHARP_FILES = @GIO_SHARP_FILES@
+GIO_SHARP_LIBS = @GIO_SHARP_LIBS@
 GLADE_SHARP_20_CFLAGS = @GLADE_SHARP_20_CFLAGS@
 GLADE_SHARP_20_LIBS = @GLADE_SHARP_20_LIBS@
 GLIB_SHARP_20_CFLAGS = @GLIB_SHARP_20_CFLAGS@
@@ -212,6 +217,11 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MCS = @MCS@
+MESSAGINGMENU_SHARP_CFLAGS = @MESSAGINGMENU_SHARP_CFLAGS@
+MESSAGINGMENU_SHARP_FILES = @MESSAGINGMENU_SHARP_FILES@
+MESSAGINGMENU_SHARP_LIBS = @MESSAGINGMENU_SHARP_LIBS@
+MESSAGING_MENU_CFLAGS = @MESSAGING_MENU_CFLAGS@
+MESSAGING_MENU_LIBS = @MESSAGING_MENU_LIBS@
 MKDIR_P = @MKDIR_P@
 MONO = @MONO@
 MONO_MODULE_CFLAGS = @MONO_MODULE_CFLAGS@
@@ -219,8 +229,6 @@ 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@
@@ -233,8 +241,6 @@ 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@
diff --git a/src/smuxi-win32.nsis.in b/src/smuxi-win32.nsis.in
index dc00d25..02652aa 100644
--- a/src/smuxi-win32.nsis.in
+++ b/src/smuxi-win32.nsis.in
@@ -35,7 +35,7 @@ SetCompressor lzma
 !define PRODUCT_UNINST_ROOT_KEY "HKLM"
 !define DOTNET_VERSION "4.0"
 !define GTKSHARP_PRODUCT_GUID "{3CB70B01-4BC8-4C0F-B28F-7C6E33F913CC}"
-!define GTKSHARP_VERSION "2.12.10"
+!define GTKSHARP_VERSION "2.12.20"
 
 ############################
 # MUI 1.67 compatible mode #
@@ -131,20 +131,21 @@ FunctionEnd
 !macroend
 
 !macro CheckGtkSharp GTKSHARP_REQ
-    !define GTKSHARP_FILE         "gtk-sharp-2.12.10.win32.msi"
+    !define GTKSHARP_FILE         "gtk-sharp-2.12.20.win32.msi"
     !define GTKSHARP_BASE_URL     "http://www.smuxi.org/jaws/data/files/"
     !define GTKSHARP_DOWNLOAD_URL "${GTKSHARP_BASE_URL}${GTKSHARP_FILE}"
     !define GTKSHARP_TEMP_FILE "$TEMP\${GTKSHARP_FILE}"
 
     DetailPrint "Checking your GTK# version..."
     Var /GLOBAL GTKSHARP_FOUND_VERSION
+    # GTK# 2.12.20 uses a Xamarin key
     ReadRegStr $GTKSHARP_FOUND_VERSION HKLM \
-          "SOFTWARE\Novell\GtkSharp\Version" ""
+              "SOFTWARE\Xamarin\GtkSharp\Version" ""
 
-    # GTK# 2.12.20 uses a Xamarin key
+    # GTK# 2.12.10 uses a Novell key
     ${If} $GTKSHARP_FOUND_VERSION == ""
         ReadRegStr $GTKSHARP_FOUND_VERSION HKLM \
-              "SOFTWARE\Xamarin\GtkSharp\Version" ""
+            "SOFTWARE\Novell\GtkSharp\Version" ""
     ${EndIf}
 
     ${VersionCompare} $GTKSHARP_FOUND_VERSION ${GTKSHARP_REQ} $R0
@@ -519,7 +520,11 @@ Section "Main" SEC01
   File "../bin-win32/Newtonsoft.Json.dll"
   File "../bin-win32/jabber-net.dll"
   File "../bin-win32/Db4objects.Db4o.dll"
+  File "../bin-win32/ServiceStack.Text.dll"
+  File "../bin-win32/ServiceStack.Interfaces.dll"
+  File "../bin-win32/ServiceStack.Common.dll"
   File "../bin-win32/smuxi-common.dll"
+  File "../bin-win32/smuxi-engine-campfire.dll"
   File "../bin-win32/smuxi-engine-irc.dll"
   File "../bin-win32/smuxi-engine-twitter.dll"
   File "../bin-win32/smuxi-engine-xmpp.dll"
@@ -533,6 +538,7 @@ Section "Main" SEC01
   File "../bin-win32/plink.exe"
   File "../bin-win32/Fixedsys500c.ttf"
   File /nonfatal /r "../bin-win32/locale"
+  File /nonfatal /r "../bin-win32/icons"
 
   IfFileExists "$FONTS/Fixedsys500c.ttf" SkipFont InstallFont
 
@@ -594,6 +600,7 @@ Section Uninstall
   Delete "$INSTDIR\smuxi-frontend-gnome.log"
   Delete "$INSTDIR\smuxi-frontend-gnome-irc.dll"
   Delete "$INSTDIR\smuxi-engine.dll"
+  Delete "$INSTDIR\smuxi-engine-campfire.dll"
   Delete "$INSTDIR\smuxi-engine-irc.dll"
   Delete "$INSTDIR\smuxi-engine-twitter.dll"
   Delete "$INSTDIR\smuxi-engine-xmpp.dll"
@@ -605,6 +612,9 @@ Section Uninstall
   Delete "$INSTDIR\Nini.dll"
   Delete "$INSTDIR\Mono.Posix.dll"
   Delete "$INSTDIR\Meebey.SmartIrc4net.dll"
+  Delete "$INSTDIR\ServiceStack.Text.dll"
+  Delete "$INSTDIR\ServiceStack.Interfaces.dll"
+  Delete "$INSTDIR\ServiceStack.Common.dll"
   Delete "$INSTDIR\log4net.dll"
   Delete "$INSTDIR\plink.exe"
   Delete "$INSTDIR\Fixedsys500c.ttf"

-- 
smuxi



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